Sunday 12 May 2013

Add Form Validation using Model in Sencha Touch 2 - Part2

In Sencha Touch 2, Form Validation can be done using Model Validation. Before that, we are going to take the Form that we created as part of  'How to Create Basic Form Using Sencha Touch - Part1' Post. Here is the source code of the Basic Sencha Form with snapshot.
Ext.define('MyApp.view.FormPanel', {

    extend: 'Ext.form.Panel',
    alias: 'widget.FormPanel',

    config: {
        itemId: 'registrationform',
        items: [
            {
                xtype: 'fieldset',
                title: 'Registration Form',
                items: [
                    {
                        xtype: 'textfield',
                        label: 'Username',
                        labelWrap: true,
                        name: 'username',
                        placeHolder: 'Enter Username'
                    },
                    {
                        xtype: 'textfield',
                        label: 'Password',
                        labelWrap: true,
                        name: 'password',
                        placeHolder: 'Enter Password'
                    },
                    {
                        xtype: 'emailfield',
                        label: 'Email',
                        labelWrap: true,
                        name: 'email',
                        placeHolder: 'email@example.com'
                    },
                    {
                        xtype: 'urlfield',
                        label: 'Website',
                        labelWrap: true,
                        name: 'website',
                        placeHolder: 'http://example.com'
                    },
                    {
                        xtype: 'textareafield',
                        label: 'About You',
                        labelWrap: true,
                        name: 'aboutyou',
                        placeHolder: 'Tel me about yourself'
                    }
                ]
            },
            {
                xtype: 'button',
                itemId: 'save',
                width: '30%',
                text: 'Save'
            }
        ],
        listeners:[{
           fn: 'onFormSave',
           event: 'tap',
           delegate: '#save'
       }]
     }        
});

This basic form contains the following fields: Username, Password, Email, Website and AboutYou with tap listeners attached to the 'save' button. We are going to see, how we can apply model validation to this form.


Create a Model with Form Fields

Now, I am going to create a model with fields that matches with Form Fields using fields configuration. Using validations configuration, We are going to attach various validations types available to the form fields. Following are the those

Using presence validation, username, password, email and website Fields are required and can't be empty
Using format validation. username Field needs to be AlphaNumeric and error message that needs to be shown if validation fails.
Using email validation. email Field needs to be in Email Format and error message that needs to be shown if validation fails.
Using length validation, password field must contain minimum 6 characters and error message that needs to be shown if validation fails.

 Ext.define('MyApp.model.User',{
     extend: 'Ext.data.Model',
     alias: 'model.User',

       config: {
           fields: [
           {
              name: 'username'
           },
           {
              name: 'password'
           },
            {
              name: 'email'
           },
           {
              name: 'website'
           },
            {
              name: 'aboutyou'
           }
           ],
           validations: [
           {
              type: 'presence',
              field: 'username'
           },
           {
              type: 'presence',
              field: 'password'
           },
           {
              type: 'presence',
              field: 'email'
           },
           {
              type: 'presence',
              field: 'website'
           },
           {
              type: 'format',
              field: 'username',
              matcher: /[0-9A-Za-z]{6,15}/,
              message: 'Username should be alphanumeric'
           },
            {
              type: 'length',
              field: 'password',
              min: 6,
            message: 'Password must contain min 6 characters'
           },
            {
              type: 'email',
              field: 'email',
            message: 'Email format is invalid'
           }]
     }
});

How to Validate Form Fields

First, we are going to get the form values using getValues() inside onFormSave() Method, that will be trigged when 'save' button is clicked. This getValues() will returns an object containing the value of each field in the form, keyed to the field's name.

Now,  Lets create an instance of already defined User model Class using Ext.create() by setting fields with the form values and apply validation using validate(). This method returns error objects. Using isValid() method, we can check whether is there any errors. if error exists, we are forming error message using Ext.each() else we are display success message.

