For an input field with constraints of minLength: 2 and maxLength: 10 symbols, if you were to introduce 11 symbols, you are going to get a static error message that it is an "Invalid entry".
The following Input field:
<Input value="{
path: 'modelExample>/Example1',
type: 'sap.ui.model.type.String',
constraints: {
minLength: 2,
maxLength: 10
}
}"/>
How to modify Input field, so that the error message is changed to: "Your input can only be between 2 and max 10 symbols"?
Somewhere you must be setting the valueState manually, hence the generic error message.
Here you can see more specific messages depending on the input value:
globalThis.onUI5Init = () => sap.ui.require([
"sap/ui/core/mvc/XMLView",
"sap/ui/model/json/JSONModel",
"sap/ui/core/Core",
], async (XMLView, JSONModel, Core) => {
"use strict";
const control = await XMLView.create({
definition: `<mvc:View xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:core="sap.ui.core"
core:require="{
StringType: 'sap/ui/model/type/String'
}"
>
<App>
<Page showHeader="false" class="sapUiResponsiveContentPadding">
<Input
width="17rem"
showClearIcon="true"
value="{
path: '/myModelValue',
type: 'StringType',
constraints: {
minLength: 2,
maxLength: 10
}
}"
/>
</Page>
</App>
</mvc:View>`,
models: new JSONModel({ myModelValue: "Alice" }),
height: "100%",
});
Core.getMessageManager().registerObject(control, true);
control.placeAt("content");
});
<script id="sap-ui-bootstrap"
src="https://sdk.openui5.org/resources/sap-ui-core.js"
data-sap-ui-oninit="onUI5Init"
data-sap-ui-libs="sap.ui.core,sap.m"
data-sap-ui-theme="sap_horizon"
data-sap-ui-async="true"
data-sap-ui-compatversion="edge"
data-sap-ui-excludejquerycompat="true"
data-sap-ui-xx-waitfortheme="init"
></script>
<body id="content" class="sapUiBody sapUiSizeCompact"></body>
Cf. documentation topic Validation Messages section "Automatically Created Messages". Most of the times, setting "handleValidation": true to the "sap.ui5" section in manifest.json is sufficient to enable generating meaningful messages automatically.
Related
I made an example for this question with the following logic:
A dropdown (sap.m.Select) has 2 options:
But whenever a checkbox above it is checked it only has one option left:
In that case I don't need any of this anymore:
So I found out, that the property editable="false" does exactly what I want in this case:
...but I don't know how to set editable dynamically depending on the current number of options.
Here's the full example:
https://jsfiddle.net/mb0h8v1s/1/
Since you are using a JSONModel you can say something like
editable="{= ${options>/arr1}.length > 1 }"
This is called Expression Binding and lets you use basic JavaScript within your binding.`
This assumes that you always use the same list and change the content of your list once the CheckBox is triggered and not rebind the list.
View:
<!DOCTYPE html>
<title>SAPUI5</title>
<script src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap" data-sap-ui-theme="sap_bluecrystal" data-sap-ui-libs="sap.m" data-sap-ui-bindingSyntax="complex" data-sap-ui-compatVersion="edge" data-sap-ui-preload="async"></script>
<script id="myView" type="ui5/xmlview">
<mvc:View controllerName="MyController" xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc"
xmlns:layout="sap.ui.commons.layout">
<Shell>
<Page id="mainPage" showHeader="false">
<FlexBox id="flex" justifyContent="Center" alignItems="Center" direction="Column">
<CheckBox
text="Only 1 option"
selected="{path:'options>/cbx_val'}"
/>
</FlexBox>
</Page>
</Shell>
</mvc:View>
</script>
<body class="sapUiBody">
<div id="content"></div>
</body>
JavaScript:
sap.ui.getCore().attachInit(function() {
"use strict";
sap.ui.controller("MyController", {
onInit: function() {
console.log("INITIALIZING!");
var arr1 = [{
id: "1",
name: "1st option"
}];
var arr2 = arr1.concat([{
id: "2",
name: "2nd option"
}]);
var oModel = new sap.ui.model.json.JSONModel({
cbx_val: false,
arr1: arr1,
arr2: arr2
});
this.getView().setModel(oModel, "options");
var selectVal = new sap.m.Select({
id: "selectField",
selectedKey: '',
editable: true,
enabled: "{= !${options>/cbx_val}}"
});
var selectLbl = new sap.m.Label({
text: "Select:",
labelFor: selectVal,
});
var selectLogicListener = new sap.m.Text({
visible: false,
text: {
parts: ['options>/cbx_val'],
formatter: function(bVal) {
var result = "options>/arr2";
if (bVal) {
result = "options>/arr1";
}
console.log(result);
selectVal.bindItems({
path: result,
template: new sap.ui.core.Item({
key: "{options>id}",
text: "{options>name}"
})
});
}
}
});
this.byId("flex").addItem(selectLbl);
this.byId("flex").addItem(selectVal);
this.byId("flex").addItem(selectLogicListener);
}
});
sap.ui.xmlview({
viewContent: jQuery("#myView").html()
}).placeAt("content");
});
How to register validationError callback for datetimepicker in XML view and how to get this event fired for invalid date input.
The datetimepicker control is an input box with a popup date picker.
The user can type directly into the input or use the date picked to select a date. I can add sophisticated validation to the datetime value but I am trying to simply trigger the validationError event when the user types an invalid date into the box, for example "1010101010010101010101010" or "32/15/2019".
Ideally I am looking for a constraint that tests for a valid date value and triggers the validationError() function if needed.
I guess a workaround is to use the change() event and do the validation in JS, set the valueState etc, but I want to understand what the datetimepicker can do in this regard without having to resort to excess JS.
I am convinced this must be in the docs somewhere but have not yet found anything conclusive. I feel strictParsing should play some part.
I found this SO questionabout setting date range constraints via declaring a new data type. I thought this might be a solution but I am stuck with how to set the constraint for 'a valid date' input value.
Reading the SAPUI5 docs about sap.ui.model.type.DateTime it mentions
The DateTime type supports the following validation constraints:
maximum (expects an dateTime presented in the source-pattern format)
minimum (expects an dateTime presented in the source-pattern format)
which gives no pointers over how to do a straight date validity or format check.
Can anyone point me in the right direction?
EDIT - on suggestion of #Matbtt and reference to docs I altered the type to the string literal sap.ui.model.type.DateTime. However the snippet then produced no output. I traced this to the binding to the model where I was binding to a string. When changed to bind to a JS date object this was fixed.
EDIT - on suggestion of #Developer added validationError callback but does not appear to work. See snippet.
// JSON sample data
var classData = {className: "Coding 101", id: 800, startdate: "2017-12-31T23:59:59.000"}
// convert JSON date to JS date object and format via moment for UI5 consumption
classData.startdateraw = new Date(classData.startdate)
classData.startdatefmt = moment(classData.startdateraw).format('YYYY-MM-DD-HH-mm-ss')
sap.ui.getCore().attachInit(function() {
"use strict";
sap.ui.controller("MyController", {
onInit: function() {
// create JSON model instance
var oModel = new sap.ui.model.json.JSONModel();
// set the data for the model
oModel.setData(classData);
// set model to core.
sap.ui.getCore().setModel(oModel);
// Enable validation !!
sap.ui.getCore().getMessageManager().registerObject(this.getView(), true);
this.getView().byId("startDate").attachValidationError(function(){
alert('Validation error fires - hoorah')
})
},
valError : function(){
console.log("There was a validation error")
}
});
sap.ui.xmlview({
viewContent: jQuery("#myView").html()
}).placeAt("content");
});
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/1.7.2/moment.min.js"></script>
<script src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap" data-sap-ui-theme="sap_bluecrystal" data-sap-ui-libs="sap.m" data-sap-ui-bindingSyntax="complex" data-sap-ui-compatVersion="edge" data-sap-ui-preload="async"></script>
<script id="myView" type="ui5/xmlview">
<mvc:View controllerName="MyController" xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns:layout="sap.ui.commons.layout" xmlns:f="sap.ui.layout.form">
<f:SimpleForm id="EditForm" maxContainerCols="2" editable="true" width="25rem" layout="ResponsiveGridLayout" path="{}">
<f:content>
<Label id="lblStartDate" text="Start" design="Bold" labelFor="startDate" />
<DateTimePicker
id="startDate"
placeholder="Enter a crazy date and time, e.g. 23/01/12345"
valueFormat="yyyy-MM-dd-HH-mm-ss"
validationError="valError"
value="{
path: '/startdateraw',
type: 'sap.ui.model.type.DateTime',
strictParsing: 'true'
}"
/>
</f:content>
</f:SimpleForm>
</mvc:View>
</script>
<div id="content"></div>
You can do it by handling change event of sap.m.DateTimePicker:
handleChange : function(oEvent){
var bValid = oEvent.getParameter("valid");
if(!bValid){
sap.m.MessageToast.show("Entered date range isn't valid");
return;
}
}
Jsbin working example.
EDITED 15:03 310117
Change event of sap.m.DateTimePicker is borrowed event from class sap.m.DatePicker.
Resolution
First, we need to distinguish between the events parse error and validation error.
parseError is fired when the user input could not be parsed (e.g. "123123").
validationError is fired only when the input could be parsed but violates one of the constraints defined in the property binding info object.
With the help of type and constraints in property binding, invalid user inputs can be automatically prevented from being stored in the model.
Additionally, you can also register the control or the entire application in the MessageManager for automatically generating the error messages in order to notify and guide the user what to do.
Refer to "Formatting, Parsing, and Validating Data" and "Validation Messages".
Sample
Here are some samples with sap.m.DateTimePicker corresponding to the model:
JSONModel
globalThis.onUI5Init = () => sap.ui.require([
"sap/ui/core/mvc/XMLView",
"sap/ui/model/json/JSONModel",
"sap/ui/core/Core",
], async (XMLView, JSONModel, core) => {
"use strict";
const control = await XMLView.create({
definition: `<mvc:View xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:core="sap.ui.core"
core:require="{
TypeDateTime: 'sap/ui/model/type/DateTime'
}"
displayBlock="true"
>
<App>
<Page showHeader="false" class="sapUiResponsiveContentPadding">
<ObjectAttribute title="Model value" text="{/myDate}" />
<ObjectAttribute title="Minimum Date" text="today" />
<DateTimePicker id="myDTP"
width="15rem"
value="{
path:'/myDate',
type: 'TypeDateTime',
formatOptions: {
style: 'medium/short'
}
}"
parseError="alert('Parse error')"
validationError="alert('Validation error')"
/>
</Page>
</App>
</mvc:View>`,
afterInit: function() {
const dateTimeValueBinding = this.byId("myDTP").getBinding("value");
dateTimeValueBinding.getType().setConstraints({
minimum: new Date(), // today
});
},
models: new JSONModel({
myDate: new Date(),
}),
});
core.getMessageManager().registerObject(control, true);
control.placeAt("content");
});
<script id="sap-ui-bootstrap"
src="https://sdk.openui5.org/resources/sap-ui-core.js"
data-sap-ui-libs="sap.ui.core,sap.m,sap.ui.unified,sap.ui.layout"
data-sap-ui-theme="sap_horizon_dark"
data-sap-ui-async="true"
data-sap-ui-oninit="onUI5Init"
data-sap-ui-compatversion="edge"
data-sap-ui-excludejquerycompat="true"
data-sap-ui-xx-waitfortheme="init"
></script>
<body id="content" class="sapUiBody sapUiSizeCompact"></body>
API reference: sap/ui/model/type/DateTime
ODataModel
globalThis.onUI5Init = () => sap.ui.require([
"sap/ui/core/mvc/XMLView",
"sap/ui/model/odata/v4/ODataModel",
"sap/ui/core/mvc/Controller",
"sap/ui/core/Core",
], async (XMLView, ODataModel, Controller, core) => {
"use strict";
const control = await XMLView.create({
definition: `<mvc:View controllerName="demo.MyController"
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:core="sap.ui.core"
core:require="{
TypeDateTimeOffset: 'sap/ui/model/odata/type/DateTimeOffset'
}"
displayBlock="true"
>
<App>
<Page
showHeader="false"
class="sapUiResponsiveContentPadding"
binding="{
path: '/People(userName=%27sandyosborn%27)/Trips(20)',
events: {
dataReceived: '.onDateTimeReceived'
}
}"
>
<ObjectAttribute
title="Model value"
text=""{ path: 'StartsAt', targetType: 'any' }""
/>
<ObjectAttribute title="Nullable" text="false" />
<DateTimePicker id="myDTP"
busy="true"
busyIndicatorDelay="1"
width="15rem"
value="{
path: 'StartsAt',
type: 'TypeDateTimeOffset',
formatOptions: {
style: 'medium/short'
},
constraints: {
nullable: false
}
}"
parseError="alert('Parse error')"
validationError="alert('Validation error')"
/>
</Page>
</App>
</mvc:View>`,
models: new ODataModel({
serviceUrl: "https://services.odata.org/TripPinRESTierService/(S(o1bizjomxywpc12mu2ad3fje))/",
autoExpandSelect: true,
operationMode: "Server",
}),
controller: new (Controller.extend("demo.MyController", {
onDateTimeReceived: function() {
this.byId("myDTP").setBusy(false);
},
}))(),
});
core.getMessageManager().registerObject(control, true);
control.placeAt("content");
});
<script id="sap-ui-bootstrap"
src="https://sdk.openui5.org/resources/sap-ui-core.js"
data-sap-ui-libs="sap.ui.core,sap.m,sap.ui.unified,sap.ui.layout"
data-sap-ui-theme="sap_horizon_dark"
data-sap-ui-async="true"
data-sap-ui-oninit="onUI5Init"
data-sap-ui-compatversion="edge"
data-sap-ui-excludejquerycompat="true"
data-sap-ui-resourceroots='{ "demo": "./" }'
data-sap-ui-xx-waitfortheme="init"
></script>
<body id="content" class="sapUiBody sapUiSizeCompact"></body>
API Reference: sap/ui/model/odata/type/DateTimeOffset
Documentation: "Dates, Times, Timestamps and Time Zones" (must-read)
Note
Unlike sap/ui/model/type/Date*, there is currently no support for minimum & maximum constraints in sap/ui/model/odata/type/* yet (Except for Decimal).
Until then, you could extend the DateTimeOffset type and implement the validateValue method accordingly. Sample: https://embed.plnkr.co/qatUyq
You have to use the fully qualified object name in your data type declaration as you're referring to a JavaScript object not to a build in HTML type. If you change the following part:
DateTime to sap.ui.model.type.DateTime
it will work. Please be aware that attributes like valueFormat or displayFormat as used in your example are ignored if a type is in use. In this case you have to provide these information in the binding. For further details please check the documentation of the type implementation.
An shortened example can be found here. More examples can be found in the UI5 Explored application which is in general a good starting point. An explanation of binding in general can be found here.
If you don't want to that much work in JS, I believe you can work with the validationError event. Simply set in in your XML, validationError="functionNameHere" and in your JS you can just set the ValueState to error. The validationError event is fired when the value can't be sent to the model, so you don't have to do any checks on the formatting, this event occurring means the formatting is indeed wrong. You can check the link below to read the documentation.
https://sapui5.hana.ondemand.com/#docs/api/symbols/sap.ui.base.ManagedObject.html#event:validationError
I have a date. It is a string in the JSONModel (for example '2016'), shown by DateTimeInput:
<DateTimeInput
value="{year}"
displayFormat="yyyy"
valueFormat="yy"
/>
However, DateTimeInput is deprecated and I want replace it by DatePicker:
<DatePicker
value="{year}"
displayFormat="yyyy"
valueFormat="yy"
/>
But when the click on the value help, the picker shows the calendar, not the list of years only.
As of UI5 1.68, DatePicker is capable of displaying the year-picker only. To enable it, displayFormat and valueFormat should be "yyyy".
Below is a small demo, including binding and validation:
sap.ui.getCore().attachInit(() => sap.ui.require([
"sap/ui/core/Fragment",
"sap/ui/model/json/JSONModel",
"sap/ui/core/Core",
], async (Fragment, JSONModel, Core) => {
"use strict";
const control = await Fragment.load({
definition: `<DatePicker xmlns="sap.m" xmlns:core="sap.ui.core"
core:require="{ DateType: 'sap/ui/model/type/Date' }"
maxDate="{/maxDate}"
class="sapUiTinyMargin"
displayFormat="yyyy"
valueFormat="yyyy"
width="7rem"
value="{
path: '/myYear',
type: 'DateType',
formatOptions: {
pattern: 'yyyy',
source: {
pattern: 'yyyy'
}
},
constraints: { maximum: 2030 }
}"
/>`,
});
Core.getMessageManager().registerObject(control, true);
control.setModel(new JSONModel({
myYear: new Date().getFullYear(), // current year, e.g. 2019
maxDate: new Date("2030-12-31") // control awaits a JS date object for maxDate
})).placeAt("content");
}));
<script id="sap-ui-bootstrap"
src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.ui.core, sap.m, sap.ui.unified"
data-sap-ui-theme="sap_fiori_3"
data-sap-ui-async="true"
data-sap-ui-compatversion="edge"
data-sap-ui-xx-waitfortheme="init"
></script><body id="content" class="sapUiBody"></body>
Using sap.m.Select, I have a similar code as this below:
<m:Select
selectedKey='{state}'
items="{
path: 'states>/content',
sorter: {
path: 'name'
}
}">
<core:Item key="{states>id}" text="{states>name}" />
</m:Select>
As want to be able to filter states by country when it is selected in another input, so, I'm trying using filters, which is defined in documentation in:
https://sapui5.netweaver.ondemand.com/docs/api/symbols/sap.ui.base.ManagedObject.html#bindAggregation
https://sapui5.netweaver.ondemand.com/#docs/api/symbols/sap.ui.model.Filter.html
The problem is that I couldn't find anywhere (docs, google, SO, source code, examples, tests) showing how to correctly use it. I tried these 2 ways with no success:
<m:Select
selectedKey='{state}'
items="{
path: 'states>/content',
sorter: {
path: 'name'
},
filters: [{
path: 'countryId',
operator: 'EQ',
value1: '10' // just example
]}
}">
<core:Item key="{states>id}" text="{states>name}" />
</m:Select>
and
# View
<m:Select
selectedKey='{state}'
items="{
path: 'states>/content',
sorter: {
path: 'name'
},
filters: ['.filterByCountry'}
}">
<core:Item key="{states>id}" text="{states>name}" />
</m:Select>
# Controller
...
filterByCountry: new sap.ui.model.Filter({
path: 'countryId',
operator: 'EQ',
value1: '10'
}),
...
Anybody knows the proper way to use it?
Here is how filters work in XML Views - see the 2 examples below I coded for you (use the jsbin links if they don't run here on stackoverflow). They both use the Northwind OData service. As you will see it's pretty much straight forward:
<Select
items="{
path : '/Orders',
sorter: {
path: 'OrderDate',
descending: true
},
filters : [
{ path : 'ShipCountry', operator : 'EQ', value1 : 'Brazil'}
]
}">
Of course, you can add multiple filters as well (see the second example below).
However, keep in mind that the filters are declared in the XMLView. Unfortunately, UI5 is currently not so dynamic to allow changing such filters defined in an XMLView dynamically by only using the binding syntax in the XMLView. Instead you would need some piece of JavaScript code. In your case you could listen for the change event of the other field. In the event handler you would then simply create a new Filter and apply it:
var oSelect, oBinding, aFilters, sShipCountry;
sFilterValue = ...; // I assume you can get the filter value from somewhere...
oSelect = this.getView().byId(...); //get the reference to your Select control
oBinding = oSelect.getBinding("items");
aFilters = [];
if (sFilterValue){
aFilters.push( new Filter("ShipCountry", FilterOperator.Contains, sFilterValue) );
}
oBinding.filter(aFilters, FilterType.Application); //apply the filter
That should be all you need to do. The examples below do not use any JavaScript code for the filter, but I guess you get the idea.
1. Example - Select box:
Run the code: https://jsbin.com/wamugexeda/edit?html,output
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SAPUI5 single file template | nabisoft</title>
<script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-libs="sap.m"
data-sap-ui-bindingSyntax="complex"
data-sap-ui-compatVersion="edge"
data-sap-ui-preload="async"></script>
<!-- use "sync" or change the code below if you have issues -->
<!-- XMLView -->
<script id="myXmlView" type="ui5/xmlview">
<mvc:View
controllerName="MyController"
xmlns="sap.m"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc">
<Select
items="{
path : '/Orders',
sorter: {
path: 'OrderDate',
descending: true
},
filters : [
{ path : 'ShipCountry', operator : 'EQ', value1 : 'Brazil'}
]
}">
<core:Item key="{OrderID}" text="{OrderID} - {ShipName}" />
</Select>
</mvc:View>
</script>
<script>
sap.ui.getCore().attachInit(function () {
"use strict";
//### Controller ###
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/odata/v2/ODataModel"
], function (Controller, ODataModel) {
"use strict";
return Controller.extend("MyController", {
onInit : function () {
this.getView().setModel(
new ODataModel("https://cors-anywhere.herokuapp.com/services.odata.org/V2/Northwind/Northwind.svc/", {
json : true,
useBatch : false
})
);
}
});
});
//### THE APP: place the XMLView somewhere into DOM ###
sap.ui.xmlview({
viewContent : jQuery("#myXmlView").html()
}).placeAt("content");
});
</script>
</head>
<body class="sapUiBody">
<div id="content"></div>
</body>
</html>
2. Example - Table:
Run the code: https://jsbin.com/yugefovuyi/edit?html,output
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SAPUI5 single file template | nabisoft</title>
<script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-libs="sap.m"
data-sap-ui-bindingSyntax="complex"
data-sap-ui-compatVersion="edge"
data-sap-ui-preload="async"></script>
<!-- use "sync" or change the code below if you have issues -->
<!-- XMLView -->
<script id="myXmlView" type="ui5/xmlview">
<mvc:View
controllerName="MyController"
xmlns="sap.m"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc">
<Table
id="myTable"
growing="true"
growingThreshold="10"
growingScrollToLoad="true"
busyIndicatorDelay="0"
items="{
path : '/Orders',
sorter: {
path: 'OrderDate',
descending: true
},
filters : [
{ path : 'ShipCity', operator : 'Contains', value1 : 'rio'},
{ path : 'ShipName', operator : 'EQ', value1 : 'Hanari Carnes'}
]
}">
<headerToolbar>
<Toolbar>
<Title text="Orders of ALFKI"/>
<ToolbarSpacer/>
</Toolbar>
</headerToolbar>
<columns>
<Column>
<Text text="OrderID"/>
</Column>
<Column>
<Text text="Order Date"/>
</Column>
<Column>
<Text text="To Name"/>
</Column>
<Column>
<Text text="Ship City"/>
</Column>
</columns>
<items>
<ColumnListItem type="Active">
<cells>
<ObjectIdentifier title="{OrderID}"/>
<Text
text="{
path:'OrderDate',
type:'sap.ui.model.type.Date',
formatOptions: { style: 'medium', strictParsing: true}
}"/>
<Text text="{ShipName}"/>
<Text text="{ShipCity}"/>
</cells>
</ColumnListItem>
</items>
</Table>
</mvc:View>
</script>
<script>
sap.ui.getCore().attachInit(function () {
"use strict";
//### Controller ###
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/odata/v2/ODataModel"
], function (Controller, ODataModel) {
"use strict";
return Controller.extend("MyController", {
onInit : function () {
this.getView().setModel(
new ODataModel("https://cors-anywhere.herokuapp.com/services.odata.org/V2/Northwind/Northwind.svc/", {
json : true,
useBatch : false
})
);
}
});
});
//### THE APP: place the XMLView somewhere into DOM ###
sap.ui.xmlview({
viewContent : jQuery("#myXmlView").html()
}).placeAt("content");
});
</script>
</head>
<body class="sapUiBody">
<div id="content"></div>
</body>
</html>
Here I see I can insert a date-time input:
https://ui5.sap.com/#/entity/sap.m.DateTimeInput/sample/sap.m.sample.DateTimeInput
<DateTimeInput type="Date" placeholder="Enter Date ..." />
But I want the user to choose only month and year, not the day.
Is it possible?
Yes, surprisingly easy:
Add the following attribute to your DateTimeInput: displayFormat="MM/yyyy"
As sap.m.DateTimeInput is deprecated, sap.m.DatePicker should be used in our case.
Same as picking the year only, DatePicker now can handle displayFormat="MM/yyyy" since UI5 1.68. The picker opens then with a month picker directly.
Below is a small sample with binding and validation:
sap.ui.getCore().attachInit(() => sap.ui.require([
"sap/ui/core/Fragment",
"sap/ui/model/json/JSONModel",
"sap/ui/core/Core",
], async (Fragment, JSONModel, Core) => {
"use strict";
const control = await Fragment.load({
definition: `<DatePicker xmlns="sap.m" xmlns:core="sap.ui.core"
core:require="{ DateType: 'sap/ui/model/type/Date' }"
maxDate="{/maxDate}"
class="sapUiTinyMargin"
displayFormat="MM/yyyy"
valueFormat="MM/yyyy"
width="7rem"
value="{
path: '/myMonthYear',
type: 'DateType',
formatOptions: {
pattern: 'MM/yyyy',
source: {
pattern: 'MM/yyyy'
}
},
constraints: { maximum: '12/2030' }
}"
/>`,
});
Core.getMessageManager().registerObject(control, true);
control.setModel(new JSONModel({
myMonthYear: `${new Date().getMonth() + 1}/${new Date().getFullYear()}`, // current month/year, e.g. '11/2019'
maxDate: new Date("2030-12-31") // control awaits a JS date object for maxDate
})).placeAt("content");
}));
<script id="sap-ui-bootstrap"
src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.ui.core, sap.m, sap.ui.unified"
data-sap-ui-theme="sap_fiori_3"
data-sap-ui-async="true"
data-sap-ui-compatversion="edge"
data-sap-ui-xx-waitfortheme="init"
></script><body id="content" class="sapUiBody"></body>