validationmagento2jquery-widgetsmagento2.2

Magento 2 how to validate customer registration form on keyup event


I am working on a project where I need to validate customer registration form as customer types. I want to use the event keyup for inputs. I want to change the default messages also. Right now I am doing validation like below

$("#firstname").keyup(function(){
    $('input[name="firstname"]').validation();
    if(!$('input[name="firstname"]').validation('isValid')){
        $("#firstname-error").remove();
        $("#firstname").after('<div for="firstname" generated="true" class="mage-error" id="firstname-error">Please enter your firstname</div>');
    }else{
        $("#firstname-error").remove();
    }
});

Not a good way of doing that I think. But I will need to do this for all fields.Then I was looking at this file vendor\magento\magento2-base\lib\web\mage\validation.js at around line no 1735 I saw below code

$.widget('mage.validation', {
        options: {
            meta: 'validate',
            onfocusout: false,
            onkeyup: false,
            onclick: false,
            ignoreTitle: true,
            errorClass: 'mage-error',
            errorElement: 'div',
    ...

Seeing this I thought maybe there is a better way to do this. So if there is any simple way please let me know.


Solution

  • After some digging, I came up with this solution. For the solution, all you need to do is add new js using requirejs-config.js. But I created a new module. Module files are as below.

    app\code\Vky\Core\registration.php

    <?php
    
    \Magento\Framework\Component\ComponentRegistrar::register(
        \Magento\Framework\Component\ComponentRegistrar::MODULE,
        'Vky_Core',
        __DIR__
    );
    

    app\code\Vky\Core\etc\module.xml

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
        <module name="Vky_Core" setup_version="0.0.1"/>
    </config>
    

    app\code\Vky\Core\view\frontend\requirejs-config.js

    var config = {
        map: {
            '*': {
                vky_customjs:      'Vky_Core/js/vky_custom'
            }
        }
    };
    

    app\code\Vky\Core\view\frontend\web\js\vky_custom.js

    define([
        "jquery",
        "jquery/ui",
        'mage/validation'
    ], function($) {
        "use strict";
        console.log('vky_custom.js is loaded!!');
            //creating jquery widget
            $.widget('vky_custom.js', {
                _create: function() {
                    this._bind();
                },
    
                /**
                 * Event binding, will monitor change, keyup and paste events.
                 * @private
                 */
                _bind: function () {
                    this._on(this.element, {
                        'change': this.validateField,
                        'keyup': this.validateField,
                        'paste': this.validateField,
                        'click': this.validateField,
                        'focusout': this.validateField,
                        'focusin': this.validateField,
                    });
                },
    
                validateField: function () {
                    $.validator.validateSingleElement(this.element);
                },
    
            });
    
        return $.vky_custom.js;
    });
    

    Now, wherever your register.phtml file is open it. Add few things as below. At the end of the file add this

    <script type="text/x-magento-init">
        { ".v-validate": { "Vky_Core/js/vky_custom": {} } }
    </script>
    

    And then, for example, you want to validate email. Find input tag for email and add class v-validate. Like this

    <input type="email" name="email" autocomplete="email" id="email_address" value="<?= $block->escapeHtmlAttr($block->getFormData()->getEmail()) ?>" title="<?= $block->escapeHtmlAttr(__('Email')) ?>" class="input-text v-validate" data-validate="{required:true, 'validate-email':true}">
    

    So any input with class v-validate will be validated on events like keyup, change, click, focusout, etc. I added a class to all input tags.

    For firstname and lastname in register.phtml above this line var dataForm = $('#form-validate'); I added

    $('#firstname').addClass('v-validate');
    $('#lastname').addClass('v-validate');
    

    That's all I did to solve my problem. And It works. That's why posting my answer. May be this can help someone.