Add "Today" button to controls that use calendar - datepicker

In my UI5 app, I have a sap.m.DatePicker object and I want to let user to pick today's date in one click.
I can add a button outside the sap.m.DatePicker but it looks ugly because I have about 15 sap.m.DatePicker objects on the same screen and it will be a poor UI/UX.
Is there any way to show a "Today" button in sap.m.DatePicker?

yes, currently the easiest ways is as already suggested to extend the DatePicker. Anyways the DatePicker is an input with a button and calendar in a popover. So if you want to go the hard way you could assemble your own control.

As of UI5 1.95 (commit dd3aeaa), controls displaying a calendar can set showCurrentDateButton with true in order to display a Today-icon in the navigation header area.
Here is a sample with sap.m.DatePicker:
globalThis.onUI5Init = () => sap.ui.require([
"sap/ui/core/mvc/XMLView"
], async XMLView => (await XMLView.create({
definition: document.getElementById("myxmlview").textContent,
height: "100%",
})).placeAt("content"));
<script defer id="sap-ui-bootstrap"
src="https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.ui.core,sap.m,sap.ui.unified"
data-sap-ui-oninit="onUI5Init"
data-sap-ui-async="true"
data-sap-ui-theme="sap_fiori_3"
data-sap-ui-excludejquerycompat="true"
data-sap-ui-compatversion="edge"
data-sap-ui-xx-waitfortheme="init"
></script>
<script id="myxmlview" type="text/xml">
<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" displayBlock="true">
<App>
<Page showHeader="false" class="sapUiResponsiveContentPadding">
<DatePicker showCurrentDateButton="true" value="1972-04-01" width="8rem"/>
</Page>
</App>
</mvc:View>
</script>
<body id="content" class="sapUiBody sapUiSizeCompact"></body>
Once clicked, the calendar will navigate to and focus today's date.
Press Enter, Space, or click the focused date to select today.

Related

Using a controller and and view together

I'm writing my first SAP app, and having gone through some of the tutorials, I understand that I need a controller for my view if I want it to do anything.
When I add the controllerName="./controller/login" (the controller's called 'login.controller.js'), it doesn't work, and I've tried variations of this.
The tutorials get me to copy code that uses the controller name, but they don't teach me anything about how to write the string for my own controller code.
How do I do this?
Controller code looks like this so far:
sap.ui.define([
"sap/ui/core/mvc/Controller"
], function(Controller) {
"use strict";
return Controller.extend("controller.Login", {
// controller logic goes here
});
});
and the view code looks like this:
<mvc:View
controllerName="controller.Login"
xmlns="sap.m"
xmlns:form="sap.ui.layout.form"
xmlns:mvc="sap.ui.core.mvc">
<Panel headerText="{/panelHeaderText}" class="sapUiResponsiveMargin" width="auto">
<form:SimpleForm editable="true" layout="ColumnLayout">
<Label text="User Name"/>
<Input value="{/firstName}" valueLiveUpdate="true" width="200px"/>
<Label text="Password"/>
<Input value="{/lastName}" valueLiveUpdate="true" width="200px"/>
<Button text="login" press=".onVisitHomePage"/>
</form:SimpleForm>
</Panel>
</mvc:View>
I'm going to add the .onVisitHomePage function to the controller but first I want to get this to work.
Like Julian Schmuckli already said you have to prefix the controller.login with your Namespace check you index.html where you initialize the sap-ui-core (see below).
<script src="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" data-sap-ui-async="true"
data-sap-ui-frameOptions="trusted" data-sap-ui-appCacheBuster="./"
data-sap-ui-resourceroots='{
"your.namespace": "./",
"sap.ui.demo.mock": "mockdata"
}'></script>
Here you have to take the string that is in place of the "your.namespace" and combine it with the controller.login to your.namespace.controller.login .
You have to do this in both the view and the controller file.

Date picker: How to change the focus of calendar to today's date in UI5?

