【问题标题】:Javascript Validate on input change, only submit when Submit button clickedJavascript验证输入更改,仅在单击提交按钮时提交
【发布时间】:2012-03-02 17:07:42
【问题描述】:

我的网站上有一个表格。单击提交按钮时,会运行一个函数来获取每个字段的内容,根据 RegEx 和其他要求验证内容,然后如果一切正常,则通过 Ajax 将表单提交到 .php 邮件程序。

我希望表单在输入字段值发生变化时自动验证,或者当输入字段失去焦点时(我没有偏好,要么很好)然后我希望表单仅在以下情况下提交用户单击表单上的提交按钮。如果用户在所有字段都有效之前单击提交按钮,我不希望表单提交。

这是我的代码:

    //contact form validation   
$(function(){
    $('.error').hide();
    // hide error messages onchange
    $("#contact-form").change(function(){
        $('.error').hide(); 
        $("label#name_error").hide(); 
        $("label#invalid_error").hide(); 
        $("label#email_error").hide(); 
        $("label#invalid_phone_error").hide(); 
        $("label#phone_error").hide(); 
        $("label#zip_error").hide();
    });

    // validate fields on click
    $(".cool-button").click(function(){
        $('.error').hide(); 
        $("label#name_error").hide(); 
        $("label#invalid_error").hide(); 
        $("label#email_error").hide(); 
        $("label#invalid_phone_error").hide(); 
        $("label#phone_error").hide(); 
        $("label#zip_error").hide(); 

        var name=$("input#contact_name").val();
        var email=$("input#contact_email").val();
        var emailRegEx =/^([a-zA-Z0-9])(([a-zA-Z0-9])*([\._-])?([a-zA-Z0-9]))*@(([a-zA-Z0-9\-])+(\.))+([a-zA-Z]{2,4})+$/
        var phone=$("input#contact_phone").val();
        var phone=phone.replace(/\s+-/g, "");
        var phoneRegEx = /^(1-?)?\s?(\([2-9]\d{2}\)|\s?-?[2-9]\d{2})-?\s?[2-9]\d{2}-?\d{4}$/
        var zip=$("input#contact_zip").val();
        var best_time=$("input#contact_best_time").val();
        var message=$("textarea#contact_message").val();
        var timestamp=$("input#timestamp").val();

        if(name==""){
            $("label#name_error").show();
            $("input#contact_name").focus();return false;
            }
        if(email==""){
            $("label#email_error").show();
            $("input#contact_email").focus();return false;
            }
        if (document.getElementById('contact_email').value.search(emailRegEx )==-1) {
            $("label#invalid_error").show();
            $("input#contact_email").focus();return false;
            }
        if(phone==""){
            $("label#phone_error").show();
            $("input#contact_phone").focus();return false;
            }
        if (document.getElementById('contact_phone').value.search(phoneRegEx )==-1) {
            $("label#invalid_phone_error").show();
            $("input#contact_phone").focus();return false;
            }
        if(zip==""){
            $("label#zip_error").show();
            $("input#contact_zip").focus();return false;
            }
        if(message==""){
            $("label#message_error").show();
            $("textarea#contact_message").focus();return false;
            }
        else {
var dataString='contact_name='+name+'&contact_email='+email+'&contact_phone='+phone+'&contact_zip='+zip+'&contact_best_time='+best_time+'&timestamp='+timestamp+'&contact_message='+encodeURIComponent(message);
    $.ajax({
        type:"POST",
        url:"php/contact.php",
        data:dataString,
        success:function(){$('#contact-form').html("<div id='message'></div>");$('#message').html("<h3>Message Sent</h3>").append("<p>Thank you for contacting us. We'll be in touch. <br /><br />If you have any further questions, you can always email us at info@wirecrafters.com or call us at 800-924-9473</p>").hide().fadeIn(800,function(){$('#message').append("<img id='checkmark' src='images/submit2.png' />");});}});
        }
        return false;
    });

});

这是表单的 HTML 和 PHP 代码

