Skip to Content

Generic UI5 form validator

A common usecase is to have a form — or multiple forms — which should be validated upon clicking a “Submit” button. The UI5 validation mechanism by default does a terrific good job for inline validation (i.e. validating fields right after you have changed them, giving immediate feedback to the user) but this can lead to some issues.

Imagine a form with a couple of input fields which require a value. However, since they are initially empty, leaving them blank does not trigger a change event (and subsequent validation), so you could possibly submit your form without entering any data.

Or imagine you have a page with multiple forms, with input fields which depend on each other, and you want to validate all forms and their fields at once when clicking the “Submit” button.

Those cases are examples where after submit validation is more appropriate, and I will show how this can be achieved by still using the standard UI5 validation mechanism.

I have created a simple class which will validate your form(s) upon submitting it, and the implementation is pretty simple. But first, let me explain a bit about the standard validation mechanism.

To enable standard, inline validation of a control, you should do at least the following:

  1. Attach to the core’s validationError and validationSuccess error handlers
  2. Implement a contraint to the binding of your control

Attaching to the validation event handlers is pretty simple, and need only be done once (for instance in the view controller’s onInit() event handler):

    onInit: function() {

        // Attaches validation handlers

        sap.ui.getCore().attachValidationError(function (oEvent) {



        sap.ui.getCore().attachValidationSuccess(function (oEvent) {




Setting a constraint to a control is done using the UI5 Simple Types. For instance, to set an input field to required, you can simply use this:

    <Label text=”Name” required=”true” />

    <Input value=”{

        path : ‘/userName’,

        type : ‘sap.ui.model.type.String’,

        constraints : {

            minLength : 2



You could even use regular expressions, for instance for validating an email address:

    <Label text=”Email” required=”true” />

    <Input value=”{

        path : ‘/userEmail’,

        type : ‘sap.ui.model.type.String’,

        constraints : {

            search : ‘\\S+@\\S+\\.\\S+’



(The above example uses rather basic email validation, just a simple ‘lorem@ipsum.dolor’. Use a more robust regex productively!)

If you implement this in a UI5 page, and type a name of 1 character or supply an invalid email address, you will see the controls will be surrounded with a red border, and the validation error is displayed in a tooltip:

Screen Shot 2015-11-01 at 16.34.08.png

However, not entering anything will not trigger a validation…

I have created a simple class which takes care of the validation upon clicking a submit button, and the implementation is fairly simple:

    onSubmit: function() {

        // Create new validator instance

        var validator = new Validator();

        // Validate input fields against root page with id ‘somePage’

        if (validator.validate(this.byId(“somePage“))) {

            // perform the actual form submit here



You simply create a new instance of the class, and then call the only method of that class, ‘validate‘. The input parameter for that method is the ID of any page, control, or form you wish to set as the root container for your validation. The method returns ‘true’ if all fields are filled correctly (i.e., no constraints are violated), or false otherwise.

Below is a screenshot of the ‘validate’ method, and hopefully the inline comments explain everything that is happening:

Screen Shot 2015-11-01 at 16.59.28.png

In short:

  • Check if the supplied control is something that can be visible and actually is visible (no sense in checking anything that cannot be visible)
  • Then check if a constraint is set
  • If yes, then try validating the control as if it were an inline validation
  • However, if the control could not be validated, it may have aggregations that could be validated (i.e. it may be a form, a table, etc. which may hold child controls). We then check the children, and recursively call the validate method again

You can see a working demo of this ‘after-submit validation’ here.

The Validator code itself is available from GitHub. It is a simple, single file you may include in your project. If you find any bugs or room for improvement, please feel free to clone and submit any changes!

I hope some may find it useful!

You must be Logged on to comment or reply to a post.
  • Good One, I worked on same requirement, but did the validations through a utility method and getting each control through ID and setting error state based on the value.

    You can check whether the control is enabled along with visible property.

  • Good one!

    This is a good utility for triggering the validations based on databinding and standard simple types.

    But for me these simple type validations are most times not sufficient or the standard value state messages are too general.

    An example:

    I have a datepikcer bound to an OData model field and type set to sap.ui.model.type.Date

    <Label text="{i18n>ValidFrom}" required="true" />

    <DatePicker value="{path: 'ValidFrom', type: 'sap.ui.model.type.Date',

         formatOptions: { pattern: 'yyyy-MM-dd' } }"

         change="onChangeFormField" />


    Since this is a required field in my form it mustn't be empty.

    In the onChange event I check if the date is empty and call setValueState on the control.

    This seems to conflict with the standard validation triggered by the type assignment because I can see the red border appear for a very short time before it is removed again.

    This is because the type validation detects no error if no date is set.

    I think standard type validation doesn't work if custom validation on the same control should also be used.

    Leaving the

    type: 'sap.ui.model.type.Date'

    out of my control declaration also doesn't work because then the date format yyyy-MM-dd is lost.

    So what to do??

    It would be perfect in my eyes if your validator would take a callback function as argument.

    This function could then be called if there is no type validation for a binding or if the type validation didn't return any error.

    The callback function could check for which control it is called and do custom validations and return a custom value state message to your validator.

    What do you think?

    • Hi Frank,

      As far as I have experienced, all validations (which include required fields) could be handled using the simple types, even sap.ui.model.type.Date can be set to both a formatter and still be validated as required by setting the 'constraint' parameter:

      As you can see from the example I provided the DatePicker control is required too (although I forgot to include the 'required' property in the label, which is now fixed) because if you set a constraint:

      <DatePicker id="myDate" value="{

          path : '/date',

          type : 'sap.ui.model.type.Date',

          formatOptions : {

              source: {

                  pattern: 'dd-MM-yyyy'


              pattern: 'dd-MM-yyyy'


          constraints : {

              minimum : '01-01-1900'


      }"/> now must enter a date of at least Jan 01, 1900, which in effect makes your DatePicker require an input. Same is valid for strings (for instance, { minlength : 1 }), numbers (for instance, { minimum : 1 }), currency (for instance, { minimum : 0.01 }), etc

      • Ok, makes sense.

        However, I can't get the constraints to work with my datepicker.

        SAPUI5 SDK - Demo Kit

        The documentation says that

        • maximum (expects an date presented in the source-pattern format)
        • minimum (expects an date presented in the source-pattern format)

        I don't know the exact source format since it comes from the OData model.

        I tried different things as source: { pattern: '....' } but nothing worked.

        Any idea?

        Another point is the validation of dependencies between fields.

        I suppose you just do them "manually" after you call your validator class?

        Do then check whether a certain field may already have an error state set from the type based validation and then skip your advanced check?

        • Not sure about the OData pattern, but you may be able to determine it by just calling the service in a browser and see the date format...

          Validation dependency between fields (for instance, from-date must be before to-date, etc) I simply set a new constraint on both fields on the respective onChange events (so the from-date maximum is the to-date value, and the to-date minimum is the from-date value, etc)

          This way I ensure I still validate the 'correct' way and don't need to do any manual validation -- validating in multiple ways can lead to inconsistencies

          • The OData format of date values is internally mapped to Javascript Date objects in UI5.

            This one will set the minimum date to 1990-01-01

               value="{path: 'ValidFrom',
               type: 'sap.ui.model.type.Date',
                  formatOptions: {
                      pattern: 'yyyy-MM-dd',
                      strictParsing: 'true',
                      UTC: 'true'
                  constraints : {
                      minimum : 631148400000
              }" />

            But this will display a validation error which no one can understand:

            2015-12-07 10_19_41-SPOT.png

            And from your example: No user will understand this error message containing a regex.

            2015-12-07 10_20_18-Plunker.png

            Maybe we have to derive your own types for every use case where the validation messages of the standard simpe types don't suffice.

  • We use it and it works well. Now we try to disable button x when the form is invalid on init. That's mostly the case, when someone clicks create new x. In this case oControl.getBinding(aValidateProperties[i]) in line 53 of validator.js hostet on github for all returns undefined and in the end isValid/() returns true. Is that intended? What can we do?

    • If getBinding returns undefined, it usually means the binding is not set. Could you try moving your logic to the 'onAfterRendering()' event handler instead of onInit()? The form is not available in the onInit() hook, which may cause this issue

        • That is weird, because regardless of where you call the validator function (in onAfterRendering or in a button's press event handler), all controls should be available, and the instanceof should work just fine.

          However, this script was intended to be fired when clicking a button, and not as a listener (that's where the standard 'attachValidationError/Success' handlers are for.

          If you need to set the state of your button when editing fields, and enable/disable the button directly when filling fields (and validating them), you could better set the state of your button depending on the state in the core's 'attachValidationZzz' handlers

  • Hi Robin,

    another thing which I experienced using this validator:

    Having a sap.m.input which has a binding of type sap.ui.model.odata.type.Decimal thousand separators are automatically inserted (if configured this way). So passing this value

    "123,456.99" into validateValue gives an exception with message "Enter a number".

    The value has to be parsed from external into internal format first:

    var oBinding = oControl.getBinding(aValidateProperties[i]);

    var oValue = oControl.getProperty(aValidateProperties[i];

    oValue = oBinding.getType().parseValue(oValue, oBinding.sInternalType);


  • Great blog..

    Just a quick question, does this only works with Forms. I tried putting couple of input fields in VBox, attached the attachValidationError in init but for me, validations are never triggered.



    • The Validator is meant to be working from the Submit button, so you'll have to add something like this:

           onSubmit: function() {

              // Create new validator instance

              var validator = new Validator();

              // Validate input fields against root page with id 'somePage'

              if (validator.validate(this.byId("somePage"))) {

                  // perform the actual form submit here



      Validation through the use of this class is only triggered by explicitly calling the validate method.

      • I was just trying to test the first part, where validation should trigger when i am typing something out of constraint. Example if my constraint has maximum field length 4 and I type 5 characters, on exit of input field should display error. 🙂 as working in example here. But somehow not working for me. I put a debug point, to see what is going wrong. My debugger never reached    oEvent.getParameter("element").setValueState(ValueState.Error);. May be event is never regiseterd.



  • Hi Robin,

    really a nice feature! For now I decided to create my own validation using the "byId" option for the form fields though since I am still learning UI5 and want to know exactly what I am doing. But I might use it later because I really like what you build. 

    I succeeded in building the validation and when the user decides to use the back button I do a resetChanges() on the model to make sure their changes are 'canceled'. However, when validation errors were previously shown and the user opens the form again the validation errors are still shown on the fields, how do you reset those? Or better said is there another way (like resetChanges on the model) to reset them all at once or do I need to call a validationReset function where I just reset each of the statuses manually back to 'none' when the user leaves the screen?



  • Hi Robin,

    I need to call the validate method twice in the controller for 2 different fields. I cannot pass a parent control id as it is a Tree Table which has rows and there are some restrictions in using the rows aggregations.(it doesn't have a visible property)

    If in your example, I call the validate method twice for 2 different controls.


    validator.validate(this.byId("myNum"));  //for the input field in Another Form

    validator.validate(this.byId("myDate"));  //for the DatePicker in Another Form

    it validates both the controls but only highlights the last one (i.e datePicker) in red.

    Can you let me know what needs to be changed so that I can call the validate() for 2 or more controls. ?



  • Dear all,

    If you would like to use this validator function also inside your forms within a sap.m.ObjectPageLayout, you will have to expand the array "aPossibleAggregations" with the following three elements:

    "sections", "subSections", "_grid"

    var aPossibleAggregations = ["items", "content", "form", "formContainers", "formElements", "fields", "sections", "subSections", "_grid"],


    Happy validating 🙂


  • Quick question, I've implemented your code but i'm having issues. After entering text into a field and removing focus from that input the text is immediately erased. No errors in the console. Even with all blank fields the Validator is still getting a value of True.  Is there a minimum version of UI5 i need to be running? is this a problem you've seen or heard of before?

    • Hi Andrew, the only time I see this happening is when your control is not correctly bound to your model (but that has nothing to do with my code since that will only be invoked after a button press, and should in no way modify your control contents)

      Can you check whether you have bound your controls correctly to your model?

  • Hey Robin,


    Great job, thank you very much. However, I have some problems while trying validate the combobox. Can you please provide an example how to validate combobox/select element?

      • Hi Robin,

        Nice blog. It reduces developer efforts and saves time too.

        I just tried with Select control. But not able to achieve it. Following is the example:

        <Select selectedKey="" id="idSelect">
        <core:Item key="" text=""/>
        <core:Item key="ABC" text="ABC"/>
        <core:Item key="DEF" text="DEF"/>
        <l:GridData span="L2 M2 S10"/>

        Even if selected key is empty, no error is thrown.


        • Your code example is missing two things:

          1. Model binding
          2. A validation constraint

          Like all the other controls, this is mandatory.


          Your Select example should be something like this:

          <Select items="{/choices}" selectedKey="{ 
              path : '/mySelectedKey', 
              type : 'sap.ui.model.type.Integer', 
              constraints : { 
                  minimum : 1 
              <core:Item key="{key}" text="{value}"/>

          (In this example, the list of items should have a key equal or greater than 1 to validate, any other value will give a validation error)

  • Hello Robin.  Implementing this wonderful piece is a problem for me. Am using Eclipse to develop SAP UI5 apps, usually after creating projects it automatically creates the Controllers for you and the way it's set up it's totally different from the way yours is set up.  I have tried  to use jQuery.require to require the validator.js in the init and Validate functions in my controller, but it just wouldn't work.  I know am obviously doing something wrong . Please is there a way you can help me with the way my App files structured. see Image to help you understand what i have done,










  • Hello Robert Implementing this wonderful piece is a problem for me. I use eclipse for developing SAP UI5 Apps. usually after creating project, it automatically creates the controller for you and the way the controller is setup is totally different from yours. Am assuming I will have to do some Jquery.require but am not just getting it. Please can you help. I have attached screen shot so you can see what i have done so far.



      There’s a coupe of things wrong in your code:

      • you used a forward slash in your jQuery.require statement
      • the controller methods are outside the scope of your controller

      But regardless, the way Eclipse generates the controller is no longer recommended (not sure it’s no longer supported too, but apparently it works for you)

      I would strongly advice to set up your code using sap.ui.define, see 

      The API is at and click on ‘sap.ui.define’ for details.


      • Good day Robin.  So I took your Advice. Am defining my controllers using sap.ui.define and so far so good the validator has worked. But I still came up with some issues dho. I want the the method function not to work if they are still some fields not keyed in properly. like an If condition, I tried using this   if (validator.validate(this.byId(“somePage“))) but it didn't work, the lines of code were executed even with some fields red. I also put the validator var on console.log but it turns out that _isvalid always returns true .

          • Hello Robin am sorry for taking your time. How can I know in my controller when all form fields are validated correctly.  so I can perform some certain functions when all are validated and throw an error when some fields are not keyed in properly by the user . that's what i mean. See my screen shot to help you understand my point well. thank you 

          • Hello Robin, Thanks for your help for the Generic Validation. I ran into trouble again, Am trying to hide a Button in a View based on the value gotten from an Odata Request. I noticed that when I start the App from Index and navigate to the view, I get the values from the request as required. but when am on the view and use the browser refresh button, the values return as null.

            Now I understand that this might not be the right forum to ask this question, but I tried researching on my own on this issue and I noticed you commented on one of the forums that the Asynchronous nature of  SAP UI5 might be the issue when stuffs like this happen. I suspect that may be the issue and since you are already of help here i decided to seek for your help here again.

            I really hope you can help me . find attached Screen shots of code and equivalent Browser console.

  • I am facing issue  while adding same code in dialog box

    if i am using same form inside dialog box validation is not happening. Could you please guide me. issue happening at below lines.

    // Validate input fields against root page with id 'somePage'          validator.validate(this.byId("somePage"));

    if i am using like below

    // Validate input fields against root page with id 'somePage' // Validate input fields against root page with id 'somePage'          validator.validate(sap.ui.getCore().byId("somePage")); it is not entering into this line--> if (oControl.getBinding(aValidateProperties[i])) {

      • thank you for helping me sharing such a usefull blog to us. I go soultion for my issue.

        I am calling dialog box in fragment. after calling fragment i used this below line,then i am able to do validation.

        this.dialog11 = sap.ui.xmlfragment("popup.view.ContactPopup", this);

        this.getView().addDependent(this.dialog11); ;

  • Hi Robin,

    Very Nice Blog and a helpful one.

    Currently we have requirement in which during run time we set the fields in the form as mandatory  or not, and we do not have any constraints on the fields.

    Is there a way in which the form validates the mandatory fields during form submit?


    Thanks in Advance,


    • this is the code shared by others. you can check it:

      if (oControl.getBinding(aValidateProperties[i])) {
      ///original code
      }else if (oControl.getRequired && oControl.getRequired()===true) {
      oControlBinding = oControl.getBinding(aValidateProperties[i]);
      oExternalValue = oControl.getProperty(aValidateProperties[i]);
      if (!oExternalValue || oExternalValue==="") {
      this._isValid = false;
      new Message({
      message: "",
      type: MessageType.Error,
      target : ( oControlBinding.getContext() ? oControlBinding.getContext().getPath() + "/" : "") +
      processor: oControl.getBinding(aValidateProperties[i]).getModel()


  • Hello Robin,

    Could you please tell me how to work with search filed. this is not doing validation

    <SearchField width="200px" id="Processor" value="{
    path : '/Processor',
    type : 'sap.ui.model.type.String',
    constraints : {
    minLength :5,
    maxLength : 10

    • Hi,


      They do get validated (i.e. it will proceed into the exception handler) but since the SearchField does not extend from sap.m.InputBase, it will not indicate so with the red outline and message.



    I am using your validator and it works great.  I came across one issue with the sap.m.Datepicker control when I use the dateValue property instead of the value property.

    I added the property in the property list (aValidateProperties array).

    When the validator executes I have exception when trying to execute the following line:

    oInternalValue  = oControlBinding.getType().parseValue(oExternalValue, oControlBinding.sInternalType);

    I get the error: Don’t know how to parse Date from object

    The sINternalType is object and my oExternalValue is of the following format:

    Tue Nov 21 2017 00:00:00 GMT-0500 (Eastern Standard Time)

    Any ideas how I can parse that to validate?

    My control looks like:

    									<DatePicker id="datePicker_Other" dateValue="{ path : 'Zfbdt', type : 'sap.ui.model.type.Date', formatOptions : { source: { pattern: 'MMM dd, yyyy' }, pattern: 'MMM dd, yyyy' }, constraints : { minimum : '01-01-2000' } }" 
    									placeholder="{i18n>placeholderOtherDate}" enabled="true" visible="true" width="50%" tooltip="{i18n>tooltipOtherDate}"/>

    Thank You


  • Hello there!

    Has anyone managed to make this validator work with MultiComboBox? The problem I am facing comes from the fact that MultiComboBox has SelectedKeys property that returns an array which I don't know how to set constraints on.


  • Hi Robin,
    I used your validator class and modified it to basically change the value state of the input field in my smart table. Based on a particular property i am erroring out some input fields in the smart table but the issue is that when i scroll in my smart table as the structure is loaded onbeforerebindTable method so it loads the data into the structure.Hence it doesnt do for all the rows but only for the initial rows that are fetched by the framework. if the threshold below is set to the total number of rows in the backend then it works as it loads each cell correctly but this is not a viable solution as I need to get the scroller working.

    <table:Table rowActionCount="1" busyStateChanged="onBusyStateChanged" threshold="10" enableGrouping="true">

    any help i this regard is beneficial

    Prabuddha Raj