Form validation in Sencha Touch
Regarding form validation Sencha Touch is certainly not Ext JS. By default it doesn't have any validation mechanisms on forms. When searching for it on the internet, I have found a reasonable solution to overcome this. In this small article I will show how I have integrated this in my applications. I like to thank Suresh Kumar for the insight.
Validation by the use of models
A model has some powerful features to validate data. For form validation in Sencha Touch we are going to use a model to validate data. In the following example I have used some code of Suresh Kumar, but I hope it makes a complete picture.
Let's keep it simple. I have a mask field with pincode that has to be validated. The pincode is always 4 characters long. After Touch accepts valid data, its validity has to be checked on the server. The application is used on an intranet, so I have skipped in this sample any security measurements that would make it complex. This sample is for educational purposes.
Mobile.view.panel.Login
Ext.define('Mobile.view.panel.Login', {
extend: 'Ext.form.Panel',
alias: 'widget.LoginPanel',
requires: [
'Mobile.model.validation.Login'
],
config: {
padding: '20 10 10 10',
items: [
{
xtype: 'passwordfield',
minWidth: 4,
maxLength: 4,
label: 'Pincode',
name: 'pincode',
required: true,
width: 300
},
{
xtype: 'toolbar',
docked: 'top',
layout: {
type: 'hbox'
},
items: [
{
xtype: 'button',
docked: 'right',
text: 'Anmelden',
listeners: {
tap: function(button, e, eOpts) {
var me = button.up('LoginPanel');
me.ValidateLogin(button, e, eOpts);
}
}
}
]
}
]
},
ValidateLogin: function(button, e, options) {
var me = button.up('LoginPanel');
var formObj = me;
var formData = formObj.getValues();
var validation = Ext.create('LoginValidation', {
pincode: formData.pincode
});
var errs = validation.validate();
var msg = '';
if (!errs.isValid()) {
errs.each(function(err) {
msg += err.getField() + ' : ' + err.getMessage() + '';
});
Ext.Msg.alert('Fehler', msg);
} else {
me.fireEvent('LoginClicked', me);
}
}
});
In the class definition it says that Mobile.model.validation.Login is required. The name of this application is Mobile. I like to keep my model folder clean and therefor I added the validation folder inside the model folder.
The structure of the Mobile application is like this:
- Apps
- Mobile
- controller
- Mobile
- model
- validation
- Login
- more data models ...
- store
- view
- panel
- Login
Mobile.model.validation.Login
Ext.define('Mobile.model.validation.Login', {
extend: 'Ext.data.Model',
alias: 'LoginValidation',
config: {
fields: [
{
name: 'pincode'
}
],
validations: [
{
type: 'length',
field: 'pincode',
min: 4,
message: 'Pincode ist 4 Zeichen lang'
}]
}
});
In the validations array of your config object you can add all required rules. When you have more fields to validate in your form then you can add these in the fields array.
The controller event LoginClicked
When the validation is passed successfully the event LoginClicked is fired by the login panel. Now let's look at the event in the controller.
Ext.define('Mobile.controller.Mobile', {
extend: 'Ext.app.Controller',
views: [
'panel.Login'
],
config: {
refs: {
'LoginPanel': 'LoginPanel'
},
control: {
'LoginPanel': {
LoginClicked: 'onLoginClicked',
LoginSuccess: 'onLoginSuccess'
}
}
},
//------------------//
// Event Handlers
//------------------//
onLoginClicked: function(panel) {
var form = panel;
form.submit({
url: 'server_request/login',
params: {
.. some additional parameters here to post ..
},
success: function(form, result) {
.. do something here ..
panel.fireEvent('LoginSuccess', panel, result);
},
failure: function(form, result) {
Ext.Msg.alert('Fehler', result.message);
}
});
},
onLoginSuccess: function(panel, result) {
// mainPanel is a card layout panel with the login
// panel as first panel (0)
var mainPanel = me.getMainPanel();
mainPanel.setActiveItem(1);
}
});