Monday, April 18, 2011

JQuery-Plugin, Validators

Hey...

Here I'm going to describe a very useful jquery plugin for every enterprise applications. This is jquery validation plugin. I've extended this plugin and add some features to it. But the first, concept detail.

Concept Detail

A validation should prevent page from submitting if the client input values don't follow validation rules. It's a simple model of validation. But there are much more points which should be considered. A page may contains more than one action but only some of the rules should be performed for any actions. For example for a simple signup page have two methods to save entry. signup action and temporary save action. Some fields are required for signup but not for temporary save and so on.

The second point is, all validation rules are not just required rule. There are different kinds of rules. Some of them are here:
  • required
  • integer
  • decimal
  • gt
  • ge
  • lt
  • le
  • eq
  • email
  • number
  • maxLength
  • minLength
  • max
  • min
  • remote
  • custom
  • ...
Our validation method should support different kinds of validation rules.

The third point is, all validation should not be shown as an error. Some of them should be shown as a warning. A warning is not an incompatibility or at least does not make a fatal error. But client should be aware of it. For example for registration you should enter your email in correct format. But for temporary save it is not necessary. Because finally you should signup it and in signup email format validation prevents from signup if incompatibility exist.

The final point is custom message. The developer should be able to change the default message of validation and inject its own message for any incompatibility happens.

Validation Plugin Detail
General use of validation is like here:
$('#formId').validate({
rules:{inputname:{ruleName:ruleValue, ...},
...},
messages:{
'inputname':{ruleName:$.validator.format('This is custom message'),...},
...},
validationGroup:'validationGroup',
warningGroup:'warningGroup',
clickedButton:btnObject});
  • 'inputname' is your page input name
  • 'ruleName' is one of the supported rules: required, number, date, ....
  • 'ruleValue' depends on type of selected rule: required:true, max:20, date:true, minLength:50, between:[10,20], ... . It is simple value. But for grouping use, value can be a collection. Take a look here:
    'testinput':{required:{value:true, validationGroup:'signup', warningGroup:'tempSave'}}
    This collection has only three parts:
    • value: The value of the related rule
    • validationGroup:A simple text containing validation groups. More than one validation group is supported but should be separated with ','. For example: validationGroup:'signup,tempSave'
    • warningGroup: A simple text containing warning groups. More than one warning group is supported but should be separated with ','. For example: warningGroup:'signup,tempSave'
    If the value is simple(for example true or [10,20]) it means this rule should be checked in every actions of the page and grouping check is not needed.
  • messages is used for custom messages
  • validationGroup is used to validate the inputs which their rules validationGroup contains this validationGroup
  • warningGroup is used to validate the inputs which their rules warningGroup contains this warningGroup

Here are available rules for an input with name of "testinput":
'testinput':{range:[10,30]}
rule namesupported valuedescriptionexample
requiredtrue/flaseThe input should have value'testinput':{required:true}
between['#firstInputId',
'#secondInputId']
The input should have value be between 'firstInputId' value and 'secondInputId' value'testinput':{between:['#testinput1', '#testinput2']}
decimaltrue/flaseThe input should have decimal value'testinput':{decimal:true}
emailtrue/flaseThe input value should follow email format 'testinput':{email:true}
eq['#compareInputId', 'compareInputLabel']The input should equal to 'compareInputId' and if not, uses 'compareInputLabel' in error massage'testinput':{eq:['#testInput1', 'first name']}
ge['#compareInputId',
'compareInputLabel']
The input should greater equal to 'compareInputId' and if not, uses 'compareInputLabel' in error massage'testinput':{ge:['#testInput1', 'first name']}
gt['#compareInputId',
'compareInputLabel']
The input should greater than 'compareInputId' and if not, uses 'compareInputLabel' in error massage'testinput':{gt:['#testInput1', 'first name']}
integertrue/flaseThe input should have integer value'testinput':{integer:true}
le['#compareInputId',
'compareInputLabel']
The input should less equal to 'compareInputId' and if not, uses 'compareInputLabel' in error massage'testinput':{le:['#testInput1', 'first name']}
lt['#compareInputId',
'compareInputLabel']
The input should less than 'compareInputId' and if not, uses 'compareInputLabel' in error massage'testinput':{lt:['#testInput1', 'first name']}
maxlengthinteger numberThe input value length should be less than input integer number.'testinput':{maxlength:10}
maxinteger numberThe input value should be less than input integer number'testinput':{max:20}
minlengthinteger numberThe input value length should be more than input integer number.'testinput':{minlength:100}
mininteger numberThe input value should be more than input integer number'testinput':{min:80}
neq['#compareInputId', 'compareInputLabel']The input should not equal to 'compareInputId' and if not, uses 'compareInputLabel' in error massage'testinput':{neq:['#testInput1', 'first name']}
rangelength[integer number1,
integer number2]
The input value length should be between integer number1 and integer number 2'testinput':{rangelength:[10,30]}
range[integer number1,
integer number2]
The input value should be between integer number1 and integer number 2'testinput':{range:[10,30]}
custom---Custom validation doesn't follow the other validation methods. you should first write your own javascript function. The javascript function has three parameters: value,element, parameter. Then you should register your function in jquery validation this way: $.validator.addMethod('method name text', method name, jQuery.validator.format('error message'));
function customjavascript(value, element, parameter){
if(value == $('#input1').val()*10){
return true;
} else {
return false;
}
}
$.validator.addMethod('customjavascript',
customjavascript,
jQuery.validator.format('The input value should equal to input1 * 10'));
remote{url:'url string',
type:'get'or'post'
data:{
pname:pvalue
,...}}
Calls a server side method via ajax. It also posts parameters(pname=pvalue) with its call. We can use parameters in server side in request parameter object.
If server side method returns empty String, it means it passes the validator elsewhere It does not pass the validator and return string is the message which should be shown in client.
'testinput':{remote:{url:'home/remoteCheck.html',
type:'post',
data:{'input1':$('#input1').val(),
'input2':$('#input2').val()}}}
@RequestMapping(value = "/home/remoteCheck")
@ResponseBody
public String remoteCheck(HttpServletRequest request){
if(request.getParameter('input1') == request.getParameter('input2')){
return "input1 and input2 should be equal together"
}
return "";
}

