How to: SAPUI5 User Input Validations
Hallo Guys
Today I would like to show you how to do front end user input validations in SAPUI5.
How to show a user that a field is mandatory
You know those little red stars that we all know indicates a required field? Well we can do this in SAPUI5 as well.
The trick is to remember that this is usually indicated in the label, not the control
Example:
Use the “required” property to indicate that a control is mandatory.
tfdMineManager = new sap.ui.commons.TextField({
id : “tfdMineManagerID”,
required : true,
});
But you won’t see anything yet, you have to link the control to a label using the “labelFor” property
lblMineManager = new sap.ui.commons.Label({
text : “Mine Manager Section:”,
labelFor : tfdMineManager,
});
Now you will see the infamous little red star
This does not do any actual validation, it merely shows the user that this is a required field.
How to force the user to enter a value in a mandatory field
There is this awesome thing called Value State, which is available with most of the input controls.
Example:
//View
tfdMineManager = new sap.ui.commons.TextField({
id : “tfdMineManagerID”,
required : true,
change : function() {
if (this.getValue() === “”) {
this.setValueState(sap.ui.core.ValueState.Error); // if the field is empty after change, it will go red
}
else {
this.setValueState(sap.ui.core.ValueState.None); // if the field is not empty after change, the value state (if any) is removed
}
}
});
What if I only want to show a warning?
Sometimes there are grey (or yellow) areas that we have to cater for. In this case we use the Warning value state.
You can make use of any of the following vlaue states :
I want to validate a numeric field
This is a common requirement, but you can replace the function with whatever your validation check should be.
Example:
var testPreCalibration = sap.ui.getCore().getControl(“PreCalibration”).getValue();
if ( ! sap.ui.controller(<my controller>).isNumberFieldValid(testPreCalibration) ){
sap.ui.getCore().getControl(“PreCalibration”).setValueState(sap.ui.core.ValueState.Error);
}
isNumberFieldValid : function(testNumber){
var noSpaces = testNumber.replace(/ +/, ”); //Remove leading spaces
var isNum = /^\d+$/.test(noSpaces); // test for numbers only and return true or false
return isNum;
};
What do you do for controls that don’t support value states?
Not all of the input controls have value states. An example of this would be the DateTimeInput control . . . . .setValueState does nothing for this control . . . .
Let me introduce you to my dear friend . . . . CSS. ο
Without too much coding we can create a CSS class for this control.
Example :
//Index
.myTimeErrorValueState input{
border-width: 1px;
border-style: Solid;
border-color: #CC0000;
background-color: #FFDDD9;
}
.myTimeWarningValueState input{
border-width: 1px;
border-style: Solid;
border-color: #CC5200;
background-color: #FFFFCC;
}
//Controller for error
var testTotalTime = sap.ui.getCore().getControl(“TotalTime”).getText();
if ( createTotalTime == “0” ){
sap.ui.getCore().getControl(“StartTime”).addStyleClass(“myTimeErrorValueState”);
sap.ui.getCore().getControl(“StopTime”).addStyleClass(“myTimeErrorValueState”);
};
//Controller for warning
var testStart = sap.ui.getCore().byId(“StartTime”).getDateValue();
var testStop = sap.ui.getCore().byId(“StopTime”).getDateValue();
if ( start > stop ){
sap.ui.getCore().getControl(“StartTime”).addStyleClass(“myTimeWarningValueState”);
sap.ui.getCore().getControl(“StopTime”).addStyleClass(“myTimeWarningValueState”);
};
What if you need to display a message to explain to the user why the fields are going red ?
You could trigger an alert or message to fire with the validation. We all have a few validations in our UI’s so a bunch of alerts popping up when you click submit just won’t do.
How do we handle all the validations in a single popup? Our validations only kick in after the user clicks submit.
We created a table that lists all the errors with a reason for the error/warning in addition to the red and yellow fields.
Example :
//controller
var errorData = [];
var errorExist = false;
var warningExist = false;
var testShiftWorked = sap.ui.getCore().getControl(“ShiftWorked”).getValue();
if ( ! sap.ui.controller(<my controller>).isTextFieldValid(testShiftWorked)){
errorExist = true;
sap.ui.getCore().getControl(“ShiftWorked”).setValueState(sap.ui.core.ValueState.Error);
errorData.push({ field : “Shift Worked”,
text : “Cannot be empty”,
type : “Error”,
icon : “sys-cancel-2”});
}
//repeat the above for all your validations
if ( errorExist || warningExist ){
var errorDialog = new sap.ui.commons.Dialog({
modal: true,
inverted: false,
title: “Data Validation”,
closed: function (oEvent) {
this.destroyContent()}
});
var errorTable = new sap.ui.table.Table({
editable : false,
id : “errorTableId”,
width : “550px”,
visibleRowCount: 5,
firstVisibleRow: 0,
selectionMode: sap.ui.table.SelectionMode.None,
navigationMode: sap.ui.table.NavigationMode.Paginator,
});
errorTable.addColumn(new sap.ui.table.Column({
editable : false,
label : new sap.ui.commons.Label({ text : “Icon” }),
template : new sap.ui.core.Icon({src : “{icon}”}),
width : “40px”,
hAlign : “Center”,
resizable : false,
}));
errorTable.addColumn(new sap.ui.table.Column({
editable : false,
label : new sap.ui.commons.Label({
text : “Type” }),
template : new sap.ui.commons.TextView().bindProperty(“text”, “type”),
width: “60px”,
resizable : false,
}));
errorTable.addColumn(new sap.ui.table.Column({
editable : false,
label : new sap.ui.commons.Label({
text : “Screen Field” }),
template : new sap.ui.commons.TextView().bindProperty(“text”, “field”),
width: “130px”,
resizable : false,
}));
errorTable.addColumn(new sap.ui.table.Column({
editable : false,
label : new sap.ui.commons.Label({
text : “Message” }),
template : new sap.ui.commons.TextView().bindProperty(“text”, “text”),
width: “300px”,
resizable : false,
}));
errorDialog.addContent(errorTable);
var errorModel = new sap.ui.model.json.JSONModel();
errorModel.setData({modelData: errorData});
errorTable.setModel(errorModel);
errorTable.bindRows(“/modelData”);
if ( ! errorExist && warningExist ){
var errorAccept = new sap.ui.commons.Button({
text: “Continue”,
icon : sap.ui.core.IconPool.getIconURI(“accept”),
width: “75px”,
press: function (oEvent) {
oEvent.getSource().getParent().close();
sap.ui.controller(<my controller>).goToMainActionView(inAction, false);
}
});
errorDialog.addButton(errorAccept);
}
var errorCancel = new sap.ui.commons.Button({
text: “Back”,
icon : sap.ui.core.IconPool.getIconURI(“nav-back”),
width: “75px”,
press: function (oEvent) {
oEvent.getSource().getParent().close();
return false;
}
});
errorDialog.addButton(errorCancel);
errorDialog.open();
}
else {
return true;
}
Using a Tooltip to tell users what the requirement is
Here you can find a demo of how you can use RichTooltip to help users: SAPUI5 SDK – Demo Kit
Hope this makes your SAPUI5 validations a bit easier.ο
If you have any suggestions, please feel free to share
Regards
Antonette
Very good explanation of how custom validation works - if we do not want to create custom datatypes for this matter.
Maybe one point you could add: I suppose there is no method in the framework which checks if there are any controls with Error or Warning state on the current page. So if the user clicks on "Save" we must somehow determine if there are warnings or errors and force the user to correct them before saving his work.
How do we do that in an efficient manner?
Thank you Frank π
Yes there is, see this heading section above:
"What if you need to display a message to explain to the user why the fields are going red ?"
The picture at the end of the section above shows a table (dialog) that gets displayed when the user clicks on save or submit. All validation checks run in the save event and the ones that fail get pushed to the table π The save only commits if all the validations were successfull.
Regards
Antonette
Hi Frank,
In the blog Generic UI5 form validator I explain a utility class 'Validator' I wrote which checks upon submit if all validations are passed (also those that are not triggered yet, such as unfilled-but-required fields).
It uses the standard SAPUI5 validation mechanism so you should not have to use any extra coding
Thanks Robin. This looks interesting.
I have left a few thoughts as comment to your blog.
Good post !! Congrats Antonette Oberholster
Thank you Tulio π
The Right post on my needy.. Thanks toAntonette Oberholster
Thanks
Kathiresan S
Thank you Kathiresan π
Very good explanation of how custom validation works.
Good post !!This looks interesting.
Thanks,
Rama
Thank you Rama π
Nice article, I'd like to add on the final table that has all messages, now UI5 has the MessageModel and MessageContainer to take care of that, it's pretty nice and all automatic, and looks good in the UI as well, you should give it a try.
Thanks.
Thank you Jeferson π
Wow that's cool, will check it out, thanks for letting me know π
Regards
Antonette
hi Antonette Oberholster
Nice Article overall, but i'm facing an issue in validating a numeric field.
The method .isNumberFieldValid() is not instantiating. Its showing an error.
And When I modify the code as:
var testPreCalibration = sap.ui.getCore().byId("idNumCreate").getValue();
var noSpaces = testPreCalibration.replace(/ +/, '');
var isNum = /^\d+$/.test(noSpaces);
if(testPreCalibration !==isNum)
{
sap.ui.getCore().byId("idNumCreate").setValueState(sap.ui.core.ValueState.Error);
alert("Please Enter numeric value");
}
Still the if( ) condition is not working...
Thanks for any help..!
Unless you are asking for clarification/correction of some part of the Document, please create a new Discussion marked as a Question. The Comments section of a Blog (or Document) is not the right vehicle for asking questions as the results are not easily searchable. Once your issue is solved, a Discussion with the solution (and marked with Correct Answer) makes the results visible to others experiencing a similar problem. If a blog or document is related, put in a link. Read the Getting Started documents (link at the top right) including the Rules of Engagement.
NOTE: Getting the link is easy enough for both the author and Blog. Simply MouseOver the item, Right Click, and select Copy Shortcut. Paste it into your Discussion. You can also click on the url after pasting. Click on the A to expand the options and select T (on the right) to Auto-Title the url.
Thanks, Mike (Moderator)
SAP Technology RIG
Hello Srishti
I think it might be the way you test isNum:
"if(testPreCalibration !==isNum)"
Remember isNum returns true or false.
So if it returns false then you set the value state to error.
Hope this helps
Antonette π
Thanks Β for the useful article.
Suppose that I want to make some validations in the BackEnd.
I mean... I create a function in SE37 which validates the information and
return if it is ok or not ( or a text indicating the results).
How can I call that function from SAPUI5?
Thanks in advance,
Hi Antonette,
Very nice blog.
I was wondering how can we do the validations ONLY if value is entered. Below is the scenario.
We have telephone field which is not mandatory. But, it is optional. So, if user do not enter anything, no error should be shown. BUT, if user enters it, it has to be in specific format.
I have added below as the value property on Input field:
"{path: 'AddAddress>/Number1', formatter: '.formatter.formatTelephone', type:'sap.ui.model.type.String' , constraints : { search : '^\\d{3}-\\d{3}-\\d{4}' }}"
above constraint works fine to validate phone is in format xxx-xxx-xxxx. However, it validates even field is empty.
Do you have any idea how to tackle it?
-Bhavik
You can also use the binding magic "expressional binding syntax" to easy check if a field is empty i.e. by adding these properties to the xml view definition of the input element.
...valueState="{= ${/yourVariableName} === '' ? 'Error' : 'Success'}" valueLiveUpdate="true"...
Result is then red/green border depending on if something is entered in the field
Hi Antonette,
I understand this is a very old post but let me still take a shot.
I'm having a challenge on input validation when in a TABLE. Imagine two columns: Received Qty and Action. In one row, when I change 'Received', I wanted to control the value state of 'Action'.
From submit event of 'Received', my problem is that I can't find a way to get to the source for 'Action' so that I can trigger setValueState command.
Any idea. Thanks in advance.