onFormSave: function(button,e,options){

var formObj = button.up('FormPanel');
var formData = formObj.getValues();

var usr = Ext.create('MyApp.model.User',{
     username: formData.username,
     password: formData.password,
     email:formData.email,
     website:formData.website,
     aboutyou: formData.aboutyou
});

var errs = usr.validate();
var msg = '';

if (!errs.isValid()) {
   errs.each(function (err) {
   msg += err.getField() + ' : ' + err.getMessage() + '<br/>';
   });

   Ext.Msg.alert('ERROR', msg);

} else {
    Ext.Msg.alert('SUCCESS', 'Looks like the Form is valid');
}

}

Following are the outputs


Hope, you enjoyed this Post.

In Part3 of this Post Series, We are going to see, how we can store the form values  locally using HTML5 LocalStorage API.
  • Part1 - How to create a basic form using Sencha Touch 2

21 comments:

  1. Very good post. But I encounter with a problem, it says "Uncaught TypeError: Cannot call method 'getValues' of undefined " ? why is that? I used controller class to handle the save button.

    ReplyDelete
    Replies
    1. Hi Upul,
      sorry, its my mistake. You need to use this code
      var formObj = button.up('FormPanel'); in order to get the FormPanel Object inside onFormSave() Method. I updated this code change in the Post.

      Thanks for your appreciation.

      Delete
  2. The code is now working. But suppose I use a controller class and there I handle the save button listener.

    var formObj = button.up('FormPanel');
    this is not working if I access from another class. instead of "button.up" what should I write there?

    is *button.up('FormPanel')* equal to *'MyApp.view.FormPanel'*

    ReplyDelete
    Replies
    1. You need to create references using refs configuration in controller in order to access view components in controller. Here is the Post
      http://sureshdotariya.blogspot.com/2013/04/how-to-access-view-component-inside.html

      You need to access the referenced view component using getter method. Eg this.getFormPanel().

      Thanks.

      Delete
    2. It is working. thank you very much.

      Delete
  3. Hi,
    i have done this but i want to change alert way of validation. I want to display alert in particular field rather in alert box how to do it.
    i tried for 2Hours but could not success.
    Can you help me.

    ReplyDelete
    Replies
    1. Hi, i added a sample code which validates on each field

      Ext.define('MyApp.view.FormPanel', {
      extend: 'Ext.form.Panel',
      alias: 'widget.FormPanel',

      config: {
      items: [
      {
      xtype: 'textfield',
      itemId: 'login',
      label: 'Login',
      placeHolder: 'Enter Username'
      }
      ],
      listeners: [
      {
      fn: 'onMytextfieldBlur',
      event: 'blur',
      delegate: '#login'
      }
      ]
      },

      onMytextfieldBlur: function(textfield, e, eOpts) {
      if(textfield.getValue() === ''){
      Ext.Msg.alert("Field can't be empty");
      textfield.setFocus(true);
      }
      }

      });

      Hope, this helps. Thanks

      Delete
    2. ahh sorry i mean i want display validation message in respective compoment if first name is empty then i would like to display must be prtesent in textfiled not alert box.
      Thank you!!

      Delete
    3. Here is the required code

      Ext.define('MyApp.view.FormPanel', {
      extend: 'Ext.form.Panel',
      alias: 'widget.FormPanel',

      config: {
      items: [{
      xtype: 'textfield',
      itemId: 'login',
      label: 'Login',
      placeHolder: 'Enter Username'
      }],
      listeners: [{
      fn: 'onMytextfieldBlur',
      event: 'blur',
      delegate: '#login'
      }]
      },

      onMytextfieldBlur: function (textfield, e, eOpts) {
      if (textfield.getValue() === '') {
      textfield.setValue("Field can't be empty");
      textfield.setFocus(true);
      }
      }

      });

      Hope, this helps. Thanks

      Delete
    4. Ok
      Thank You. I'll try and let you know.
      Thanks for the help.

      Delete
    5. You can easily do the individual field validation like this and arrange your model class validations in a sequence.

      onFormSave: function(button,e,options){
      var formObj = button.up('FormPanel');
      var formData = formObj.getValues();
      var usr = Ext.create('NotesApp.model.Note',{
      username: formData.username,
      password: formData.password,
      email:formData.email,
      website:formData.website,
      aboutyou: formData.aboutyou
      });
      var errs = usr.validate();
      var msg = '';
      var msgArray = [];

      if (!errs.isValid()) {
      errs.each(function (err) {
      msgArray.push(err.getField() + ' : ' + err.getMessage() + '
      ');
      });
      Ext.Msg.alert('ERROR', msgArray[0]);

      } else {
      Ext.Msg.alert('SUCCESS', 'Looks like the Form is valid');
      }
      }

      Delete
  4. Thank you very much Suresh! This is awesome Tutorial.

    ReplyDelete
  5. I have a tab panel like this,

    Ext.define('MyApp.view.FrontPage', {
    extend: 'Ext.tab.Panel',
    {
    title: 'HOME',
    itemId: 'home',
    items: [
    {
    xtype: 'address'
    }
    ]
    },
    {
    title: 'OFFICE',
    itemId: 'office',
    items: [
    {
    xtype: 'address'
    }
    ]
    },


    The xtype addresses extends Ext.form.panel and have following items

    Ext.define('MyApp.view.Address', {
    extend: 'Ext.tab.Panel',
    {
    xtype: 'textfield',
    name : 'address1',
    label: 'Address1',
    id: 'address_1',
    },
    {
    xtype: 'textfield',
    name : 'address2',
    label: 'Address2',
    id: 'txt_address_2',
    },

    I want to retrieve the value of address1 and address2 of home and office.
    i.e. Both home tab and office tab calls the same view, so how to get the values of home addresses (address1 and address2)
    and office address(address1 and address2).

    ReplyDelete
    Replies
    1. Hi Sathish,

      First, you need to get the active tab panel using the below code

      //first get active tab
      var currentTab = this.getActiveItem();

      Then get address1, address2 fields

      //get address1
      var address1 = currentTab.down('#address_1');

      //get address2
      var address2 = currentTab.down('#txt_address_2');

      Hope, this help

      Thanks
      Suresh Ariya

      Delete
    2. how to hide HOME tab from the output.
      Please reply fast.

      Delete
    3. Sathish,

      You need to use setHidden(true), in order to hide any component. Eg
      homeTab = this.down('#home');
      homeTab.setHidden(true);

      Thanks and Regards,
      Suresh Ariya

      Delete
    4. Sathish,

      Please use this code for hiding tab bar

      this.getTabBar().getComponent(0).hide(); //will hide 1st tab bar

      Thanks and Regards,
      Suresh Ariya

      Delete
  6. Thanks a lot
    Finally this code works for me.
    this.down(name_of_xtype).getTabBar().getComponent(3).hide()

    But instead of passing number, Can we pass the id of item to hide tab bar.

    ReplyDelete
  7. where do you put for this code
    onFormSave: function(button,e,options){

    var formObj = button.up('FormPanel');
    var formData = formObj.getValues();

    var usr = Ext.create('MyApp.model.User',{
    username: formData.username,
    password: formData.password,
    email:formData.email,
    website:formData.website,
    aboutyou: formData.aboutyou
    });

    var errs = usr.validate();
    var msg = '';

    if (!errs.isValid()) {
    errs.each(function (err) {
    msg += err.getField() + ' : ' + err.getMessage() + '
    ';
    });

    Ext.Msg.alert('ERROR', msg);

    } else {
    Ext.Msg.alert('SUCCESS', 'Looks like the Form is valid');
    }

    }

    ReplyDelete
    Replies
    1. Hi,

      You need to add this code next to config:{}, inside 'MyApp.view.FormPanel' view file.

      Thanks and Regards,
      Suresh Kumar Ariya

      Delete
  8. hi,

    where i write a code of validations?

    ReplyDelete

Related Posts Plugin for WordPress, Blogger...