Sample

You can download the sample from here. The needed js and css files are in that zipped file.
Sample Detail
It is a simple sign up form. You should enter some information in this form. The form has two actions:
  • signup: It is supposed that the input data is saved and accepted by the client.
  • tempSave: It is supposed that the input data is saved temporarily. But is not final accepted by the client.
Any actions has its own validation some of the validations are warning in any action mode.
For more information refer to the sample.
Sample Validation Method
A javascript function handles validation configuration.
function postFunc(validationGroupParam, warningGroupParam, btn) {
            var settings = $('#signupform').validate().settings;
            $.extend(settings, {
                rules:{
                    'fname':{required:true},
                    'lname':{required:true},
                    'email':{required:true, email:{value:true, validationGroup:'signup', warningGroup:'tempSave'}},
                    'sDate':{date:true, le:{value:['#eDate', 'end date'], validationGroup:'signup'}},
                    'eDate':{date:true, required:{value:true, validationGroup:'signup', warningGroup:'tempSave'}},
                    'age':{number:true, required:{value:true, validationGroup:'signup', warningGroup:'tempSave'}, min:{value:18, validationGroup:'signup'}}
                },
                messages:{'eDate':{required:$.validator.format('account end date is required...')}},
                validationGroup:validationGroupParam,
                warningGroup:warningGroupParam,
                clickedButton:btn
            });
        }
This method will be raised in buttons click:
<input type="submit" value="signup" name="signup" onclick="postFunc('signup', 'signup', this);"/>
<input type="submit" value="tempSave" name="tempSave" onclick="postFunc('tempSave', 'tempSave', this);"/>
Sample Internationalization
This plugin supports multy languages even in direction. For example in Persian language the direction is right to left. There are some alternative scripts to handle this:
   <script type="text/javascript" src="js/jquery-1.5.1.min.js"></script>
    <script type="text/javascript" src="js/jquery.validate.js"></script>
    <!--<script type="text/javascript" src="js/jquery.validate_fa.js"></script>-->
    <script type="text/javascript" src="js/additional-methods.js"></script>
    <script type="text/javascript" src="js/messages.js"></script>
    <!--<script type="text/javascript" src="js/messages_fa.js"></script>-->
    <script type="text/javascript" src="js/jquery.tooltip.js"></script>
    <script type="text/javascript" src="js/javascriptutil.js"></script>
    <link rel="stylesheet" href="css/screen.css">
    <!--<link rel="stylesheet" href="css/screen_fa.css">-->
js/jquery.validate_fa.js, js/messages_fa.js, css/screen_fa.css are alternative files of js/jquery.validate.js, js/messages.js, css/screen.css files. You can change them with each other to change the validation language.



all rights reserved by Mostafa Rastgar and Programmer Assistant weblog

No comments: