Ajax Validation in Magento
Andriy Zhuk Avatar

I am a beginner Magento developer and recently I have received an interesting task where I had to create a custom address attribute for the customers and add a field with this to the customer’s edit address page and Magento one page checkout. Moreover, the information inserted in that field should be automatically compared with the existing values to avoid the repeating, without page reloading.

When I have started working on this task, it was hard to find some concrete information with the solutions on the Internet. So, I decided to share my experience on how to validate the input with Ajax.

For the example, we create a module that will be checking the emails field using Ajax on the customer registration page. In this module, we will use own controller, helper and rewrite the registration page.

First of all, we should activate the module, which we will be working with. Let’s name it, for instance, Atwix_EmailAjax. And to do it just create a declaration file by the following path:

app/etc/modules/Atwix_EmailAjax.xml

<?xml version="1.0" ?>

<config>
    <modules>
        <Atwix_EmailAjax>
            <active>true</active>
            <codePool>local</codePool>
        </Atwix_EmailAjax>
    </modules>
</config>

Next, we will create a module folder and configure our module. The configuration files should be inside our module in a directory named “etc” – so, let’s make that alongside with a new XML file:

app/code/local/Atwix/EmailAjax/etc/config.xml

<?xml version="1.0" ?>

<config>
    <modules>
        <Atwix_EmailAjax>
            <version>0.1.0</version>
        </Atwix_EmailAjax>
    </modules>
    <global>
        <helpers>
            <atwix_emailajax>
                <class>Atwix_EmailAjax_Helper</class>
            </atwix_emailajax>
        </helpers>
    </global>
    <frontend>
        <layout>
            <updates>
                <atwix_emailajax>
                    <file>atwix_emailajax.xml</file>
                </atwix_emailajax>
            </updates>
        </layout>
        <routers>
            <atwix_emailajax>
                <use>standard</use>
                <args>
                    <module>Atwix_EmailAjax</module>
                    <frontName>emailajax</frontName>
                </args>
            </atwix_emailajax>
        </routers>
    </frontend>
</config>

After that, we should create a helper and controller. Inside the helper we will write a function that will be checking whether any other customer has the same email as the one added to the field. Inside the controller we will call this function:

app/code/local/Atwix/EmailAjax/Helper/Data.php

<?php
class Atwix_EmailAjax_Helper_Data extends Mage_Core_Helper_Data

{

       /**
     * Check if customer email already exists
     *
     * @param $emailAddress
     * @return string
     * @throws Mage_Core_Exception
     */

    public function checkEmailExists($emailAddress)
    {
        $emailAddressCheck = Mage::getModel('customer/customer')
            ->getCollection()
            ->addAttributeToSelect('email')
            ->addAttributeToFilter('email', $emailAddress)->load();

        if(!$emailAddressCheck->getSize()) {
            $result = 'ok';
        } else {
            $result = 'error';
        }

        return $result;
    }


}

app/code/local/Atwix/EmailAjax/controllers/AddressController.php

<?php
class Atwix_EmailAjax_AddressController extends Mage_Core_Controller_Front_Action
{

    /**
     * Check if customer email already exists
     *
     */

    public function checkEmailExistsAction()
    {
        $emailAddress = $this->getRequest()->getParam('emailAddress');

        $result = Mage::helper('atwix_emailajax')->checkEmailExists($emailAddress);

        $this->getResponse()->setBody($result);
    }

}

On the next stage, we will make a layout file for our module and rewrite a template of the registration page in this layout.

app/design/frontend/rwd/default/layout/atwix_emailajax.xml

<layout>
    <customer_account_create>
        <reference name='customer_form_register'>
            <action method='setTemplate'>
                <template>atwix_emailajax/customer/form/register.phtml</template>
            </action>
        </reference>
    </customer_account_create>
</layout>

Also, let’s create a template file and there we will copy the code from the template of the needed page.

app/design/frontend/rwd/default/template/atwix_emailajax/customer/form/register.phtml

After that, we can move forward in two ways. Here is the first one:

1. We need to create a file with JavaScript code in this folder:

skin/frontend/rwd/default/js/checkemailexists.js

It should be done especially if you want to make this validation on two and more pages. In this case, it will be better to use the same code for several times and change it (if needed) just for one place which is very convenient.

Moreover, this code should be included into the layout to add JS file to the template:

<reference name='head'>
            <action method="addItem">
                <type>skin_js</type>
                <name>js/checkemailexists.js</name>
                <params/>
                <if/>
            </action>
        </reference>

Furthermore, if our code is in the separate file, we should run a PHP code (for instance – get the controller URL).
We can make an invisible SPAN with the PHP code inside.

<span id="check_email_address_exists" style="display: none"><?php echo Mage::getUrl('emailajax/address/checkemailexists');?></span>

2. Alternatively, if you plan to add this validate only on a single page, it is enough to add this code at the end of the template file:

 jQuery(function() {
        var emailAddress = jQuery('#email_address');
        emailAddress.on("change", function () {
            var url = jQuery('#check_email_address_exists').text(); // Get value from our not visible span with PHP code
            var emailAddressValue = jQuery(this).val(); // Get value from an email field
            jQuery.ajax({
                type: "POST",
                data: ({emailAddress: emailAddressValue}),
                url: url,
                success: function (result) {
                    if (result == 'ok') { // Do this if an email not exists
                        emailAddress.removeClass('validation-failed');
                        jQuery('#advice-required-entry-email_address').remove(); // Remove an error message
                        jQuery('.buttons-set .button').removeAttr("disabled"); // Enable Register button
                    } else if (result == 'error') { // Do this if an email is already exists
                        var errorHtml = '<div class="validation-advice" id="advice-required-entry-email_address">There is already a customer with this email address.</div>';
                        emailAddress.addClass('validation-failed');
                        if (!jQuery('#advice-required-entry-email_address').length) {
                            emailAddress.after(errorHtml); // Add an error message if it is not present
                        }
                        jQuery('.buttons-set .button').attr("disabled", "disabled"); // Disable Register button
                    }
                }
            });
        });
    });

On the frontend, it will look like this:

Create_new _customer_account

It was my way of solving this issue. However, I would like to know whether there are any alternative solutions – you are welcome to add your suggestions or any questions in the comments below.

Thank you for the time spent on reading us!