<form id="contact-form" method="post" action="#">
                          <p class="form-subscr-field">
                            <label for="contact_name" id="contact_name_label">Your name: *</label>
                            <input id="contact_name" type="text" name="contact_name" class="inputbox" size="10" required/>
                            <label class="error error-tip" for="contact_name" id="name_error" style="display: none; ">Please enter your name.</label>
                          </p>
                          <p class="form-subscr-field">
                            <label for="contact_email" id="contact_email_label">E-mail Address: *</label>
                            <input id="contact_email" type="email" name="contact_email" class="inputbox" size="10" required/>
                            <label class="error error-tip" for="contact_email" id="email_error" style="display: none; ">Please enter your email address.</label>
                            <label class="error error-tip" for="contact_email" id="invalid_error" style="display: none; ">Invalid email address.</label>
                          </p>
                          <fieldset class="w50">
                          <p class="form-subscr-field rowElem left">
                            <label for="contact_phone" id="contact_phone_label">Phone: *</label>
                            <input id="contact_phone" type="tel" name="contact_phone" class="inputbox"  size="10" required minlength="9"/>
                            <label class="error error-tip" for="contact_phone" id="phone_error" style="display: none; ">Please enter your phone number.</label>
                            <label class="error error-tip" for="contact_phone" id="invalid_phone_error" style="display: none; ">Please enter a valid phone number.</label>
                          </p>
                           </fieldset>
                           <fieldset class="w50">
                          <p class="form-subscr-field rowElem right">
                            <label for="contact_zip" id="contact_zip_label">Zip Code: *</label>
                            <input id="contact_zip" type="text" name="contact_zip" class="inputbox"  size="10" required minlength="5"/>
                            <label class="error error-tip" for="contact_zip" id="zip_error" style="display: none; ">Please enter your shipping zip code.</label>
                          </p>
                           </fieldset>
                          <p class="form-subscr-field">
                            <label for="contact_best_time" id="contact_best_time_label">Best time to Contact:</label>
                            <input id="contact_best_time" type="text" name="contact_best_time" class="inputbox"  size="10" />
                          </p>
                          <p class="form-subscr-field">
                            <label for="contact_message" id="comment_label">Your message: *</label>
                            <textarea id="contact_message" name="contact_message" rows="8" cols="30" required minlength="2"></textarea>
                            <label class="error error-tip" for="contact_message" id="message_error" style="display: none; ">This field is required.</label>
                          </p>
                          <input type="hidden" id="timestamp" name="timestamp" value="<?php
$hourdiff = "2"; // hours diff btwn server and local time
$insertdate = date("l, d F Y h:i a",time() + ($hourdiff * 3600));
print ("$insertdate");
?>" />
                          <div class="submit-contact">
                            <p>
                              <input type="submit" name="submit" class="cool-button csbutton-color spot-action" id="contact_button" value="Submit" />
                            </p>
                          </div>
                        </form>

【问题讨论】:

  • 只是好奇;你也在服务器上验证是吗?
  • 立即验证的问题是,您将在还没有值的字段中显示错误。您必须手动分解它,这会很丑陋,或者使用某种插件/库(您可以自己编写)。
  • @Jeffery:为了确保我理解你的问题,解释一下你在服务器上验证的意思是什么?
  • 用户很可能禁用 JavaScript 从而绕过验证,因此在客户端和服务器上进行验证通常是一种很好的做法。
  • 我真正想要的是当输入框失去焦点时我的函数的第一部分工作,然后如果函数的第一部分说一切正常,如果用户点击提交按钮,表单提交(执行ELSE语句中的代码)

标签: javascript ajax jquery-validate validation


【解决方案1】:

这通常通过keyup 函数实现。 每当释放一个键时,都可以调用一个函数来确保所有字段都是准确的,如果是,则以一种不显眼的方式让用户知道。在您的情况下,您可以禁用提交按钮,除非所有字段都正确。

注意:您不应该使用该功能修改当前编辑的文本字段,或做任何其他会证明对用户感到烦恼的事情;)


编辑:我修改了代码以在每次为所有输入字段解除键时进行验证。 我不精通 JQuery,所以我用香草 Javascript 做到了。如果需要,它应该很容易转换。

