У меня есть JQuery DataTable, в котором есть флажки для выбора элементов в нем. я добавил дж Проверка 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/
Вы, кажется, слишком усложняете это. Кроме того, где HTML-разметка? Где код, который динамически добавляет входные данные?
Я добавил еще одно обновление, надеюсь, оно поможет вам лучше понять мою проблему @Sparky
В дополнение ко всем этим обновлениям просто создайте один работающий jsFiddle, демонстрирующий эти проблемы.
@Sparky Я добавил пример jsFiddle, введите «a» в поиске и нажмите «Отправить» jsfiddle.net/mu79L32w/14



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Если вы попытаетесь найти входные данные/флажки внутри отображаемого документа, вы получите только визуализированные элементы элемента datatables. Это означает, что возможно, что вы не найдете ни одного флажка в документе, если используется фильтр таблиц данных. Если строка не отображается в элементе datatables, она удаляется из отображаемой таблицы. и, как следствие, все элементы внутри этой строки также недоступны для элемента формы-обертки.
Но вы можете перебирать данные/строки объекта DataTable-Object с помощью javascript.
Вот пример того, как проверить, установлен ли какой-либо флажок при отправке формы, с помощью 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/[email protected]/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>Спасибо за ваш ответ! Я попробую это завтра. Можете ли вы взглянуть на мой обновленный вопрос и сказать мне, может ли это сработать?
Конечно. Есть несколько других подходов к этой задаче, которые могут сработать. Например: вы также можете прослушивать события щелчка ввода и отслеживать в переменной, если какой-либо из флажков отмечен.
что мне привязать валидацию к жесткому? мне нужно привязать его к элементу с атрибутом имени?
Я предполагаю, что у вас есть форма вокруг вашего стола, которую вы хотите проверить до/при отправке. В этом случае вы не можете привязать проверку к флажкам, поскольку они не являются частью данных формы, если они не отображаются в таблице. Один из вариантов, который я могу придумать, - это невидимый элемент формы (вне таблицы), который содержит текущее количество выбранных элементов.
Это хорошая идея! так правильно привязать проверку к скрытому вводу вместо отдельных флажков?
Этот ответ, похоже, не имеет ничего общего с плагином jQuery Validation, который использует и спрашивает OP.
@Sparky, какой подход вы бы выбрали для решения этой проблемы?
Я добавил простую проверку с библиотекой jQuery-Validation, которая не требует скрытых элементов в форме и использует предыдущий представленный пример.
Зачем вам делать отдельную проверку через submitHandler, когда вы можете правильно использовать этот плагин? Это даже более подробно, чем попытка ОП.
@Sparky, потому что автор вопроса использует DataTables.js и хочет иметь возможность использовать входной фильтр этой библиотеки. DataTables динамически отображает содержимое таблицы, которая является частью формы. Если нет флажка для рендеринга, то флажка в форме нет.
Верно, и плагин может автоматически обрабатывать динамические вводы несколькими способами. Также нет необходимости писать функции, которые перебирают флажки, чтобы сделать их required.
@Sparky, вы правы, мне не нужно использовать какие-либо пользовательские функции для проверки флажков, required = "required" отлично сработало для меня. Но Ян имеет в виду, что я использую плагин DataTable.js, и если вы используете какие-либо фильтры, флажки и данные исчезают с экрана, что, в свою очередь, отключает проверку, что означает, что вы можете отправить форму, ничего не проверяя.
@BigMon, если вы пытаетесь проверить скрытые или невидимые поля, они будут проигнорированы. Это известная функция плагина, обсуждаемая в документации и в различных вопросах SO. Установите для параметра ignore значение [] («ничего»), то есть ignore: [], чтобы проверялись все скрытые поля.
@Sparky, у тебя было время посмотреть мою демо-ссылку на jsFiddle?
Как вы и подозревали, вы не можете привязать проверку к любому вводу, который еще не существует.
Я не вижу достаточно кода для демонстрации, поэтому некоторые дженерики ниже:
Вам не нужно писать собственный метод для создания флажков required с помощью этого плагина. Если флажки находятся в группе с одним и тем же name, то required сделает хотя бы один из группы обязательным. См.: jsfiddle.net/q357zcwy/1/
Весь смысл метода .rules() заключается в динамическом добавлении правил удаления после того, как плагин уже был инициализирован на форме. Так что, если вы динамически добавляете input, то вызовите .rules() тот inputпосле, который был создан. См.: jsfiddle.net/q357zcwy/2/
Если вы хотите добавить только required, то самый простой способ справиться с этим — поместить атрибут required = "required" на вход, а мой пункт № 2 выше будет отменен. Вам не нужно беспокоиться о том, существует ли он или когда звонить .rules(). Просто создайте input, который включает этот атрибут, и плагин автоматически подберет его. См.: jsfiddle.net/q357zcwy/3/
<input type = "checkbox" name = "foo" required = "required" ....
Скрытые или невидимые поля по умолчанию всегда игнорируются. Если ваш плагин скрывает какие-либо поля, которые вы пытаетесь проверить, вам нужно переопределить это поведение, используя опцию ignore. Установите ignore на []("ничего"), чтобы ничего не игнорировалось и все проверялось.
ignore: []
РЕДАКТИРОВАТЬ: Дополнительные заметки после просмотра ваш jsFiddle:
Метод .validate() вызывается один раз для инициализации плагина в form. Обычно при загрузке страницы. Однако у вас есть это в функции, которая вызывается вашим обработчиком click, что означает, что проверка не инициализируется до тех пор, пока не будет нажата кнопка, и она повторно вызывается без необходимости каждый раз, когда кнопка нажимается.
Плагин DataTables действительно полностью удаляет строки при поиске/фильтрации таблицы. Хотя подключаемый модуль проверки может обрабатывать невидимые или скрытые элементы (см. пункт № 4 выше), никто не может обоснованно ожидать, что он будет обрабатывать элементы, которых больше нет в DOM. Мне кажется странным, что DataTables не может просто скрыть эти строки или сделать их невидимыми, а не удалить их полностью.
Решение Яна интересно тем, что оно перебирает объект DataTables в поисках проверенных элементов. Однако, похоже, нет способа должным образом интегрировать эту функцию в работу подключаемого модуля jQuery Validate. В то время как плагин проверки обычно привязан к каждому входу и автоматически показывает/скрывает сообщения на основе правил, этот «обходной путь» неуклюже впихивается в submitHandler, который обычно вызывается только после форма действительна. Он также не может использовать сообщения проверки по умолчанию, highlight, unhighlight, success, invalidHandler или любые другие встроенные функции.
мощь — это способ использовать showErrors для отображения и скрытия сообщений по умолчанию программно на основе итерации объекта DataTables. Однако этот обходной путь станет слишком сложным. Вам также потребуется собрать имя (имена) проверяемого объекта из объекта DataTable, чтобы знать, какие сообщения переключать. Затем, если ни одна из строк не существует, когда вы хотите проверить, вам придется найти другой способ инициировать проверку. Поскольку почти все функциональные возможности по умолчанию плагина jQuery Validation в любом случае будут перезаписаны, на самом деле может иметь смысл просто написать собственную проверку формы с нуля. Никакой готовый плагин проверки не сможет обрабатывать несуществующие элементы ввода.
спасибо за ваш ответ, я не знал ни о чем из того, что вы упомянули, поэтому я ценю это! можете ли вы взглянуть на мое редактирование и сообщить мне, что, по вашему мнению, является лучшим способом исправить проверку несуществующего флажка (из-за применения фильтра данных)
Только что протестировал Datatables.js + jQuery-Validation. Все три предложенных вами подхода терпят неудачу, если пользователь не установил флажок, а таблица пуста из-за фильтра данных. Форма будет отправлена без каких-либо ошибок или предупреждений.
@Jan - если видимый input находится внутри form и правило required правильно инициализировано, оно буду всегда проверяется. Поэтому, пожалуйста, создайте демонстрацию полный jsFiddle, показывающую ваши наблюдения... Я не собираюсь играть в эту игру в догадки.
Они не скрыты, они удалены из документа. Просто посмотрите с помощью dev-tools/inspector на таблицу в моем примере.
@ Ян - теперь я это вижу. Возможно, было бы лучше обновить формулировку вашего ответа как таковую. "если активен фильтр данных h̶i̶d̶e̶s̶ {удаляет} всех строк"~ Ведь, как вы сказали, они не скрыты.
@Sparky Да, ты прав. Меняю формулировку в посте. DataTables немного сложны/особенны в некоторых ситуациях. Удаление строк предназначено для повышения производительности при работе с большими таблицами, а также для обработки набора данных на стороне сервера.
@Sparky Спасибо за подробный ответ, я очень ценю это. На данный момент я работаю со скрытым флажком за пределами DataTable, привязанным к пользовательской функции проверки jquery, которая проверяет, пуста ли таблица и не выбраны ли флажки. Это такой ужасный обходной путь?
@BigMon, мда ... Я не сторонник таких обходных путей, поскольку флажок вне таблицы не имеет практического значения в контексте проверки записей пользовательской формы. Однако какой у вас есть выбор? Если бы это был мой проект, я бы вообще не удалял элементы ввода из DOM... Я бы их спрятал. В противном случае, если это неизбежно, я бы написал пользовательскую проверку с нуля, поскольку большинство стандартных возможностей плагина jQuery Validate все равно будут обойдены.
@Большой Мон. FWIW, идея скрытого флажка кажется глупой. Если он скрыт, то input не имеет смысла как type = "checkbox". Просто используйте вместо этого type = "hidden", для этого он и предназначен.
@Sparky, я согласен с тобой в этом. Не могли бы вы привязать проверку jQuery к функции вместо ввода? Кроме того, единственная причина, по которой я использую type = "checkbox", а не type = "hidden", заключается в том, что когда я делаю $('form').data('validator').settings.ignore = ':hidden:not("#cbApplicationSelected")'; и добавляю правило: $('[name = "cbApplicationSelected"]').rules('add', { noApplicationSelected: "error" }); с type = "hidden" оно не работает, а type = "checkbox" работает нормально, когда оно заключено в div с class = "hidden"
@BigMon, ну, вы определенно делаете что-то очень неправильно, так как этот базовый код отлично работает для меня: jsfiddle.net/9dn0p6bg Проверьте, что вы делаете внутри метода .rules().... пары key:value представляют rule:parameter. Почему noApplicationSelected: "error", когда должно быть просто required: true. И нет... почему/как бы вы привязали проверку к функции? Это даже не имеет никакого смысла. Вы привязываете проверку данных к элементам ввода формы. В любом случае... слишком много времени потрачено на этот необычный пограничный случай.
Учитывая первоначальный вопрос и учитывая детали, которые я опубликовал, я думаю, вы должны принять мой ответ (нет, вы абсолютно не можете привязать проверку к любому элементу, который не существует в DOM) или, по крайней мере, опубликовать очень подробный отчет о вашем обходном пути. с демо.
Вы не должны проверять html-элементы, которые в настоящее время отображаются таблицами данных. Вместо этого попробуйте перебрать данные объекта DataTable-Object.