jQuery验证不存在复选框

时间:2019-05-26 16:48:26

标签: javascript jquery datatables jquery-validate

我有一个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: 这是我初始化数据表及其中复选框的方法

function initializeDataTable(){

$.ajax({
    url: url,
    contentType: "application/json;charset=utf-8",
    method: "GET",
    dataType: 'json',
    cache: false,
    success: function(apps){

        var $dataTable = $("#tbl");
        var appsData = [];

        $.each(apps, function (index, app){
            appsData.push(createRow(index, app));
        });

        var tableData = {
            "data": appsData,
            "order": [ 1, "asc" ],
            "columnDefs": [{ "targets": [0], "orderable": false }],
            "searching": true,
            "paging": true,
            "info": false
        };

    }
}); 
}

function createRow(index, app){

var inputId = 'app_'+app.id;

var checkbox = '<div class="text-center">'
                 + '<label for="'+inputId+'">'
                    + '<input type="checkbox" id="'+inputId+'" name="cbDisplay" class="cbClaim" />'+ '</label>'+ '</div>';

var appsRow = [
    checkbox,
    app.name
];

return appsRow;

}

修改3:

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

2 个答案:

答案 0 :(得分:0)

如果尝试在显示的文档中查找输入/复选框,则只能获取datatables-element的呈现元素。这意味着如果使用数据表过滤器,则可能在文档中找不到任何复选框元素。 如果datatables-element中未显示行,则将其从呈现的表中删除,结果该行中的所有元素也都不可用于包装表单元素。

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

这里是一个示例,说明如何使用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 :(得分:0)

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

我没有看到足够的代码来进行演示,因此下面有一些泛型:

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

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

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

    <input type="checkbox" name="foo" required="required" ....
    
  4. 默认情况下,始终忽略
  5. 隐藏或不可见的字段。如果您的插件隐藏了您要验证的任何字段,那么您需要使用ignore选项覆盖此行为。将ignore设置为[](“无”),以便什么都不会被忽略,并且所有内容都会得到验证。

    ignore: []
    

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

  1. 调用.validate()方法一次以初始化form上的插件。 Typically on page load。但是,您可以将其包含在click处理函数所调用的函数中,这意味着直到单击按钮后才会初始化验证,并且每次单击按钮时都会不必要地重复调用它。

  2. 当您搜索/过滤表时,DataTables插件确实可以完全删除行。尽管验证插件可以处理不可见或隐藏的元素(请参阅上面的项目4),但是没有任何人可以合理地期望它处理DOM中不再存在的元素。我感到奇怪的是,DataTables不能仅隐藏这些行或使其不可见,而不能完全删除。

  3. Jan的解决方案很有趣,因为它遍历DataTables对象以查找已选中的项目。但是,似乎没有办法将此功能正确集成到jQuery Validate插件的操作中。虽然validate插件通常绑定到每个输入并根据规则自动显示/隐藏消息,但这种“解决方法”被笨拙地推入submitHandler中,通常仅在 该表格有效。它还不能利用默认验证消息highlightunhighlightsuccessinvalidHandlerany of the other built-in functions

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