问题
In a form, I have two DatePicker
fields which are From
and To
. In this case user should not be able to choose a value for To
less than what he/she choose for the From
field.
I just wanted to know is there any SAPUI5 native way to do this comparison and validate the DatePicker
fields? In the image blow, you can see that the From
has a greater value than the To
, which is wrong! In this case, I need to show the validation error around the fields.
回答1:
Assume you have the following 2 DatePicker
objects in your xml view file:
<m:DatePicker id="__input_validFrom"
value="{path: 'ZValidFrom', type : 'sap.ui.model.type.Date'}"
fieldGroupIds="fieldGroup1"
change="handleValidFromChange"/>
<m:DatePicker id="__input_validTo"
value="{path: 'ZValidTo', type : 'sap.ui.model.type.Date'}"
fieldGroupIds="fieldGroup1"
change="handleValidToChange" />
These 2 fields show the date in a suitable format as we set the type to sap.ui.model.type.Date
.
Now we have to play with constraints of the sap.ui.model.type.Date
in the onChange
event handler:
handleValidFromChange: function (oEvent) {
var oDatePicker = oEvent.getSource(),
sValue = oDatePicker.getValue(),
sToDatePicker = "__input_validTo",
oToDatePicker = this.byId(sToDatePicker);
oToDatePicker.getBinding("value").setType(new sap.ui.model.type.Date(null, {
minimum: new Date(sValue)
}), "string");
},
handleValidToChange: function (oEvent) {
var oDatePicker = oEvent.getSource(),
sValue = oDatePicker.getValue(),
sFromDatePicker = "__input_validFrom",
oFromDatePicker = this.byId(sFromDatePicker);
oFromDatePicker.getBinding("value").setType(new sap.ui.model.type.Date(null, {
maximum: new Date(sValue)
}), "string");
}
As soon as user change value in one of fields we change the constraints in the other field.
Notes:
- Please note that we cannot directly bind the constraints to a model.
- By applying this solution you need to use validation on date pickers to see some validation state text.
回答2:
By using the change event on the "from" picker we can then use the method setMinDate() for the "To" picker based on the date picked so the user can only select dates after the date selected.
On our XML view we can have both sap.m.DatePicker:
<DatePicker id="DP1" placeholder="Enter Date ..." change="handleChange"/>
<DatePicker id="DP2" placeholder="Enter Date ..."/>
And in our controller we can then apply the logic:
handleChange: function(oControlEvent) {
//get date picked from first picker
var sDatePicked = oControlEvent.getSource().getDateValue();
//set minimum date on second picker
this.getView().byId("DP2").setMinDate(sDatePicked).setValue();
}
By applying this method we can now get the new value from the first sap.m.DatePicker and apply it to the "To" Date Picker by using the setMinDate() method and reset its value so the user has to select a new date.
回答3:
Is there any SAPUI5 native way to do this
Yes, take a look at Date Range Selection.
sap.ui.getCore().attachInit(() => sap.ui.require([
"sap/ui/core/Core",
"sap/ui/model/odata/v2/ODataModel",
"sap/ui/core/Fragment",
], async (Core, ODataModel, Fragment) => {
"use strict";
Core.setModel(createNorthwindModel()); // Load $metadata first
await Promise.all([ // then control libs
Core.loadLibrary("sap.m", true),
Core.loadLibrary("sap.ui.unified", true),
]);
const control = await Fragment.load({ // XML sample
definition: `<DateRangeSelection xmlns="sap.m" xmlns:core="sap.ui.core"
core:require="{DateInterval: 'sap/ui/model/type/DateInterval'}"
placeholder="<From> - <To>"
width="16rem"
binding="{
path: '/Employees(1)',
parameters: {
select: 'EmployeeID, BirthDate, HireDate'
}
}"
value="{
parts: [ 'BirthDate', 'HireDate' ],
type: 'DateInterval'
}"
/>`,
});
function createNorthwindModel() {
return new ODataModel({
serviceUrl: [
"https://cors-anywhere.herokuapp.com/", // proxy
"https://services.odata.org/V2/Northwind/Northwind.svc/"
].join(""),
tokenHandling: false,
preliminaryContext: true,
defaultBindingMode: "TwoWay",
useBatch: false,
});
}
Core.getMessageManager().registerObject(control.placeAt("content"), true);
}));
<script id="sap-ui-bootstrap"
src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_fiori_3"
data-sap-ui-async="true"
data-sap-ui-modules="sap/ui/thirdparty/datajs"
data-sap-ui-compatversion="edge"
></script>
<body id="content" class="sapUiBody sapUiSizeCompact" style="height: 100%"></body>
Note: the above code snippet fails to run as it relied on the public proxy server
https://cors-anywhere.herokuapp.com/
which is no longer available (See the announcement here). There are currently no known sample OData services which support CORS. But the solution with DateRangeSelection
still applies regardless of the data source.
This solves the given problem:
- User needs to pick two date values. ✔️
- User should not be able to choose
To
less thanFrom
. ✔️ - Looking for "UI5 native way" to solve this. ✔️
There is even the binding type: sap.ui.model.type.Date*Interval to enable:
- Two-way data binding ✔️
- Format options ✔️
- Input validation ✔️
Compared to the custom implementation with two DatePickers, DateRangeSelection requires:
- Less clicks for the user ✔️
- Zero JS code to maintain for handling date ranges ✔️
来源:https://stackoverflow.com/questions/53523776/datepicker-from-and-to