【问题标题】:JQuery validation on not existing checkbox对不存在的复选框进行 JQuery 验证
【发布时间】:2019-05-26 16:48:26
【问题描述】:

我有一个 JQuery DataTable,其中包含用于选择项目的复选框。我加了 j JQuery 验证,这样您就无法在没有至少选中一个复选框的情况下提交表单。这是我的验证的样子:

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

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

我该如何解决这个问题?

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

编辑 2:

探针演示:https://jsfiddle.net/mu79L32w/14/

【问题讨论】:

  • 您不应该检查当前由 DataTables 呈现的 html 元素。而是尝试迭代 DataTable-Object 的数据。
  • 您似乎过于复杂了。另外,HTML 标记在哪里?动态添加输入的代码在哪里?
  • 我添加了另一个更新,希望能帮助你更好地理解我的问题@Sparky
  • 除了所有这些更新之外,请仅构建一个可工作的 jsFiddle 来演示这些问题。
  • @Sparky 我添加了一个 jsFiddle 示例,在搜索中输入“a”并点击提交jsfiddle.net/mu79L32w/14

标签: javascript jquery datatables jquery-validate


【解决方案1】:

如果您尝试在显示的文档中查找输入/复选框,您只能获得数据表元素的渲染元素。这意味着如果使用数据表过滤器,您可能不会在文档中找到任何复选框元素。 如果数据表元素中未显示某行,则会从呈现的表格中删除该行,因此该行内的所有元素也不能用于包装表单元素。

但是您可以使用 javascript 遍历 DataTable-Object 的数据/行。

这是一个示例,说明如何使用 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>

【讨论】:

  • 感谢您的回答!我明天试试这个。你能看看我更新的问题并告诉我这是否可行吗?
  • 当然。此任务还有其他几种可行的方法。例如:如果选中任何复选框,您还可以在变量中监听输入点击事件和跟踪。
  • 我如何将验证绑定到强硬?我必须将它绑定到具有 name 属性的元素吗?
  • 我假设您的桌子周围有一个表格,您希望在提交之前/提交时进行验证。在这种情况下,您无法将验证绑定到复选框,因为当它们不在表格中呈现时,它们不是表单数据的一部分。我能想到的一个选项是一个不可见的表单元素(在表格之外),它包含当前选定元素的数量。
  • 这是个好主意!那么将验证绑定到隐藏输入而不是单个复选框是否正确?
【解决方案2】:

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

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

  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 选项覆盖此行为。将 ignore 设置为 []("nothing") 以便不会忽略任何内容并验证所有内容。

    ignore: []
    

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

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

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

  3. Jan 的解决方案很有趣,因为它遍历 DataTables 对象以查找选中的项目。但是,似乎没有办法将此功能正确地集成到 jQuery Validate 插件的操作中。虽然 validate 插件通常与每个输入相关联并根据规则自动显示/隐藏消息,但这种“解决方法”被笨拙地塞进了 submitHandler,它通常只在 表格有效。它也无法利用默认验证消息highlight、unhighlight、success、invalidHandler 或 any of the other built-in functions。

可能有一种方法可以利用 showErrors 根据通过 DataTables 对象的迭代以编程方式显示和隐藏默认消息。但是,这种解决方法会变得过于复杂。您还需要从 DataTable 对象中收集检查对象的名称,以便知道要切换哪些消息。然后,如果要验证时不存在任何行,则必须找到另一种触发验证的方法。由于 jQuery Validation 插件的几乎所有默认功能都会被覆盖,因此从头开始编写自己的表单验证实际上可能更有意义。没有现成的验证插件能够处理不存在的输入元素。

【讨论】:

  • 谢谢你的回答,我不知道你提到的任何东西,所以我很感激!你能看看我的编辑,让我知道你认为修复不存在复选框的验证的最佳方法(由于应用了数据表过滤器)
  • 刚刚测试过 Datatables.js + jQuery-Validation。如果用户没有选择复选框并且由于数据表过滤器而表为空,则您建议的所有三种方法都会失败。表单将在没有任何错误或警告的情况下提交。
  • @Jan - 如果可见的input 在form 内并且required 规则已正确初始化,它将始终验证。所以请构建一个完整的 jsFiddle 演示来展示你的观察......我不会玩这个猜谜游戏。
  • 它们不是隐藏的,而是从文档中删除的。只需在我的示例中查看表中的 dev-tools/inspector。
  • @Jan - 我现在明白了。也许最好更新您的答案的措辞。 “如果数据表的活动过滤器h̶i̶d̶e̶s̶{removes}所有行”~毕竟,就像你说的那样,它们没有被隐藏。
猜你喜欢
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-26
  • 1970-01-01
  • 1970-01-01
  • 2014-09-10
  • 2017-01-29
相关资源
最近更新 更多