mwin007
10/30/2015 - 10:53 AM

Form Validation, the Magento way…

Form Validation, the Magento way…

http://www.human-element.com/form-validation-the-magento-way/




Notice the

class="input-text required-entry"
that’s what prototype looks at to determine whether or not to validate the field. This can be taken further than just “is there stuff in the field?” (required-entry) to maybe something like “are there only numbers in the field?” or “are there only 5 numbers in the field?”

Now take a peek at the code for the email field in checkout

01
02
03
04
05
06
<div class="field">
    <label for="billing:email" class="required"><em>*</em>Email Address</label>
    <div class="input-box">
        <input type="email" autocapitalize="off" autocorrect="off" spellcheck="false" name="billing[email]" id="billing:email" value="" title="Email Address" class="input-text validate-email required-entry">
    </div>
</div>
Here there’s required-entry and also validate-email in the input field class. Starting to see a pattern yet?

Example 1
Let’s say we want to make the “Company” field in the billing section of checkout required. Easy, we just open up the template file and add the correct class name to the field in question.

/app/design/frontend/rwd/enterprise/template/persistent/checkout/onepage/billing.phtml
01
02
03
04
05
06
<div class="field">
    <label for="billing:company"><?php echo $this->__('Company') ?></label>
    <div class="input-box">
        <input type="text" id="billing:company" name="billing[company]" value="<?php echo $this->escapeHtml($this->getAddress()->getCompany()) ?>" title="<?php echo $this->__('Company') ?>" class="input-text required-entry" />
    </div>
</div>
you can find the company input field around line 49 and add the class

class="input-text required-entry"
Let’s test it. Try to continue to the next step and notice the “This is a required field” message under the company field now. Company is now a required field (yeah yeah, I know I didn’t add the red star! that’s just styling…)Company is now a required field

But wait there’s more! There’s a whole list of ready to use validation rules to choose from… You can find the methods yourself by looking in js/prototype/validation.js starting around line 414

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
'validate-no-html-tags'         => 'HTML tags are not allowed'
'validate-select'               => 'Please select an option.'
'required-entry'                => 'This is a required field.'
'validate-number'               => 'Please enter a valid number in this field.'
'validate-number-range'         => 'The value is not within the specified range.'
'validate-digits'               => 'Please use numbers only in this field. Please avoid spaces or other characters such as dots or commas.'
'validate-digits-range'         => 'The value is not within the specified range.'
'validate-alpha'                => 'Please use letters only (a-z or A-Z) in this field.'
'validate-code'                 => 'Please use only letters (a-z), numbers (0-9) or underscore(_) in this field, first character should be a letter.'
'validate-alphanum'             => 'Please use only letters (a-z or A-Z) or numbers (0-9) only in this field. No spaces or other characters are allowed.'
'validate-alphanum-with-spaces' => 'Please use only letters (a-z or A-Z), numbers (0-9) or spaces only in this field.'
'validate-street'               => 'Please use only letters (a-z or A-Z) or numbers (0-9) or spaces and # only in this field.'
'validate-phoneStrict'          => 'Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.'
'validate-phoneLax'             => 'Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.'
'validate-fax'                  => 'Please enter a valid fax number. For example (123) 456-7890 or 123-456-7890.'
'validate-date'                 => 'Please enter a valid date.'
'validate-date-range'           => 'The From Date value should be less than or equal to the To Date value.'
'validate-email'                => 'Please enter a valid email address. For example johndoe@domain.com.'
'validate-emailSender'          => 'Please use only visible characters and spaces.'
'validate-password'             => 'Please enter 6 or more characters. Leading or trailing spaces will be ignored.'
'validate-admin-password'       => 'Please enter 7 or more characters. Password should contain both numeric and alphabetic characters.'
'validate-both-passwords'       => 'Please make sure your passwords match.'
'validate-url'                  => 'Please enter a valid URL. Protocol is required (http://, https:// or ftp://)'
'validate-clean-url'            => 'Please enter a valid URL. For example http://www.example.com or www.example.com'
'validate-identifier'           => 'Please enter a valid URL Key. For example &quot;example-page&quot;, &quot;example-page.html&quot; or &quot;anotherlevel/example-page&quot;.'
'validate-xml-identifier'       => 'Please enter a valid XML-identifier. For example something_1, block5, id-4.'
'validate-ssn'                  => 'Please enter a valid social security number. For example 123-45-6789.'
'validate-zip'                  => 'Please enter a valid zip code. For example 90602 or 90602-1234.'
'validate-zip-international'    => 'Please enter a valid zip code.'
'validate-date-au'              => 'Please use this date format: dd/mm/yyyy. For example 17/03/2006 for the 17th of March, 2006.'
'validate-currency-dollar'      => 'Please enter a valid $ amount. For example $100.00.'
'validate-one-required'         => 'Please select one of the above options.'
'validate-one-required-by-name' => 'Please select one of the options.'
'validate-not-negative-number'  => 'Please enter a number 0 or greater in this field.'
'validate-zero-or-greater'      => 'Please enter a number 0 or greater in this field.'
'validate-greater-than-zero'    => 'Please enter a number greater than 0 in this field.'
'validate-state'                => 'Please select State/Province.'
'validate-new-password'         => 'Please enter 6 or more characters. Leading or trailing spaces will be ignored.'
'validate-cc-number'            => 'Please enter a valid credit card number.'
'validate-cc-type'              => 'Credit card number does not match credit card type.'
'validate-cc-type-select'       => 'Card type does not match credit card number.'
'validate-cc-exp'               => 'Incorrect credit card expiration date.'
'validate-cc-cvn'               => 'Please enter a valid credit card verification number.'
'validate-ajax'                 => ''
'validate-data'                 => 'Please use only letters (a-z or A-Z), numbers (0-9) or underscore(_) in this field, first character should be a letter.'
'validate-css-length'           => 'Please input a valid CSS-length. For example 100px or 77pt or 20em or .5ex or 50%.'
'validate-length'               => 'Text length does not satisfy specified text range.'
'validate-percents'             => 'Please enter a number lower than 100.'
'validate-cc-ukss'              => 'Please enter issue number or start date for switch/solo card type.'
Easy right? Yep, but wait that’s not all, what if you wanna validate based on some other set of conditions not in the list?

