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.
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.