【问题标题】:jQuery Validation: Changing Rules DynamicallyjQuery 验证:动态更改规则
【发布时间】:2010-11-08 22:18:40
【问题描述】:

我有一个表单,根据单击的单选按钮(登录或注册),显示:

  • 电子邮件地址
  • 密码

或:

  • 姓名
  • 年龄
  • 电子邮件地址
  • 密码

单击单选按钮可切换登录/注册字段的可见性:

<form id="myForm">
    <input name="userAction" type="radio" value="login" checked="checked">Login</input>
    <br />
    <input name="userAction" type="radio" value="signup">Sign Up</input>

    <div id="loginFields" style="display:none">
        <!-- Login fields (email address and password) -->
    </div>

    <div id="signupFields" style="display:none">
        <!-- Signup fields (name, age, email address, password) -->
    </div>
</form>

我正在使用jQuery Validation plug-in,我想使用以下规则:

var signupRules = {
    emailAddressTextBox:
    {
        required: true,
        email: true 
    },
    passwordTextBox:
    {
        required: true,
        minlength: 6,
        maxlength: 24,
        passwordValidationRule: true // custom regex added with $.validator.addMethod()
    }
};

var loginRules = {
    nameTextBox:
    {
        required: true,
        maxlength: 50
    },
    loginEmailAddressTextBox:
    {
        required: true,
        email: true 
    },
    loginPasswordTextBox:
    {
        required: true,
        minlength: 6,
        maxlength: 24,
        passwordValidationRule: true // custom regex added with $.validator.addMethod()
    },
    loginPasswordAgainTextBox:
    {
        required: true,
        minlength: 6,
        maxlength: 24,
        equalTo: "#loginPasswordTextBox"
        passwordValidationRule: true // custom regex added with $.validator.addMethod()        
    }
};

如何根据以下条件动态添加正确的验证规则:

   $("input[name='userAction']").change(function() {
        if ($("input[name='userAction']:checked" ).val() === "login") {
            // use loginRules
        } else {
            // use signupRules
        }
    });

我尝试了以下方法:

$("#myForm").validate({
    rules: ($("input[name='userAction']:checked" ).val() === "login") ? loginRules : signupRules;
});

但由于我的登录字段是默认显示的,因此它的验证工作,但注册场景不;它出于某种原因想要验证登录字段。我错过了什么吗?

【问题讨论】:

  • 您是替换表单中的元素,还是显示表单中的隐藏元素?我会为两个单独的表单设置验证,然后根据选择的选项切换两个表单的可见性。
  • 这是一个单一的表单,其中登录/注册字段的可见性由单选按钮切换。
  • 每个表单只能调用一次 validate 方法。将其视为初始化。详情请查看this post

标签: jquery jquery-validate


【解决方案1】:

啊验证插件,总是那么棘手:(

首先,我为所有输入框添加了 id 属性。然后,我为你做了一个更改函数:

$("input[name='userAction']").change(function() {
    $('#signupFields').toggle();
    $('#loginFields').toggle();    
    if ($("input[name='userAction']:checked").val() === "login") {
        removeRules(signupRules);
        addRules(loginRules);
    } else {        
        removeRules(loginRules);
        addRules(signupRules);

    }
});

添加和删除函数如下所示:

function addRules(rulesObj){
    for (var item in rulesObj){
       $('#'+item).rules('add',rulesObj[item]);  
    } 
}

function removeRules(rulesObj){
    for (var item in rulesObj){
       $('#'+item).rules('remove');  
    } 
}

差不多就是这样。有关工作示例,请参见此处:http://jsfiddle.net/ryleyb/wHpus/66/

编辑:对我来说,不直观的部分是,在您调用 @ 之后,我没有看到一种简单的方法来向整个 form 添加/删除规则987654325@,而您必须操作各个表单元素。

【讨论】:

  • 我看到“$.data(element.form, 'validator') is undefined”错误。
  • 在我的 jsfiddle 上,或者当您在代码中使用它时?如果是你的,你是否在所有表单元素中添加了 id 标签?
  • 我在我的代码中看到了错误。事实证明,在应用规则之前我没有添加 validate() 。这一切都不同 :) 谢谢。
  • 在 1.13.0 版本中,我发现我可以通过覆盖来删除整个规则集。见:stackoverflow.com/a/24829279/866236
  • 使用依赖回调。