Example B
Sticking with our checkout example, let’s say we want to add a validation rule that prevents PO Box addresses in checkout. First, open up billing.phtml again and find the address fields (there are two of them starting around line 61). Next, add the class name we’re gonna use on the input fields.. we’ll call this one validate-for-pobox

/app/design/frontend/rwd/enterprise/template/persistent/checkout/onepage/billing.phtml
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<?php $_streetValidationClass = $this->helper('customer/address')->getAttributeValidationClass('street'); ?>
        <li class="wide">
            <label for="billing:street1" class="required"><em>*</em><?php echo $this->__('Address') ?></label>
            <div class="input-box">
                <input type="text" title="<?php echo $this->__('Street Address') ?>" name="billing[street][]" id="billing:street1" value="<?php echo $this->escapeHtml($this->getAddress()->getStreet(1)) ?>" class="input-text validate-for-pobox <?php echo $_streetValidationClass ?>" />
            </div>
        </li>
<?php $_streetValidationClass = trim(str_replace('required-entry', '', $_streetValidationClass)); ?>
<?php for ($_i = 2, $_n = $this->helper('customer/address')->getStreetLines(); $_i <= $_n; $_i++): ?>
        <li class="wide">
            <label for="billing:street<?php echo $_i ?>"><?php echo $this->__('Street Address %s', $_i) ?></label>
            <div class="input-box">
                <input type="text" title="<?php echo $this->__('Street Address %s', $_i) ?>" name="billing[street][]" id="billing:street<?php echo $_i ?>" value="<?php echo $this->escapeHtml($this->getAddress()->getStreet($_i)) ?>" class="input-text validate-for-pobox <?php echo $_streetValidationClass ?>" />
            </div>
        </li>
<?php endfor; ?>
All we have to do now is add a new validation rule in JS for this class name, kinda like the ones in validation js. We’ll write ours right here in billing.phtml. Down on line 220… you’ll see

var billingForm = new VarienForm('co-billing-form');
remember that time, way back at the beginning of this post, when you read some stuff about passing the form id to VarienForm object?

below it, add

01
02
03
04
05
06
07
08
09
Validation.add('validate-for-pobox','ERROR MESSAGE',function(field_value) {
    // setup a regex var for pretty much every possibility of PO box...
    var regex = /[P|p]*(OST|ost)*\.*\s*[O|o|0]*(ffice|FFICE)*\.*\s*[B|b][O|o|0][X|x]/;
    // if the field_value contains PO Box
    if(field_value.match(regex)){
        return false;
    }
    return true;
});
Now try a test in checkout and behold
Screen_Shot_2014-11-04_at_15_42_14

What just happened?
 Validation.add('validate-for-pobox','ERROR MESSAGE',function(field_value) { amazing code here }); 
validate-for-pobox — the class name we want to use to kick off validation on input fields
ERROR MESSAGE — the error message , duh! (it’ll display below the field in red…)
field_value — the value the user types into the field.

That’s pretty much it. Time to validate stuff…