$(function(){


  var inputs = document.getElementsByTagName("input");

  for(var i = 0; i < inputs.length; i++) {

    inputs[i].addEventListener("keyup", function(){validate()}, true);

  }


  $('.error').hide();
  $(".cool-button").click(function(){validate()});

  function validate() {
                          $('.error').hide(); 
                          $("label#name_error").hide(); 
                          $("label#invalid_error").hide(); 
                          $("label#email_error").hide(); 
                          $("label#invalid_phone_error").hide(); 
                          $("label#phone_error").hide(); 
                          $("label#zip_error").hide(); 

                          var name=$("input#contact_name").val();
                          var email=$("input#contact_email").val();
                          var emailRegEx =/^([a-zA-Z0-9])(([a-zA-Z0-9])*([\._-])?([a-zA-Z0-9]))*@(([a-zA-Z0-9\-])+(\.))+([a-zA-Z]{2,4})+$/
                          var phone=$("input#contact_phone").val();
                          var phone=phone.replace(/\s+-/g, "");
                          var phoneRegEx = /^(1-?)?\s?(\([2-9]\d{2}\)|\s?-?[2-9]\d{2})-?\s?[2-9]\d{2}-?\d{4}$/
                          var zip=$("input#contact_zip").val();
                          var best_time=$("input#contact_best_time").val();
                          var message=$("textarea#contact_message").val();
                          var timestamp=$("input#timestamp").val();

                          if(name==""){
                          $("label#name_error").show();$("input#contact_name").focus();return false;
                          }
                          if(email==""){
                          $("label#email_error").show();$("input#contact_email").focus();return false;
                          }
                          if (document.getElementById('contact_email').value.search(emailRegEx )==-1) {
                          $("label#invalid_error").show();$("input#contact_email").focus();return false;
                          }
                          if(phone==""){
                          $("label#phone_error").show();$("input#contact_phone").focus();return false;
                          }
                          if (document.getElementById('contact_phone').value.search(phoneRegEx )==-1) {
                          $("label#invalid_phone_error").show();$("input#contact_phone").focus();return false;
                          }
                          if(zip==""){
                          $("label#zip_error").show();$("input#contact_zip").focus();return false;
                          }
                          if(message==""){
                          $("label#message_error").show();$("textarea#contact_message").focus();return false;
                          }
                          else {
                          var dataString='contact_name='+name+'&contact_email='+email+'&contact_phone='+phone+'&contact_best_time='+best_time+'&contact_zip='+zip+'&timestamp='+timestamp+'&contact_message='+encodeURIComponent(message);
                          $.ajax({
                                 type:"POST",
                                 url:"php/contact.php",
                                 data:dataString,
                                 success:function(){$('#contact-form').html("<div id='message'></div>");$('#message').html("<h3>Message Sent</h3>").append("<p>Thank you for contacting us. We'll be in touch. <br /><br />If you have any further questions, you can always email us at info@wirecrafters.com or call us at 800-924-9473</p>").hide().fadeIn(800,function(){$('#message').append("<img id='checkmark' src='images/submit2.png' />");});}});
                          }
                          return false;
                          };
  });

【讨论】:

  • 有没有办法修改我上面已有的代码?我已经内置了自定义 jQuery 工具提示作为验证消息。当输入字段失去焦点时,我想在“else”语句之前执行所有操作,然后仅在所有字段都有效时执行“else”操作,并且仅当用户单击提交按钮时。
  • 这似乎需要添加很多工作或代码,但 jquery 工具验证器是一个小插件,如果您每次要提交表单时都执行上述操作,它将为您节省大量代码。表单插件将使您不必手动序列化表单(这也是您在上面所做的)
  • 此时重做网站上的所有表单将是一项艰巨的任务 :( 有没有办法将函数拆分为两个不同的事物,其中:函数 1 - 获取值模糊或从输入字段更改,然后验证,如果不正确则抛出弹出消息。功能 2 - 如果第一个函数将某个变量(或任何更好的方法)设置为“有效”或其他东西,那么当用户点击提交按钮,表单提交了吗?
  • 您可能可以将键盘功能应用到论坛,因此您只需执行一次。虽然不积极。编辑:您还可以遍历所有元素并附加一个事件侦听器。
  • 这是我可以用上面显示的原始代码做的事情吗?如果有,给我看看? :)
【解决方案2】:

您应该使用某种验证器插件。就我个人而言,我使用过 jquery 工具表单验证器,效果很好。还有其他的。检查这个: http://flowplayer.org/tools/validator/

我还使用了我构建的一个插件,该插件将采用表单并通过 ajax 提交,并且有一些与我的工作方式非常相似:

http://jquery.malsup.com/form/

就是一个例子。这允许您以普通 html 格式制作表单,并将表单提交到表单的操作 url,并且它将构建表单值的方式与您在没有 ajax 的情况下提交时浏览器的方式相同。因此,无论您的后端脚本是表单字段提交,就好像您没有使用 ajax 一样。

