JQuery 对不存在的复选框进行验证

JQuery validation on not existing checkbox

我有一个 JQuery 数据表,其中包含 select 个项目的复选框。我加了j JQuery 验证,以便您必须至少 select 选中一个复选框才能提交表单。这是我的验证结果:

jQuery.validator.addMethod("noApplicationSelected", function(value, element, params) { return $('.cbDisplay').length != 0; },'{0}');
$('[name="cbDisplay"]').rules('add', { noApplicationSelected: ['No checkbox selected'] });

一切正常,但我的问题是,例如,如果我在我的 DataTable 搜索中添加一个过滤器,使得不存在任何条目(空 DataTable),并且我尝试提交表单,即使我没有提交,它也会提交' t selected 任何复选框。 我认为这样做的原因是因为验证无法绑定复选框上的规则,因为它们不存在。

我该如何解决这个问题?

编辑 1: 添加一些验证来检查 DataTable 是否为空并且复选框是否 selected 可以解决我的问题吗?但我看到的问题是我将此验证绑定到什么?我想我可以将它绑定到 select all/deselect all 复选框,但这没有意义

编辑 2:

问题演示:https://jsfiddle.net/mu79L32w/14/

如果您尝试在显示的文档中找到 inputs/checkboxes,您只会得到 datatables-element 的渲染元素。这意味着如果使用 datatables 过滤器,您可能在文档中找不到任何 checkbox-element。 如果某行未显示在 datatables-element 中,它将从呈现的 table 中删除,因此该行内的所有元素也不可用于换行form-element.

但是您可以使用 javascript 迭代 DataTable-Object 的 data/rows。

下面是一个示例,说明如何使用 jquery-validates submitHandler.

测试表单提交时是否选中了任何复选框

$(document).ready(function() {

  let table = $('#example').DataTable({
    "columns": [
      { "data": "column_a" },
      { "data": "column_b" }
    ]
  });
  
  function isAnythingChecked() {
    let foundChecked = false;
    let inputs = table.rows().nodes().to$().find('input');
    for (let input of inputs) {
      if (input.checked) foundChecked = true;
    }
    return foundChecked;
  }
  
  $("#myForm").validate({
    submitHandler: function(form) {
      if (isAnythingChecked()) {
        alert('Yeah! A checkbox is selected');
        //form.submit();
      } else {
        alert('Oh no! No checkbox selected');
      }
    }
  });

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-validation@1.19.0/dist/jquery.validate.min.js"></script>

<link href="https://cdn.datatables.net/v/dt/dt-1.10.18/datatables.min.css" rel="stylesheet"/>
<script src="https://cdn.datatables.net/v/dt/dt-1.10.18/datatables.min.js"></script>

<form id="myForm">

  <table id="example" class="display" style="width:100%">
    <thead>
      <tr>
        <th>Column A</th>
        <th>Column B</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><input type="checkbox"> Checkbox 1</td>
        <td>Test</td>
      </tr>
      <tr>
        <td><input type="checkbox"> Checkbox 2</td>
        <td>Lorem</td>
      </tr>
      <tr>
        <td><input type="checkbox"> Checkbox 3</td>
        <td>ipsum</td>
      </tr>
    </tbody>
  <table>

  <button id="btn" type="submit">Submit</button>
  
</form>

如您所料,您无法将验证绑定到任何尚不存在的输入。

我没有看到足够的演示代码,所以下面是一些泛型:

  1. 您无需编写自定义方法来使用此插件制作复选框 required。如果复选框在共享相同 name 的组中,则 required 将使组中的至少一个成为必填项。参见:jsfiddle.net/q357zcwy/1/

  2. .rules() 方法的重点是在插件已经在表单上初始化后动态添加删除规则。因此,如果您动态添加 input,然后在创建 input 之后调用 .rules() 。参见:jsfiddle.net/q357zcwy/2/

  3. 如果您只想添加 required,那么最简单的处理方法是将 required="required" 属性放在输入上,我上面的项目 #2 被否定.您不必担心它是否存在或何时调用 .rules()。只需创建包含此属性的 input,插件就会自动获取它。参见:jsfiddle.net/q357zcwy/3/

    <input type="checkbox" name="foo" required="required" ....
    
  4. 默认情况下始终忽略隐藏或不可见的字段。如果您的插件隐藏了您尝试验证的任何字段,那么您需要使用 ignore 选项 over-ride 此行为。将 ignore 设置为 []("nothing") 以便不会忽略任何内容并验证所有内容。

    ignore: []
    

编辑:看到your jsFiddle后的更多注释:

  1. .validate() 方法被调用一次以初始化 form 上的插件。 Typically on page load。但是,您在 click 处理程序调用的函数中拥有它,这意味着在单击按钮之前不会初始化验证,并且每次单击按钮时都会不必要地重复调用它。

  2. 当您 search/filter table 时,DataTables 插件确实会完全删除行。尽管验证插件可以处理不可见或隐藏的元素(参见上面的第 4 项),但任何人都无法合理地期望它处理 DOM 中不再存在的元素。我觉得很奇怪,DataTables 不仅可以隐藏这些行或使它们不可见,而不是完全删除。

  3. Jan 的解决方案很有趣,因为它遍历 DataTables 对象以查找选中的项目。但是,似乎没有办法将此功能正确集成到 jQuery Validate 插件的操作中。虽然验证插件通常绑定到每个输入并根据规则自动 shows/hides 消息,但此 "workaround" 被笨拙地推入 submitHandler,通常只调用 after 表格有效。它也无法利用默认验证消息 highlightunhighlightsuccessinvalidHandlerany of the other built-in functions.

可能 是一种利用 showErrors 根据 DataTables 对象的迭代以编程方式显示和隐藏默认消息的方法。但是,此解决方法会变得过于复杂。您还需要从 DataTable 对象中收集选中对象的名称,以便了解要切换的消息。然后,如果要验证时存在 none 行,则必须找到另一种方法来触发验证。由于 jQuery 验证插件的几乎所有默认功能无论如何都是 over-written,因此从头开始编写自己的表单验证实际上可能更有意义。没有 off-the-shelf 验证插件将能够处理不存在的输入元素。