Trying to validate the form using the jquery-validate plugin:

// Callback forms (function(){ var app = { init: function(){ this.setUpListeners(); }, setUpListeners: function(){ $(document).on('submit', 'form', this.submitForm); $(document).on('keyup', 'input', this.removeError); }, submitForm: function(e){ e.preventDefault(); var form = $(this), btnSubmit = form.find('[type="submit"]'); if(app.validateForm(form) === false) return false; btnSubmit.addClass('disabled'); var str = form.serialize(); $.ajax({ url: 'contacts.php', type: 'post', data: str }).done(function(msg){ if(msg === "OK"){ var res = "<div class=\"alert alert-success\" role=\"alert\"> <strong>Well done!</strong> You successfully read this important alert message. </div>"; $(".fancybox").html(res); setTimeout(function(){ $.fancybox.close(); }, 2000) console.log('ok'); $(".fancybox").fancybox().trigger('click'); }else { $(".fancybox").html(msg); $(".fancybox").fancybox().trigger('click'); } }).always(function(){ btnSubmit.removeAttr('disabled', ''); }); }, validateForm: function(form){ var inputs = form.find('input'), valid = true; form.validate({ invalidHandler: function(event, validator){ var errors = validator.numberOfInvalids(); if (errors) { valid = false; } else { console.log('valide'); } validator.focusInvalid(); } }); return valid; }, removeError: function(){ var $this = $(this), formGroup = $this.closest('.form-group'); formGroup.removeClass('has-danger'); } } app.init(); })(); if($(".modalbox").length){ $(".modalbox").fancybox({ fitToView : false, autoSize : false, closeClick : false, maxWidth : 502, maxHeight : 444, prevEffect : 'none', nextEffect : 'none', padding : 0, margin : 50, closeBtn : false, helpers : { overlay : { css : { 'background' : 'rgba(0, 0, 0, 0.72)' } }, } }); } 
 .callback-modal { display: none; } 
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>JS Bin</title> <script src="https://code.jquery.com/jquery-1.11.3.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.css" /> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.1/jquery.validate.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.1/additional-methods.js"></script> </head> <body> <div class="wrap"> <a href="#request" class="modalbox">Оформить заявку</a> <div id="request" class="callback-modal"> <div class="callback-modal__inner"> <form class="callback__form" id="callbackForm"> <div class="form-row"> <input type="text" name="name" id="r-name" placeholder="Имя" class="input" data-rule-required="true"> </div> <div class="form-row"> <input type="text" name="phone" id="r-phone" placeholder="Телефон" class="input" data-rule-required="true" data-rule-minlength="5"> </div> <div class="form-row"> <input type="text" name="email" id="r-email" placeholder="E-mail" class="input" data-rule-required="true" data-rule-email="true"> </div> <div class="form-row"> <textarea name="msg" id="r-msg" placeholder="Описание сайта" class="input"></textarea> </div> <input type="submit" value="Отправить" class="btn btn__submit"> <div class="fancybox"></div> </form> </div> </div> </div> </body> </html> 

But I can not understand why the test works, only the second time? Maybe someone worked with this plugin.

