Tutorial Part 1 • Part 2 • Part 3 • Part 4 • Live demo
How to use Mootools Formvalidator effectively – a tutorial in 4 parts
This additional part contains stuff that didn’t fit in the previous parts and things I’ve been asked (or asked myself) afterwards.
Optional minimum length
Imagine something like this: A user can enter her postcode (which by any weird definition has to contain at least 5 characters) but isn’t required to. So the field can either be empty or – if it’s filled – it has to contain 5 or more characters.
A custom validator could look like this:
FormValidator.add('optionalMinLength', {
errorMsg: function(element, props) {
return 'Leave this empty or enter at least ' + props.optionalMinLength + ' chars';
},
test: function(element,props) {
if (element.value.length > 0 && element.value.length < props.optionalMinLength) {
return false;
}
return true;
}
});
Usage:
<input type="text" name="postcode" class="optionalMinLength:5" />
How does it work? The test function is similar to the ones before: First we check if our element has a length of at least one - if so (something is filled in) we compare it to our property (here: optionalMinLength). And if the element is too short, the test fails.
One thing to notice here is the error message - instead of using a simple text we can apply the same arguments to the function as we use for the test method: The element and properties. So we can print our error message dynamically by inserting the number of required characters.
Shipping Address Example
Depending on a user selection, some fields might change their required-status. A common example would be a shopping cart where you select Ship to another address
- in this case the shipping address fields would become required.
This works out-ouf-the-box if you include the Form.Validator.Extras-package. Here's an example:
<label for="shipping">Ship to a different address?</label>
<input type="checkbox" class="validate-toggle-oncheck toToggleChildrenOf:'shippingfields'" id="shipping" name="profile[shipping]" />
<div id="shippingfields">
<label for="ship_street">Shipping address</label>
<input type="text" class="required" id="ship_street" name="profile[ship_street]" />
<label for="ship_city">Shipping city</label>
<input type="text" class="required" id="ship_city" name="profile[ship_city]" />
</div>
The validate-toggle-oncheck validator toggles all the fields which are children of the ID you provide. In this case we simply added a DIV with the ID "shippingfields" and put all the fields which depend on this checkbox insde.
So if the checkbox is not selected, the shipping address-fields are ignored - otherwise they are validated.
You can also provide a list of fields to toggle:
<input type="checkbox" class="validate-toggle-oncheck toToggle:['ship_street','ship_city']" id="shipping" name="profile[shipping]" />
Shipping address improved
The previous example has one small disadvantage when it comes to usability: If you'd like to mark required fields with a *
you can't put the asterisk on the shipping address fields, since that depends. But we can improve the general usability by simple toggling their visibility:
<label for="shipping">Ship to a different address?</label>
<input type="checkbox" onclick="$('shippingfields').toggleClass('hidden')" class="validate-toggle-oncheck toToggleChildrenOf:'shippingfields'" id="shipping" name="profile[shipping]" >
<div id="shippingfields">
<label for="ship_street">Shipping address</label>
<input type="text" class="required" id="ship_street" name="profile[ship_street]" />
<label for="ship_city">Shipping city</label>
<input type="text" class="required" id="ship_city" name="profile[ship_city]" />
</div>
The CSS-class hidden is defined as display:none
More to follow....
Hi! Thanks for the tutorial. I have an issue with email validation. Perhaps you have an idea for a fix or workaround: Perfectly valid adresses such as (abc)def@ghi.com are not validated correctly.
You can use a custom validator and check your email-address with a regex, that is the most easy solution.
very very useful! Thanks for your contribute! :)
Nice to hear that, thx!
Is there any way to specify a minLength IF the field is filled in?
Eg. I want an optional field, but if something’s entered there, it should be at least 5 characters.
Interesting – that should of course be possible with a small custom validator. Have a look at part #4 now.
Yeah. As an example of how to write your own validators it’s great stuff. All 3 tutorials are really informative. Keep it up.
This is great stuff, but I have one comment. Form.Validator validates inputs both on change and on submit, which means that the user is going to submit the form and you’ll have this synchronous hit to the server followed immediately by another hit (the form actually being submitted). If you wanted to avoid this you would have to do some extra leg work that I won’t try and cram into this comment. I think it’s actually a better solution to write this code on its own and not use Form.Validator for this particular use case. Add a change event to the username input and do your check, showing a hint when the name is taken, but don’t prevent submitting the form or anything. Let the back end handle that collision as normal.
The complexity of this pattern is the reason Form.Validator doesn’t ship with a built-in validator for this problem…
Thanks for the comment.
You’re right: The solution is not optimal when it comes to server load (of course depending on traffic, database implementation and so on).
Same as the non-asynchronous request this is more a “and-this-can-also-be-done-tutorial” than a “best-practice-for-all-cases-tutorial” :)
Are single quote characters valid for class attributes?
ex. class=”matchInput:’password'”
I know that : and . are technically allowed in ‘id’ attributes according to the w3c but still don’t behave well across all browsers so best to avoid.
I’m not sure of the validation rules for ‘class’ but it seems strange that a single quote would be a valid value.
Good point. The W3C validator and HTML tidy at least do not complain.. I assume if the CSS-classes are listed first, it won’t make problems.
The mootools-documentation states it’s valid XHTML:
http://mootools.net/docs/more/Forms/Form.Validator#Form-Validator – see “Notes”
Additionally, the class is called FormValidator not Form.Validator
My bad, you might want to mention what version of mootools-more you are using. Aaron changed it from 1.2.3 to 1.2.4 to use the dot.
You are missing a }); after the myFormValidator argument list in your first code snippit…
Thanks! Fixed it (and added the version number).