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

JQuery Validator Checkbox onClick update error message inconsistent behavior?

我创建了一个非常标准的复选框 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>

表单的默认状态确保勾选字符串复选框:

我添加了一个 onclick 实现,试图在复选框被选中或未选中时验证表单。

用例 #1

结果:显示错误信息,正确。

用例 #2

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

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


更新

我通过添加

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 函数仅在表单处于无效状态时调用。因此,勾选字符串复选框会使表单进入有效状态,并且不会调用 invalidHandler

submitHandler 是我能找到的与 invalidHandler 对应的最接近的东西 - 但是它只被称为 onSubmit 而不是 onClick.


最终解决方案

我有三个要求:

  1. 实时验证:在用户与表单交互时验证复选框,而不仅仅是在提交时。
  2. 双向依赖:验证双向依赖。 IE。如果勾选 Number,则必须勾选 FloatIntDouble,而且如果 FloatIntDouble 已打勾,Number 必须打勾。
  3. 不要 Hack:不要在大型​​自定义验证方法中重写内置规则。

实时验证:实现自定义 onclick 函数很常见,但我遗漏了两个关键细节:

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

最终的 onclick 处理程序:

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

双向依赖: required 属性非常适合单向依赖,但不适用于复选框组依赖。一个合理的规则可能是:

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

然而,这仅说明如果选中任何类型(数字或字符串),则需要数字类型。因此以下是有效的:

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

  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;
  });

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

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

if (!numberChecked && stringChecked) {
      return !numericTypeChecked;
}
// Fall-back on built in rules for everything else.
return true;

然而,经过这次检查,我returntrue。虽然很想在同一规则中编写其他组合,但通过 returning true,我继续使用 required 规则,即:

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

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

添加这个:

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

onclick: function(element) { ... } 里面应该没问题。