How can I fix the module so that the plugin works and works as expected (if the fields are not filled, the form is not sent, the error fields are displayed, if everything is OK, then the data is sent)?

    2 answers 2

    In this case, incorrect use of the plugin occurs. Before you use something, you need to initialize it.

    By analogy, expect that this.submitForm will work when a form is submitted without calling app.init .


    Further, the initialization itself is not completely correct.

    In the documentation for the plugin, you can see that the invalidHandler property is needed to execute your code in case the validation fails. In the code in question, in this method the valid variable is set, which is used in the code to determine whether validation has passed or not.

    Instead, it was necessary to use the form method , which just returns the result of the test, without additional variables.

    As a result, the validateForm method : function (form) { can be removed and its use replaced with one line

     form.validate().form() 

    In this case, the plug-in will not be initialized twice or more, due to the presence of a check inside the plug-in itself.

    Example:

     // Callback forms (function() { var app = { init: function() { this.setUpListeners(); }, setUpListeners: function() { $(document).on('submit', 'form', this.submitForm); $(document).on('keyup', 'input', this.removeError); }, submitForm: function(e) { e.preventDefault(); var form = $(this), btnSubmit = form.find('[type="submit"]'); if (form.validate().form() === false) return false; btnSubmit.addClass('disabled'); var str = form.serialize(); $.ajax({ url: 'contacts.php', type: 'post', data: str }).done(function(msg) { if (msg === "OK") { var res = "<div class=\"alert alert-success\" role=\"alert\"> <strong>Well done!</strong> You successfully read this important alert message. </div>"; $(".fancybox").html(res); setTimeout(function() { $.fancybox.close(); }, 2000) console.log('ok'); $(".fancybox").fancybox().trigger('click'); } else { $(".fancybox").html(msg); $(".fancybox").fancybox().trigger('click'); } }).always(function() { btnSubmit.removeAttr('disabled', ''); }); }, removeError: function() { var $this = $(this), formGroup = $this.closest('.form-group'); formGroup.removeClass('has-danger'); } } app.init(); })(); if ($(".modalbox").length) { $(".modalbox").fancybox({ fitToView: false, autoSize: false, closeClick: false, maxWidth: 502, maxHeight: 444, prevEffect: 'none', nextEffect: 'none', padding: 0, margin: 50, closeBtn: false, helpers: { overlay: { css: { 'background': 'rgba(0, 0, 0, 0.72)' } }, } }); } 
     .callback-modal { display: none; } 
     <script src="https://code.jquery.com/jquery-1.11.3.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.css" /> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.1/jquery.validate.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.1/additional-methods.js"></script> <div class="wrap"> <a href="#request" class="modalbox">Оформить заявку</a> <div id="request" class="callback-modal"> <div class="callback-modal__inner"> <form class="callback__form" id="callbackForm"> <div class="form-row"> <input type="text" name="name" id="r-name" placeholder="Имя" class="input" data-rule-required="true"> </div> <div class="form-row"> <input type="text" name="phone" id="r-phone" placeholder="Телефон" class="input" data-rule-required="true" data-rule-minlength="5"> </div> <div class="form-row"> <input type="text" name="email" id="r-email" placeholder="E-mail" class="input" data-rule-required="true" data-rule-email="true"> </div> <div class="form-row"> <textarea name="msg" id="r-msg" placeholder="Описание сайта" class="input"></textarea> </div> <input type="submit" value="Отправить" class="btn btn__submit"> <div class="fancybox"></div> </form> </div> </div> </div> 

    • This is a great answer !!!! THANK YOU !!!!) - HamSter

    As I understand it, you need to initialize validate for the form before starting work with validation. Those. call $("form").validate() after loading the DOM and scripts. In your example, I just wrote this before app.init () (line 97 js) and the form started working from the 1st time.

    • then the meaning of the module is lost, but I would like to implement it with the help of the module. but thanks, if all else fails, you'll have to do it this way ((( - HamSter
    • I, too, was surprised at first - because modularly done =) But judging by the reaction to the first call to validate (), it completely ignores all endpoints that can be described inside (such as OnError, onSuccess, etc.). I tried to get an answer to the first call to validate - I failed. You can make the initialization of the call validation as an example (so that it does not invoke every time at the beginning of the application, but only immediately before starting work with validation). And then use your validate with options. - alexoander
    • @Elena Semenchenko how is lost. The meaning of validation on JS is to dynamically issue hints, highlight green / red. And there is no more sense in it. Because there is JS validation or not - validation must be from the server side. And check by submission on JS - why should it be validated twice, if it can be sent to the server, validated there, and return errors. - Goncharov Alexander
    • @GoncharovAleksandr, the meaning along with the module to use and in just such a structure! The question is why the initialization happens the second time! - HamSter
    • @ElenaSemenchenko Well, the second time since only by pressing the button validate is invoked altogether. Therefore (as I described above) the first pass triggers the initialization in general, and only the second one validates. I apologize if this is an obvious fact - I just wanted to clarify this point. What if we put .validate at the init: function() point? will be called immediately upon module initialization. But there is a minus - every subsequent call to init will trigger validate - alexoander