由于这对您来说似乎工作量太大,让我向您展示您的代码在使用和不使用它时的样子。

没有(看上面你的js)。

不假设您的表单看起来像这样(简化)

<form method="POST" action="php/contact.php">
  <label for="contact_name">Name</label>
  <input name="contact_name" id="contact_name" />
  <br />
  <label for="contact_email">Email</label>
  <input name="contact_email" id="contact_email" />
  <br />
  <label for="contact_phone">Phone</label>
  <input name="contact_phone" id="contact_phone" />
  <br />
  <label for="contact_zip">Zip</label>
  <input name="contact_zip" id="contact_zip" />
  <br />
  <label for="contact_best_time">Best time for Contact</label>
  <input name="contact_best_time" id="contact_best_time" />
  <br />
  <label for="contact_message">Message:</label>
  <input name="contact_message" id="contact_message" />
</form>

现在这可能类似于现在的样子,没有所有额外的 html 用于格式化。

如果您同时使用验证器和 ajax 表单验证器,则几乎不需要进行任何更改。让我给他们看。

使用验证器和 ajax 表单,您将拥有以下内容:

<form method="POST" action="php/contact.php" class="use-validator ajax-form">
  <label for="contact_name">Name</label>
  <input name="contact_name" id="contact_name" />
  <br />
  <label for="contact_email">Email</label>
  <input name="contact_email" id="contact_email" type="email" required="required" />
  <br />
  <label for="contact_phone">Phone</label>
  <input name="contact_phone" id="contact_phone" type="phone" />
  <br />
  <label for="contact_zip">Zip</label>
  <input name="contact_zip" id="contact_zip" required="required" />
  <br />
  <label for="contact_best_time">Best time for Contact</label>
  <input name="contact_best_time" id="contact_best_time" required="required" />
  <br />
  <label for="contact_message">Message:</label>
  <textarea name="contact_message" id="contact_message" required="required"></textarea>
</form>

那么你的js就是:

$.tools.validator.fn("[type=phone]", "Invalid phone number", function(input, value) {   
   var phoneRegEx = /^(1-?)?\s?(\([2-9]\d{2}\)|\s?-?[2-9]\d{2})-?\s?[2-9]\d{2}-?\d{4}$/ 
   return value.test(phoneRegEx);
});

$("form.use-validator").validator();

$("form.ajax-form").ajaxForm({
 success:function(){$('#contact-form').html("<div id='message'></div>");$('#message').html("<h3>Message Sent</h3>").append("<p>Thank you for contacting us. We'll be in touch. <br /><br />If you have any further questions, you can always email us at info@wirecrafters.com or call us at 800-924-9473</p>").hide().fadeIn(800,function(){$('#message').append("<img id='checkmark' src='images/submit2.png' />");});}});
});

您制作的任何自定义验证器都可以在其他表单上重复使用..

然后您可能需要一些自定义错误消息,但仅此而已..您可以删除所有其他 js 代码。

【讨论】:

  • 我更新了我的答案。我无法从您的代码中准确判断错误如何查找您的表单,但我发现使用 valiator 插件和一些工作可以为您节省大量代码。然后 ajax 表单简化了提交表单的过程,因此您不必手动构建要发送的 post/get 值。
  • 我的错误是用 CSS 设计的,看起来像 jquery 工具提示。它们附加了某些用于样式的类,然后根据验证显示或隐藏。如果我使用上面包含的更新代码,我是否必须包含/附加一个“验证”文件或任何东西?
  • 如果您有自定义验证,那么您需要为每个验证器创建一个验证器。您实际上可以将上面的验证器与您现在的方式结合使用,但您必须做一些工作。您能否在原始消息中包含您的表单的 html 外观?我很好奇错误出现的方式/位置。
  • 我编辑了我的原始问题并包含了表单的代​​码。任何帮助都会很棒! javascript显示或隐藏隐藏标签,并使用CSS进行样式化
  • 我想你想要使用的是flowplayer.org/tools/validator/#effects 我为我建立的网站写了一个,它将错误放在输入旁边的一个div中。由于每个输入都包含在一个 div 中,因此我能够以不使用绝对定位的方式定位错误,因此不会与页面上的其他内容重叠。如果你愿意,我可以为你提供代码。
【解决方案3】:

我倾向于分解每个输入的验证,这使这些工作变得容易得多。您还可以使用 jQuery 插件,从长远来看,它可能会更加模块化。

也就是说,我会这样做 (working jsFiddle):

//contact form validation 
$(function() {
    $('.error').hide(); //hide all errors
    function fieldHasValue(field, label) {
        var value = field.val().trim(); //Grab value without leading or trailing whitespace
        if (value.length > 0) {
            label.hide();
        } else {
            label.show();
            field.focus();
        }
        return (value.length > 0);
    }
    function nameIsValid() {
        return fieldHasValue($("input#contact_name"), $("label#name_error"));
    }
    function emailIsValid() {
        var email = $("input#contact_email").val().trim(); //Grab value without leading or trailing whitespace
        var emailRegEx = /^([a-zA-Z0-9])(([a-zA-Z0-9])*([\._\-])?([a-zA-Z0-9]))*@(([a-zA-Z0-9\-])+(\.))+([a-zA-Z]{2,4})+$/;
        var isValid = (email.length > 0) && email.match(emailRegEx);
        if (isValid) {
            $("label#email_error").hide();
            $("label#invalid_error").hide();
        } else if (email.length > 0) {
            $("label#invalid_error").show();
            $("input#contact_email").focus();
        } else {
            $("label#email_error").show();
            $("input#contact_email").focus();
        }
        return isValid;
    }
    function phoneIsValid() {
        var phone = $("input#contact_phone").val().replace(/\s+-/g, "").trim(); //Grab value without leading or trailing whitespace and replace [whitespace -] with an empty string.
        var phoneRegEx = /^(1-?)?\s?(\([2-9]\d{2}\)|\s?-?[2-9]\d{2})-?\s?[2-9]\d{2}-?\d{4}$/;
        var isValid = (phone.length > 0) && phone.match(phoneRegEx);
        if (isValid) {
            $("label#invalid_phone_error").hide();
            $("label#phone_error").hide();
        } else if (phone.length > 0) {
            $("label#invalid_phone_error").show();
            $("input#contact_phone").focus();
        } else {
            $("label#phone_error").show();
            $("input#contact_phone").focus();
        }
        return isValid;
    }
    function zipIsValid() {
        return fieldHasValue($("input#contact_zip"), $("label#zip_error"));
    }
    function messageIsValid() {
        return fieldHasValue($("textarea#contact_message"), $("label#message_error"));
    }
    function bestTimeIsValid() {
        return fieldHasValue($("input#contact_best_time"), $("label#best_time_error"));
    }
    function allInputsAreValid() {
        var validName = nameIsValid();
        var validEmail = emailIsValid();
        var validPhone = phoneIsValid();
        var validZIP = zipIsValid();
        var validMessage = messageIsValid();
        var validBestTime = bestTimeIsValid();
        var isValid = validName && validEmail && validPhone && validZIP && validMessage && validBestTime;
        return isValid;
    }
    $("input#contact_name").on('change blur', nameIsValid);
    $("input#contact_email").on('change blur', emailIsValid);
    $("input#contact_phone").on('change blur', phoneIsValid);
    $("input#contact_zip").on('change blur', zipIsValid);
    $("textarea#contact_message").on('change blur', messageIsValid);
    $("input#contact_best_time").on('change blur', bestTimeIsValid);
    $("input#contact_button").on('click', function (e) {
        var timestamp = $("input#timestamp").val();

        if (allInputsAreValid()) {
            var dataString = 'contact_name=' + name + '&contact_email=' + email + '&contact_phone=' + phone + '&contact_zip=' + zip + '&contact_best_time=' + best_time + '&timestamp=' + timestamp + '&contact_message=' + encodeURIComponent(message);
            $.ajax({
                type: "POST",
                url: "php/contact.php",
                data: dataString,
                success: function() {
                    $('#contact-form').html("<div id='message'></div>");
                    $('#message').html("<h3>Message Sent</h3>").append("<p>Thank you for contacting us. We'll be in touch. <br /><br />If you have any further questions, you can always email us at info@wirecrafters.com or call us at 800-924-9473</p>").hide().fadeIn(800, function() {
                        $('#message').append("<img id='checkmark' src='images/submit2.png' />");
                    });
                }
            });
        }
        e.preventDefault();
        return false;
    });
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 2017-08-15
    • 1970-01-01
    相关资源
    最近更新 更多