【问题标题】:JQuery Validator Checkbox onClick update error message inconsistent behavior?JQuery Validator Checkbox onClick更新错误信息不一致的行为?
【发布时间】:2016-08-19 12:56:07
【问题描述】:

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

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

验证rules 需要选择数字或字符串类型。如果选择了 Number,则还必须选择数字类型(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 复选框被勾选:

我添加了一个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

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


最终解决方案

我有三个要求:

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

实时验证:实现自定义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;
  });

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

not hack:我只有一个未被内置规则和依赖项涵盖的其他要求,即该字符串不是选择int,float或double时的有效类型.我在自定义规则中对此进行了编码(上面的代码)。相关代码重复如下:

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

但是,在此检查之后,我返回 true。虽然在同一规则中编写其他组合很诱人,但通过返回 true,我继续使用 required 规则,即:

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

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

【问题讨论】:

  • 提交时可以同时勾选“Number”和“String”还是只勾选1个?
  • 两者都应该被允许。

标签: javascript jquery jquery-validate


【解决方案1】:

添加这个:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多