Magento – Javascript validation for international char-sets

formsjavascriptvalidation

I have a several store views for different languages and we're having some trouble with the new customer sign up forms. We have added the character set init statement for our database as follows:

        <default_setup>
            <connection>
                <host><![CDATA[127.0.0.1]]></host>
                <username><![CDATA[root]]></username>
                <password><![CDATA[pass]]></password>
                <dbname><![CDATA[mage]]></dbname>

                <!-- important for international char-sets -->
                <initStatements><![CDATA[SET NAMES utf8]]></initStatements>

                <model><![CDATA[mysql4]]></model>
                <type><![CDATA[pdo_mysql]]></type>
                <pdoType><![CDATA[]]></pdoType>
                <active>1</active>
            </connection>
        </default_setup>

And almost everything has worked flawlessly until today. We discovered that when a new customer tries to signup from the front end using special chars in their name the javascript validation does not allow them to proceed. The validate-alpha class only appears to expect standard a-zA-Z characters and marks anything else as invalid. If we remove the class everything works great, but of course we do want to maintain some sort of validation on the field. I'm kind of surprised this has been overlooked by the Magento team.

The obvious solution seems to be to modify the validation class to also accept international characters (it doesn't look like the default library includes a method for this), but I'm curious if I'm overlooking something else that is built into the validation library.

Best Answer

You either need to define a new validation type with the correct regex to match the Unicode characters or customize the existing validation type. I believe that you will need to use an expression like p{L} instead of a-zA-Z; more info can be found at http://www.regular-expressions.info/unicode.html#prop.

To tell you how to accomplish the customization I had to go way back (literally, to archive.org's WayBack Machine capture of the support page for the class) to remind myself about extensible changes to the validation.js class:

To add your own validator do this:

Validation.add('class-name', 'Error message text', function(value [, element]) {
     return /* do validation here */ 
}, options);

or this:

Validation.add('class-name', 'Error message text', options);

The first example above includes a function as the third argument. The function enables you to write your own custom validation. The options argument is optional. The second example the third argument has become the options argument. Validator options can be used to perform common validation options without the need to write them into a function. Multiple options can be combined to create a complex validator and they can also enhance your custom validation function. Here are the available options and example usage below:

Validation.add('class-name', 'Error message text', {
     pattern : new RegExp("^[a-zA-Z]+$","gi"), // only letter allowed
     minLength : 6, // value must be at least 6 characters
     maxLength : 13, // value must be no longer than 13 characters
     min : 5, // value is not less than this number
     max : 100, // value is not more than this number
     notOneOf : ['password', 'PASSWORD'], // value does not equal anything in this array
     oneOf : ['fish','chicken','beef'], // value must equal one of the values in this array
     is :  '5', // value is equal to this string
     isNot : 'turnip', //value is not equal to this string
     equalToField : 'password', // value is equal to the form element with this ID
     notEqualToField : 'username', // value is not equal to the form element with this ID
     include : ['validate-alphanum'] // also tests each validator included in this array of validator keys (there are no sanity checks so beware infinite loops!)
});

Of particular note for your needs:

For example here's one of the in-built ones:

Validation.add('validate-alpha', 'Please use letters only (a-z) in this field.', function (v) {
     return Validation.get('IsEmpty').test(v) ||  /^[a-zA-Z]+$/.test(v)
});
Related Topic