JQuery Validator Checkbox onClick更新错误消息不一致行为?

时间:2016-08-19 12:56:08

标签: javascript jquery jquery-validate

我创建了一个非常标准的复选框JQuery验证示例:https://jsfiddle.net/rbL62zm8/1/

为清楚起见,此问题中的代码中省略了console.log语句。

验证rules需要选择数字或字符串类型。如果选择了数字,则还必须选择数字类型(Int,Float或Double)。

var validationRules = {
    debug: true,
    rules: {
      'type': {
        // Number or String
        required: true,
      },
      'numeric': {
        // Int, Float or Double.
        required: '#typeNumber:checked'
      }
    },
    messages: {
      'type': {
        required: 'A data type is required.'
      },
      'numeric': {
        required: 'A numeric data type is required.'
      }
    },
    onclick: function(element) {
      $(element).valid();
    },
    submitHandler: function(form) {
      $("#validationMsg").html("The form is valid.");
      return false;
    },
    errorPlacement: function(label, element) {
      $("#validationMsg").html(label);
    },
  }

相应的HTML表单:

<form id="mainForm" name="mainForm" method='post' action=''>
  <input type="checkbox" name="type" class="type-group" id="typeNumber" value="Number">
  <label for="typeNumber">Number</label>
  <input type="checkbox" name="type" class="type-group" id="typeString" value="String" checked>
  <label for="typeString">String</label>
  <br />
  <input type="checkbox" name="numeric" class="numeric-group" id="numericInt" value="Int">
  <label for="numericInt">Int</label>
  <input type="checkbox" name="numeric" class="numeric-group" id="numericFloat" value="Float">
  <label for="numericFloat">Float</label>
  <input type="checkbox" name="numeric" class="numeric-group" id="numericDouble" value="Double">
  <label for="numericDouble">Double</label>
  <br />
  <input type='submit' name='Submit' value='Submit' />
  <input type='reset' name='Reset' value='Reset' />
</form>

<div id="validationMsg"></div>

表单的默认状态确保勾选String复选框:

enter image description here

我添加了onclick实现,尝试在勾选或取消勾选复选框时验证表单。

使用案例#1

  • 运行JSFiddle。
  • 取消字符串复选框。

结果:显示错误消息,这是正确的。

使用案例#2

  • 运行JSFiddle。
  • 取消字符串复选框。
  • 勾选字符串复选框。

结果:显示错误消息并保持可见。这似乎不一致,因为显示错误消息的操作(取消勾选复选框)被反转,但错误消息未更新。

问题: 如何在状态发生变化时验证所有复选框?

更新

我通过添加:

validation configuration object中实现了invalidHandler
invalidHandler: function(form, validator) {
      var errors = validator.numberOfInvalids();
      console.log('Number of invalids: %s', errors);
    },

JSFiddle:https://jsfiddle.net/xz1a43fm/

只有在表单处于无效状态时才会调用invalidHandler函数。因此,勾选String复选框会将表单置于有效状态,并且不会调用invalidHandler

submitHandlerinvalidHandler我能找到的对应物最接近 - 但这只是onSubmit而不是onClick

最终解决方案

我有三个要求:

  1. 实时验证:在用户与表单进行交互时验证复选框,而不仅仅是在提交时。
  2. 双向依赖关系:验证双向依赖关系。即如果勾选Number,则必须勾选FloatIntDouble,但如果FloatInt或{{1}勾选,Double必须勾选。
  3. 不要黑客攻击:不要在大型​​自定义验证方法中重写内置规则。
  4. 实时验证:实现自定义Number功能很常见,但我遗漏了两个至关重要的细节:

    1. 验证整个表单,而不是单个元素。通过在整个表单上调用onclick,可以评估复选框组之间的所有相互依赖关系。
    2. 检查有效状态并在需要时手动清除错误消息(如@ZirboFilip所示)。
    3. 最终valid()处理程序:

      onclick

      双向依赖关系: 所需属性非常适合单向依赖,但它不适用于复选框组依赖项。合理的规则可能是:

      onclick: function(element) {
                // Validate the entire form.
                var valid = $('#mainForm').valid();
                // Clear error message manually if appropriate.
                if (valid) {
                  $("#validationMsg").html('');
                }
          }
      

      但是,这仅表明如果选中任何类型(数字或字符串),则需要数字类型。因此,以下内容有效:

      enter image description here

      ......这不是我想要的。我添加了一个自定义验证方法:

           'type': {
              required: true,
            },
            'numeric': {
              required: '#typeNumber:checked',
            }
      

      在解决我的第三个要求时,我将在下面更详细地讨论这个问题。

      不要破解:我只有一个额外的要求没有被内置规则和依赖项所涵盖,即当选择Int,Float或Double时,String不是有效类型。我在自定义规则(上面的代码)中对此进行了编码。相关代码重复如下:

        jQuery.validator.addMethod("checkDependencies", function(value, element) {
          // return true if field is ok or should be ignored.
          var intChecked = $('#numericInt').prop('checked');
          var floatChecked = $('#numericFloat').prop('checked');
          var doubleChecked = $('#numericDouble').prop('checked');
          var numberChecked = $('#typeNumber').prop('checked');
          var stringChecked = $('#typeString').prop('checked');
          var numericTypeChecked = intChecked || floatChecked || doubleChecked;
      
          if (!numberChecked && stringChecked) {
            return !numericTypeChecked;
          }
          // Fall-back on built in rules for everything else.
          return true;
        });
      

      然而,在此检查之后,我返回if (!numberChecked && stringChecked) { return !numericTypeChecked; } // Fall-back on built in rules for everything else. return true; 。虽然在同一规则中编写其他组合很有诱惑力,但通过返回true,我会继续使用true规则,即:

      required

      最终JSFiddler:https://jsfiddle.net/bmg2dcha/1/

1 个答案:

答案 0 :(得分:0)

添加:

if($(element).valid()){
    ("#validationMsg").html("");
}

onclick: function(element) { ... }内,应该没问题。