Actions

Difference between revisions of "Client-side form validation"

From Joomla! Documentation

(Major update of the page)
(7 intermediate revisions by 5 users not shown)
Line 1: Line 1:
[[Category:Development]]
 
 
==Introduction==
 
==Introduction==
Joomla 1.5 contains a behavior '''JHTMLBehavior::formvalidation()''' which enables the script '''validate.js'''.
 
It uses '''mootools''' and allows your form and its elements to be validated. 
 
  
'''Note:''' For more recent versions of Joomla (1.5.2) use '''JHTML::_('behavior.formvalidation')''' instead of '''JHTMLBehavior::formvalidation()'''
+
Joomla 1.5 and later versions contain a behavior, which allows your form and its elements to be validated at client side, i.e., before it is submitted to the server. The behavior enables the script '''validate.js''' and uses [http://mootools.net MooTools].
 +
 
 +
Note: Validate.js is a validation system different from the one provided by [http://mootools.net/docs/more/Forms/Form.Validator MooTools].
  
 
==Enable the Validation==
 
==Enable the Validation==
The only thing you have to do is set the '''classes''' of the form and elements to the specified meanings.
+
 
Classes:
+
Add a behavior to your form view template. For Joomla versions before 1.5.2:
===Form===
+
<source lang="php">
* form-validate -> enable validation
+
JHTMLBehavior::formvalidation();
===Form elements===
+
</source>
 +
For versions from 1.5.2:
 +
<source lang="php">
 +
JHTML::_('behavior.formvalidation');
 +
</source>
 +
 
 +
Add the form-validate class to your form
 +
<source lang="html4strict">
 +
<form class="form-validate"> ... </form>
 +
</source>
 +
 
 +
Add a validation class to your form field declarations. Joomla adds a ''blur'' handler to validate the form field when the user moves away from the field.
 +
<source lang="xml">
 +
<field name="email" type="text"
 +
    class="required validate-email"
 +
    size="30" />
 +
</source>
 +
 
 +
The following classes are available:
 
* required
 
* required
 
* validate-username
 
* validate-username
Line 17: Line 34:
 
* validate-numeric
 
* validate-numeric
 
* validate-email
 
* validate-email
* validate-[custom] -> custom handlers have to be set then!
+
* validate-[custom] -> custom defined - see below
 +
 
 +
Note: Joomla 2.5 translates the ''required'' field attribute into a ''required'' class value.
 +
 
 +
Finally, add the ''validate'' class to your submit button. This will cause an ''onclick'' handler to be added that validates the whole form. The form will only be submitted if it is valid.
 +
<source lang="html4strict">
 +
<button type="submit" class="validate">Submit form</button>
 +
</source>
 +
 
 +
==Custom Handlers==
 +
 
 +
If you want a custom handler, you can add one to the class, as in the following example (to be defined AFTER loading validate.js):
 +
<source lang="javascript">
 +
window.addEvent('domready', function(){
 +
  document.formvalidator.setHandler('birth', function(value) {
 +
      regex=/^\d{4}-\d{2}-\d{2}$/;
 +
      return regex.test(value);
 +
  });
 +
});
 +
</source>
 +
You can then assign validate-birth to any field to make it validate as yyyy-mm-dd.  (Valid date is not checked!)
 +
 
 +
If you want a custom handler to check both the passwords (Password and Confirm Password) are same, please add the following script after the validate.js:
 +
<source lang="javascript">
 +
window.addEvent('domready', function(){
 +
    document.formvalidator.setHandler('passverify', function (value) {
 +
        return ($('password').value == value);
 +
    });
 +
});
 +
</source>
 +
Add the class "validate-passverify" to the input field as below:
 +
<source lang="html4strict"><input class="inputbox required validate-passverify" type="password" id="password2" name="password2" size="40" value="" />
 +
</source>
 +
 
 
==Style Invalid Elements==
 
==Style Invalid Elements==
If some elements don't validate they will get the class
+
 
* invalid
+
Joomla assigns the ''invalid'' class to form fields that do not pass the validation test. ''invalid'' is also added to the field labels.
 
If you style the class in the cascading style sheet, your users will be able to see which fields are wrong. For instance:
 
If you style the class in the cascading style sheet, your users will be able to see which fields are wrong. For instance:
 
<source lang="css">
 
<source lang="css">
.invalid {color:red;}
+
.invalid {
 +
    border-color: red !important;
 +
}
 
</source>
 
</source>
==Only Accept the Form After Validation==
+
Some site templates may already contain such definition. (This one is taken from ''beez_20''.)
If you don't want the form to submit anything unless the values are validated, here's a nice script:
+
<source lang="php">
+
<?php JHTMLBehavior::formvalidation(); ?>
+
<script language="javascript">
+
function myValidate(f) {
+
  if (document.formvalidator.isValid(f)) {
+
      f.check.value='<?php echo JUtility::getToken(); ?>'; //send token
+
      return true;
+
  }
+
  else {
+
      var msg = 'Some values are not acceptable. Please retry.';
+
  
      //Example on how to test specific fields
 
      if($('email').hasClass('invalid')){msg += '\n\n\t* Invalid E-Mail Address';}
 
  
      alert(msg);
+
<!-- ==Only Accept the Form After Validation==
  }
+
    This section is not necessary, if it works at all. See validate class on submit buttons.
  return false;
+
-->
}
+
</script>
+
<form id="WV-form" method="post" class="form-validate" onSubmit="return myValidate(this);">
+
<input type="hidden" name="check" value="post"/>
+
...
+
<input type="text" name="email" id="email" size="30"  class="required validate-email"/>
+
...
+
<input type="submit" value="Submit" />
+
</form></source>
+
  
The page that receives the value can check several things:
 
<source lang="php">
 
  
defined( '_JEXEC' ) or die( 'Restricted access' );  //Verify Joomla enabled
+
==Work Around when Using with JToolBar==
$jAp=& JFactory::getApplication();
+
If you are using JHTML::_('behavior.formvalidation') with JToolBar, for example use in backend, the above method will not work. This is because it depends on onSubmit event which did not fire when we call form.submit via JavaScript. To work around this, we have to move the code in onSubmit to be in submitbutton function override. This will look like this:-
if ($_POST['check']!=JUtility::getToken()) {
+
<source lang="javascript">
  // First verify (by a Javascript error or other methods) that the form has not been submitted without the validation
+
<script type="text/javascript">
  if ($_POST['check']=='post') $jAp->enqueueMessage('Please check all the fields of the form, aub.<br/>
+
/* Override joomla.javascript, as form-validation not work with ToolBar */
If your browser blocks Javascript, then this form will never be successful. This is a security measure.','error');
+
function submitbutton(pressbutton) {
  // If the check still isn't a valid token, do nothing. This might be a spoof attack or other invalid form submission
+
    if (pressbutton == 'cancel') {
   return false;
+
        submitform(pressbutton);
 +
    }else{
 +
        var f = document.adminForm;
 +
        if (document.formvalidator.isValid(f)) {
 +
            f.check.value='<?php echo JUtility::getToken(); ?>'; //send token
 +
            submitform(pressbutton);   
 +
        }
 +
        else {
 +
            var msg = new Array();
 +
            msg.push('Invalid input, please verify again!');
 +
            if ($('title').hasClass('invalid')) {
 +
                msg.push('<?php echo JText::_('COM_JONGMAN_ERROR_SCHEDULE_TITLE_IS_REQUIRED')?>');   
 +
            }
 +
            if($('admin_email').hasClass('invalid')){
 +
                msg.push('<?php echo JText::_('COM_JONGMAN_ERROR_INVALID_EMAIL')?>');
 +
            }
 +
            alert (msg.join('\n'));
 +
        }
 +
    }    
 
}
 
}
 +
</script>
 
</source>
 
</source>
==Custom Handlers==
+
<noinclude>[[Category:Tutorials]][[Category:Development]][[Category:Component Development]]</noinclude>
If you want a custom handler, you can add one to the class, as in the following example (defined AFTER the validate.js):
+
<source lang="php">Window.onDomReady(function() {
+
  document.formvalidator.setHandler('birth', function(value) {
+
      regex=/^\d{4}(-\d{2}){2}$/;
+
      return regex.test(value);
+
  })
+
})
+
</source>
+
You can then set any class to validate-birth to make it validate as yyyy-mm-dd.  (Valid date is not checked!)
+

Revision as of 14:28, 24 November 2012

Contents

Introduction

Joomla 1.5 and later versions contain a behavior, which allows your form and its elements to be validated at client side, i.e., before it is submitted to the server. The behavior enables the script validate.js and uses MooTools.

Note: Validate.js is a validation system different from the one provided by MooTools.

Enable the Validation

Add a behavior to your form view template. For Joomla versions before 1.5.2:

JHTMLBehavior::formvalidation();

For versions from 1.5.2:

JHTML::_('behavior.formvalidation');

Add the form-validate class to your form

<form class="form-validate"> ... </form>

Add a validation class to your form field declarations. Joomla adds a blur handler to validate the form field when the user moves away from the field.

<field name="email" type="text"
    class="required validate-email"
    size="30" />

The following classes are available:

  • required
  • validate-username
  • validate-password
  • validate-numeric
  • validate-email
  • validate-[custom] -> custom defined - see below

Note: Joomla 2.5 translates the required field attribute into a required class value.

Finally, add the validate class to your submit button. This will cause an onclick handler to be added that validates the whole form. The form will only be submitted if it is valid.

<button type="submit" class="validate">Submit form</button>

Custom Handlers

If you want a custom handler, you can add one to the class, as in the following example (to be defined AFTER loading validate.js):

window.addEvent('domready', function(){
   document.formvalidator.setHandler('birth', function(value) {
      regex=/^\d{4}-\d{2}-\d{2}$/;
      return regex.test(value);
   });
});

You can then assign validate-birth to any field to make it validate as yyyy-mm-dd. (Valid date is not checked!)

If you want a custom handler to check both the passwords (Password and Confirm Password) are same, please add the following script after the validate.js:

window.addEvent('domready', function(){
    document.formvalidator.setHandler('passverify', function (value) {
        return ($('password').value == value); 
    });
});

Add the class "validate-passverify" to the input field as below:

<input class="inputbox required validate-passverify" type="password" id="password2" name="password2" size="40" value="" />

Style Invalid Elements

Joomla assigns the invalid class to form fields that do not pass the validation test. invalid is also added to the field labels. If you style the class in the cascading style sheet, your users will be able to see which fields are wrong. For instance:

.invalid {
    border-color: red !important;
}

Some site templates may already contain such definition. (This one is taken from beez_20.)



Work Around when Using with JToolBar

If you are using JHTML::_('behavior.formvalidation') with JToolBar, for example use in backend, the above method will not work. This is because it depends on onSubmit event which did not fire when we call form.submit via JavaScript. To work around this, we have to move the code in onSubmit to be in submitbutton function override. This will look like this:-

<script type="text/javascript">
/* Override joomla.javascript, as form-validation not work with ToolBar */
function submitbutton(pressbutton) {
    if (pressbutton == 'cancel') {
        submitform(pressbutton);
    }else{
        var f = document.adminForm;
        if (document.formvalidator.isValid(f)) {
            f.check.value='<?php echo JUtility::getToken(); ?>'; //send token
            submitform(pressbutton);    
        }
        else {
            var msg = new Array();
            msg.push('Invalid input, please verify again!');
            if ($('title').hasClass('invalid')) {
                msg.push('<?php echo JText::_('COM_JONGMAN_ERROR_SCHEDULE_TITLE_IS_REQUIRED')?>');    
            }
            if($('admin_email').hasClass('invalid')){
                msg.push('<?php echo JText::_('COM_JONGMAN_ERROR_INVALID_EMAIL')?>');
            }
            alert (msg.join('\n'));
        }
    }    
}
</script>