【解决方案2】:

或者您可以使用 depends 属性。

http://jqueryvalidation.org/category/plugin/ 搜索依赖

示例:根据需要指定联系人元素和电子邮件地址,后者取决于通过电子邮件检查联系人的复选框。

$(".selector").validate({
  rules: {
    contact: {
      required: true,
      email: {
        depends: function(element) {
          return $("#contactform_email:checked")
        }
      }
    }
  }
});

【讨论】:

  • 这是他如何使用它的一个例子。与其添加/删除规则,不如让它们有条件。
  • 你是对的。然而,这是一个没有解释的例子,甚至不是一个完整的工作解决方案。 depends 仅适用于可以用 truefalse 声明的 rules... 而不是其他任何一个。在 OP 更复杂的情况下,最好换掉整套规则,如已接受的答案中所充分证明的那样。
  • @Sparky 我不同意接受的答案,我的提议更短且不那么复杂,您可以将依赖函数提取为回调方法以将其重用于其他领域。但是,并不是每个人都喜欢干净的代码,或者甚至不知道如何编码。
  • 首先,OP 的确切情况比单个depends 所能完成的要复杂得多。其次,您是在回复将近两年前发表的评论。
  • 我同意 Sparky - 将其扩展为包括 OP 给出的所有 19 条规则,然后让我们来判断你的答案。
【解决方案3】:

这篇文章是几年前的,但由于它已经被浏览了很多次,我认为说 jQuery Validation 插件现在允许我们读取、添加和删除规则会很有用。

一些例子:

  1. 打印所有附加到#myField 的规则: console.log($('#myField').rules());

  2. 删除不需要的规则:$('#myField').rules('remove', 'min');

  3. 添加新规则:$('myField').rules('add', {min: 10});

所以说如果你想动态更新所需的最小值。您可以在之后拨打removeadd

// Something happened. The minimum value should now be 100
$('#myField').rules('remove', 'min');
$('#myField').rules('add', {min: 100});

更多信息可以在这里找到:https://jqueryvalidation.org/category/plugin/#-rules()

