DatePicker From and To

安稳与你 提交于 2021-02-19 06:04:23

问题


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:

  1. Please note that we cannot directly bind the constraints to a model.
  2. 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="&lt;From> - &lt;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 than From. ✔️
  • 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!