I'm facing an issue regarding sap.m.DatePicker. I want to see Today's Date in the calendar, when I click on the calendar Icon. But I'm not able to display. Below is my Code:
<DatePicker displayFormat="dd-MM-yyyy" valueFormat="yyyy-MM-dd" value="31-12-9999" navigate=".onNavigateDate"/>
In the above screenshot, I'm getting date 31-12-9999 from the back-end. But if click on calendar icon, I should see today's date in the calendar. It is very difficult for the user to navigate to the current date.
I have tried using setInitialFocusedDateValue but it didn't work. Below is my JavaScript code for the navigate event.
onNavigateDate: function(event) {
var dateObject = event.getSource();
dateObject.setModel(new JSONModel({ date: new Date() }));
var m = dateObject.getModel();
dateObject.setDateValue(m.getProperty("/date"));
dateObject.setInitialFocusedDateValue(m.getProperty("/date"));
},
Can someone please help me to display today's date in the calendar if I click on the Calendar Icon?
I used the navigate event like this and it worked:
View:
<DatePicker
id="DP1"
placeholder="Enter Date ..."
navigate="onNavigate"
value="31-12-9999"
class="sapUiSmallMarginBottom"/>
And in the controller:
onNavigate : function(oEvent) {
oEvent.getSource().setValue(new Date())
}
The logic you are using on your navigate method does not seem to work. Probably because of your UI5 version. The initialFocusedDateValue property was only released on version 1.46.0. Also, keep in mind that the approach I did changes the value of the date picker, which means that once closed, it will have today's date as a value.
by default it shows today's date
remove 31-12-9999 in here
<DatePicker displayFormat="dd-MM-yyyy" valueFormat="yyyy-MM-dd" editable="true" navigate="onclickDate" value="31-12-9999"/>
unfortunately, you have to override a private function :-(
oDatePicker._openPopup = function() {
var today = new Date();
this.setValue(today.getFullYear() + '-' + (today.getMonth() +1) + '-' + today.getDate());
DatePicker.prototype._openPopup.apply(this, arguments);
}
http://jsbin.com/dotames/edit?html,js,output
because we cannot change value in the navigate event handle as it is too late (popover has already appeared)
It is very difficult for the user to navigate to the current date.
Since UI5 1.95 (commit dd3aeaa), controls displaying a calendar can set showCurrentDateButton="true" in order to display a Today icon in the navigation header area.
Here is a sample with sap.m.DatePicker:
<!-- No navigate handler needed -->
<DatePicker showCurrentDateButton="true"/>
globalThis.onUI5Init = () => sap.ui.require([
"sap/ui/core/mvc/XMLView"
], async XMLView => {
const definition = document.getElementById("myxmlview").textContent;
const view = await XMLView.create({ definition });
view.placeAt("content");
});
<script defer id="sap-ui-bootstrap"
src="https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.ui.core,sap.m,sap.ui.unified"
data-sap-ui-oninit="onUI5Init"
data-sap-ui-async="true"
data-sap-ui-theme="sap_fiori_3"
data-sap-ui-excludejquerycompat="true"
data-sap-ui-compatversion="edge"
data-sap-ui-xx-waitfortheme="init"
></script>
<script id="myxmlview" type="text/xml">
<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" displayBlock="true">
<App>
<Page showHeader="false" class="sapUiResponsiveContentPadding">
<DatePicker showCurrentDateButton="true" value="9999-12-31" width="12rem"/>
</Page>
</App>
</mvc:View>
</script>
<body id="content" class="sapUiBody sapUiSizeCompact"></body>
Once clicked, the calendar will navigate to and focus today's date.
Press Enter, Space, or click the focused date to select today.

Flexible Column Layout Navigation (SAPUI5)

I've created an app with SAPUI5 that makes use of a Flexible Column Layout.
I'm trying to navigate between pages, but I'm having difficulty.
Here is the main xml view:
<mvc:View id="Main" controllerName="SAP.demo.controller.Main" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc"
displayBlock="true" xmlns="sap.f" xmlns:core="sap.ui.core" xmlns:m="sap.m">
<m:App id="idAppControl">
<m:pages>
<m:Page title="{i18n>title}">
<m:content>
<FlexibleColumnLayout id="fcl" initialMidColumnPage="start" layout="TwoColumnsBeginExpanded">
<beginColumnPages>
<m:Page title = "Master">
<m:content>
<Button text="Chart Button" press="displayChart"/>
</m:content>
</m:Page>
</beginColumnPages>
<midColumnPages>
<m:Page id="start" title = "Detail">
<m:content>
<core:Fragment fragmentName="SAP.demo.view.Start" type="XML"/>
</m:content>
</m:Page>
<m:Page id="charts" title="Charts">
<m:content>
<core:Fragment fragmentName="SAP.demo.view.Charts" type="XML"/>
</m:content>
</m:Page>
</midColumnPages>
</FlexibleColumnLayout>
</m:content>
</m:Page>
</m:pages>
</m:App>
I want to navigate from the start page to the charts page. The controller is as follows:
sap.ui.define([
"sap/ui/core/mvc/Controller"], function (Controller) {
"use strict";
return Controller.extend("SAP.demo.controller.Main", {
displayChart:function(oEvent){
this.byId("fcl").toMidColumnPage("charts");
}
});});
Can someone please advise as to what I'm doing wrong, because it stays on the start page even after I press the button.
This is because the real ID of the view is not "charts" but "__xmlview0--charts".
Be careful with the ID always and use the API method byId('theIDHere').
In your case use one of the following options:
displayChart:function(oEvent){
this.getView().byId("fcl").toMidColumnPage(this.getView().byId("charts"));
}
Or
displayChart:function(oEvent){
this.getView().byId("fcl").toMidColumnPage(this.getView().byId("charts").getId());
}
And also add the correct XML namespace to your button
<m:Button text="Chart Button" press="displayChart"/>
Managed to fix it with the following code:
displayChart: function () {
this.byId("fcl").toMidColumnPage(this.createId("charts"));
},

How can I put icon and text in select items

I have an sap.m.Select control for a list of countries and I need to put flag near everyone. How can I do it? In XML, if it's possible.
Here is my XML code:
<m:Label text="{i18n>COUNTRY}" />
<m:Select width="100px"
fieldWidth="60%"
class="xcuiInputNoMargin"
enabled="{Edit>/EditOn}"
items="{countryList>/}"
>
<core:Item
key="{countryList>Country}"
text="{countryList>Country} - {countryList>Name}"
/>
</m:Select>
The sap.m.Select Object is restricted to display text (or Like #Jasper_07 said) icon only.
I think that the best solution for your problem is to use another object instead of your select. You can use Select Dialog and put inside whatever you want, like listItem with image.
This is an example:
<SelectDialog
noDataText="No Products Found"
title="Select Product"
search="handleSearch"
confirm="handleClose"
close="handleClose"
items="{
path: '/ProductCollection'
}" >
<StandardListItem
title="{Name}"
description="{ProductId}"
icon="{ProductPicUrl}"
iconDensityAware="false"
iconInset="false"
type="Active" />
</SelectDialog>
see link bellow
As of UI5 version 1.62, the following controls support displaying the icon on the left side.
sap.m.Select
sap.m.SelectList
And other controls based on the above mentioned ones, such as sap.m.ComboBox.
Here is an example:
sap.ui.getCore().attachInit(() => sap.ui.require([
"sap/ui/core/mvc/XMLView",
], XMLView => XMLView.create({
definition: `<mvc:View xmlns:mvc="sap.ui.core.mvc" height="100%">
<Select xmlns="sap.m" xmlns:core="sap.ui.core" class="sapUiTinyMargin">
<core:ListItem text="Paper plane" icon="sap-icon://paper-plane" />
<core:ListItem text="Stop Watch" icon="sap-icon://fob-watch" />
<core:ListItem text="Umbrella" icon="sap-icon://umbrella" />
</Select>
</mvc:View>`
}).then(view => view.placeAt("content"))));
<script id="sap-ui-bootstrap"
src="https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.ui.core, sap.m"
data-sap-ui-preload="async"
data-sap-ui-async="true"
data-sap-ui-theme="sap_belize"
data-sap-ui-compatversion="edge"
data-sap-ui-xx-waitfortheme="true"
data-sap-ui-xx-xml-processing="sequential"
></script>
<body id="content" class="sapUiBody sapUiSizeCompact"></body>
Keep in mind to use sap.ui.ListItem as an aggregation child in this case, instead of sap.ui.core.Item.
Limitation
Currently, the icon property only allows resource paths from "sap-icon://*". I.e. images, that are not icons such as country flags, are not possible. A possible workaround would be to make use of emoji flags as additionalText.
Otherwise, I'd recommend to look for alternative controls as shmoolki suggested.
from the documentation of sap.m.Select
The URI to the icon that will be displayed only when using the
IconOnly type
seems limiting, but try
<m:Select
type="sap.m.SelectType.IconOnly"
icon="sap-icon://cart">
</m:Select>

How to Wrap CheckBox Labels

I'm using sap.m to build a simple mobile app. I've made a VBox to hold a few check boxes and embedded it in a Page.
The width of the box is neatly the width of the screen (320px in the iPhone 5 device mode on Chrome). The labels of the checkboxes do not adhere to this width and simply grow beyond.
var oTicks = new sap.m.VBox();
oTicks.addItem(new sap.m.CheckBox({
name: 'name',
text: 'Are the tools and equipment I am going to use in safe working order?'
}));
As you can see in the screenshot here, the label of the third check box is > 320px (it's 454 to be exact).
Is there any way I can "wrap" the label so that it pushes the other items down, and fits the text inside the box?
As of version 1.54, sap.m.CheckBox supports the property wrapping with which the control can determine whether the label's text should wrap or not. Default value is false (no wrapping).
Demo
sap.ui.require([
"sap/ui/core/Core",
], Core => Core.attachInit(() => sap.ui.require([
"sap/ui/core/mvc/XMLView",
"sap/ui/model/json/JSONModel",
], (XMLView, JSONModel) => XMLView.create({
definition: `<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" height="100%">
<App>
<Page title="Checkbox Wrapping">
<headerContent>
<Switch state="{/wrapping}"
customTextOff=" "
customTextOn=" "
/>
</headerContent>
<VBox width="320px" backgroundDesign="Solid">
<CheckBox
text="Are the tools and equipment I'm going to use in safe working order?"
wrapping="{/wrapping}"
/>
</VBox>
</Page>
</App>
</mvc:View>`,
models: new JSONModel({ wrapping: false }),
}).then(view => view.placeAt("content")))));
<script id="sap-ui-bootstrap"
src="https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-libs="sap.ui.core, sap.m"
data-sap-ui-async="true"
data-sap-ui-theme="sap_fiori_3_dark"
data-sap-ui-compatversion="edge"
data-sap-ui-xx-waitfortheme="init"
></script>
<body id="content" class="sapUiBody sapUiSizeCompact"></body>
You can add a StyleClass to the CheckBox and use white-space: normal. SAPUI5 automatically put white-space: to no-wrap.
Edited to Jorgs final solution!
Example:
oTicks.addStyleClass('YourClassName');
In CSS:
.YourClassName label {
white-space: normal;
line-height: normal;
vertical-align: middle;
}