【讨论】:

    【解决方案4】:

    如果您想使用新设置(规则、消息...等)再次调用验证 打电话

    $('#formid').removeData('validator')
    

    这将删除表单的验证,然后使用新设置再次对其进行初始化

    【讨论】:

    • 有动态改变规则的内置方法。无需将其清除并重新初始化。
    • 您能告诉我们动态添加/删除规则有哪些方法吗?我真的可以使用这些,因为我正在制作水疗应用程序,并且我有一个验证器对象,我在页面更改后会不断刷新。
    • 它是the rules method along with add。请参阅上面接受的答案以了解如何使用它。还有browse my answers on this plugin for other ways.
    • 那不是我要找的东西,假设我有 page1 和验证器对象,其中包含该页面上 form1 的规则,然后我单击链接转到 page2 并更改该表单的 html(否页面刷新)我将如何更改验证器的规则?你是说我应该每次都使用 for 循环
    • 最后你的方式更好了,我使用相同的原则,但多了两行 $("form").data("unobtrusiveValidation", null); $("form").data("验证器", null); $.validator.unobtrusive.parse($("form"));
    【解决方案5】:

    试试这个..

    rules: {
        address: {
           required: {
                       depends: function(element) {
                         if (....){
                           return true;}
                         else{
                           return false;}
                       }
                     }
                 }
           }
    

    来自here

    【讨论】:

      【解决方案6】:

      现在有一个选项可以忽略基于选择器标准的字段,例如不可见或禁用,这样您就不必更改规则集:

      .validate({
        ignore: ":not(:visible),:disabled",
        ...
      

      【讨论】:

      • 没有实用的方法可以将您的建议应用于 OP 的场景。 (也有用于更改规则的内置方法。)
      • 如果您尝试动态打开或关闭元素的验证,这是一个很好的建议,但如上所述,不适用于规则。
      【解决方案7】:

      跟踪验证对象并直接删除/替换规则。适用于 v1.13.0

      var validation = $('#form1').validate(); //Keep track of validation object
      
      //Rule set 1
      var validationRulesLogin = {
          headerEmail: {
              required: true,
              email: true
          },
          headerPassword: "required"
      };
      var validationMessagesLogin = {
          headerEmail: {
              required: "Please enter your email address.",
              email: "Not a valid email address."
          },
          headerPassword: "Please enter your password."
      };
      
      //Rule set 2
      var validationRulesSignup = {
          signupEmail: {
              required: true,
              email: true
          },
          signupPassword: "required",
          signupPassword2: {
              equalTo: "#phBody_txtNewPassword"
          }
      };
      var validationMessagesSignup = {
          signupEmail: {
              required: "Please enter your email address.",
              email: "Not a valid email address."
          },
          signupPassword: "Please enter your password.",
          signupPassword2: "Passwords are not the same."
      };
      
      //Toggle rule sets
      function validatingLoginForm(){
          validation.resetForm();
          validation.settings.rules = validationRulesLogin;
          validation.settings.messages = validationMessagesLogin;
      }
      function validationSignupForm(){
          validation.resetForm();
          validation.settings.rules = validationRulesSignup;
          validation.settings.messages = validationMessagesSignup;
      }
      

      【讨论】:

        【解决方案8】:

        看看我的回答https://stackoverflow.com/a/20547836/1399001。 它包括一个工作的jsfiddle。 在您的示例中将是这样的:

        $("input[name='userAction']").change(function() {
        
            var settings = $("#myForm").validate().settings;
        
              if ($("input[name='userAction']:checked" ).val() === "login") {
                    $.extend(settings, {
                      rules: loginRules
                    });
            } else {
                    $.extend(settings, {
                      rules: signupRules
                    });
            }
        
        
            $("#myForm").valid();
        
        });
        

        【讨论】:

          【解决方案9】:

          我遇到了类似的问题,并通过向所有登录文本框添加“requiredForLogin”类和向所有注册文本框添加“requiredForSignUp”类来解决它。

          然后使用jQuery的toggleClass,以及jQuery.validate的addClassRules根据按下的按钮来开启和关闭规则。

          function EnableAllValidation() {
              // remove the jquery validate error class from anything currently in error
              //  feels hackish, might be a better way to do this
              $(".error").not("label").removeClass("error");
          
              // remove any the 'disabled' validation classes, 
              //  and turn on all required validation classes 
              //  (so we can subsequently remove the ones not needed)
              $(".requiredForLoginDisabled").toggleClass("requiredForLoginDisabled requiredForLogin");
              $(".requiredForSignUpDisabled").toggleClass("requiredForSignUpDisabled requiredForSignUp");
          }
          function EnableLoginValidation() {
              // reenable all validations
              //  then disable the signUp validations
              EnableAllValidation();
              $(".requiredForSignUp").toggleClass("requiredForSignUpDisabled requiredForSignUp");
          }
          function EnableSignUpValidation() {
              // reenable all validations
              //  then disable the login validations
              EnableAllValidation();
              $(".requiredForLogin").toggleClass("requiredForLoginDisabled requiredForLogin");
          }
          $(document).ready(function () {
              $("input[value='login']").click(function () {
                  EnableLoginValidation();
              });
              $("input[value='signup']").click(function () {
                  EnableSignUpValidation();
              });
          
              $("#myForm").validate();
              jQuery.validator.addClassRules({
                  requiredForSignUp: {
                      required: true
                  },
                  requiredForLogin: {
                      required: true
                  }
              });
          
          });
          

          【讨论】:

            【解决方案10】:

            这可以通过更新.validate().settings.rules轻松完成

            下面的示例 sn-p 用于将添加所需规则的密码字段。

            $('#myForm').validate().settings.rules.password = {required: true};
            

            【讨论】:

              【解决方案11】:

              以下代码运行良好...

              .validate({
                ignore: ":not(:visible),:disabled",
                ...
              

              【讨论】:

              • 这看起来不是一个好的答案,所以它可能应该被否决,但我没有看到删除它的理由。将其标记为“看起来不错”以响应其他人在其上提出的标志。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-04-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多