Я использую отличный плагин jQuery Validate для проверки некоторых форм. В одной форме мне нужно убедиться, что пользователь заполняет хотя бы одно из группы полей. Думаю, у меня есть неплохое решение, и я хотел им поделиться. Пожалуйста, предложите любые улучшения, о которых вы можете подумать.
Не найдя встроенного способа сделать это, я поискал и нашел специальный метод проверки Ребекки Мерфи , который оказался очень полезным.
Я улучшил это тремя способами:
- Чтобы вы могли передать селектор для группы полей
- Чтобы вы могли указать, сколько из этой группы должно быть заполнено для прохождения проверки
- Чтобы показать, что все входы в группе проходят проверку, как только один из них проходит проверку. (См. Обращение к Нику Крейверу в конце.)
Таким образом, вы можете сказать: «необходимо заполнить как минимум X входов, соответствующих селектору Y».
Конечный результат с такой разметкой:
<input class="productinfo" name="partnumber">
<input class="productinfo" name="description">
... это группа правил вроде этой:
// Both these inputs input will validate if
// at least 1 input with class 'productinfo' is filled
partnumber: {
require_from_group: [1,".productinfo"]
}
description: {
require_from_group: [1,".productinfo"]
}
Пункт № 3 предполагает, что вы добавляете класс .checked
к своим сообщениям об ошибках после успешной проверки. Вы можете сделать это следующим образом, как показано здесь .
success: function(label) {
label.html(" ").addClass("checked");
}
Как и в приведенной выше демонстрации, я использую CSS, чтобы дать каждому span.error
изображению X в качестве фона, если у него нет класса .checked
, и в этом случае он получает изображение галочки.
Вот мой код:
jQuery.validator.addMethod("require_from_group", function(value, element, options) {
var numberRequired = options[0];
var selector = options[1];
//Look for our selector within the parent form
var validOrNot = $(selector, element.form).filter(function() {
// Each field is kept if it has a value
return $(this).val();
// Set to true if there are enough, else to false
}).length >= numberRequired;
// The elegent part - this element needs to check the others that match the
// selector, but we don't want to set off a feedback loop where each element
// has to check each other element. It would be like:
// Element 1: "I might be valid if you're valid. Are you?"
// Element 2: "Let's see. I might be valid if YOU'RE valid. Are you?"
// Element 1: "Let's see. I might be valid if YOU'RE valid. Are you?"
// ...etc, until we get a "too much recursion" error.
//
// So instead we
// 1) Flag all matching elements as 'currently being validated'
// using jQuery's .data()
// 2) Re-run validation on each of them. Since the others are now
// flagged as being in the process, they will skip this section,
// and therefore won't turn around and validate everything else
// 3) Once that's done, we remove the 'currently being validated' flag
// from all the elements
if(!$(element).data('being_validated')) {
var fields = $(selector, element.form);
fields.data('being_validated', true);
// .valid() means "validate using all applicable rules" (which
// includes this one)
fields.valid();
fields.data('being_validated', false);
}
return validOrNot;
// {0} below is the 0th item in the options field
}, jQuery.format("Please fill out at least {0} of these fields."));
Ура!
Выкрикивать
Теперь для этого крика - изначально мой код просто слепо скрывал сообщения об ошибках в других совпадающих полях вместо их повторной проверки, что означало, что если была другая проблема (например, `` разрешены только числа, и вы вводили буквы '') , он был скрыт, пока пользователь не попытался отправить. Это произошло потому, что я не знал, как избежать петли обратной связи, упомянутой в комментариях выше. Я знал, что должен быть способ, поэтому я задал вопрос , и Ник Крейвер просветил меня. Спасибо, Ник!
Вопрос решен
Изначально это был вопрос типа «позвольте мне поделиться этим и посмотреть, сможет ли кто-нибудь предложить улучшения». Хотя я все еще приветствую обратную связь, я думаю, что на данный момент она довольно полная. (Его можно было бы короче, но я хочу, чтобы его было легко читать и не обязательно кратко.) Так что наслаждайтесь!
Обновление - теперь часть проверки jQuery
Это было официально добавлено в jQuery Validation 3 апреля 2012 г.
источник
Ответы:
Это отличное решение, Натан. Большое спасибо.
Вот способ заставить приведенный выше код работать на случай, если у кого-то возникнут проблемы с его интеграцией, как это сделал я:
Код внутри файла additional-methods.js :
Код внутри html файла:
Не забудьте включить файл additional-methods.js!
источник
require_from_group: [1,".partnumber"]
и...[1,".contactname"]
убедиться, что вы подтверждаете правильные вещи.Хорошее решение. Однако у меня была проблема, что другие обязательные правила не работали. Выполнение .valid () для формы устранило эту проблему для меня.
источник
validator.formSubmit = true
. Затем в методе require-from-group я проверяю наличие этого флага; если он там есть$(element.form).valid();
, то естьfields.valid();
.Спасибо, Шон. Это устранило мою проблему, когда код игнорировал другие правила.
Я также внес несколько изменений, чтобы сообщение «Пожалуйста, заполните хотя бы одно поле ..» отображалось в отдельном блоке, а не после всех полей.
введите сценарий проверки формы
добавьте это где-нибудь на странице
добавить в метод require_from_group функцию addMethod
источник
Я отправил патч , который не страдает от проблем, которые есть в текущей версии (в результате чего опция «обязательный» перестает правильно работать в других полях, обсуждение проблем с текущей версией находится на github .
Пример на http://jsfiddle.net/f887W/10/
источник
Запуск имени переменной с $ требуется в PHP, но довольно странно (IMHO) в Javascript. Кроме того, я считаю, что вы называете его «$ модуль» дважды и «модуль» один раз, верно? Похоже, этот код работать не должен.
Кроме того, я не уверен, что это обычный синтаксис плагина jQuery, но я мог бы добавить комментарии над вашим вызовом addMethod, объясняя, что вы делаете. Даже с вашим текстовым описанием выше сложно следовать коду, потому что я не знаю, к какому набору полей,: заполненному, значению, элементу или селектору относятся. Возможно, большая часть этого очевидна для кого-то, кто знаком с плагином Validate, поэтому используйте суждение о том, какое количество объяснений является правильным.
Возможно, вы могли бы выделить несколько переменных, чтобы самостоятельно задокументировать код; лайк,
(при условии, что я понял значение этих фрагментов вашего кода! :))
Я не совсем уверен, что на самом деле означает «модуль» - есть ли более конкретное имя, которое вы могли бы дать этой переменной?
Хороший код в целом!
источник
Поскольку форма, над которой я работаю, имеет несколько клонированных областей с подобными сгруппированными входами, я передал дополнительный аргумент конструктору require_from_group, изменив ровно одну строку вашей функции addMethod:
и таким образом селектор, идентификатор или имя элемента могут быть переданы один раз:
и валидатор ограничит валидацию элементами с этим классом только внутри каждого набора полей, вместо того, чтобы пытаться подсчитать все элементы класса .reqgrp в форме.
источник
Вот моя трещина в ответе Rocket Hazmat, пытаясь решить проблему с другими определенными полями, которые также нуждаются в проверке, но отмечая все поля как действительные при успешном заполнении одного.
Единственная оставшаяся проблема с этим сейчас - это крайний случай, когда поле пустое, затем заполнено, а затем снова пусто ... и в этом случае ошибка будет применена к одному полю, а не к группе. Но это кажется маловероятным с какой-либо частотой, и в этом случае это все еще технически работает.
источник
У меня были проблемы с другими правилами, которые не проверялись в связи с этим, поэтому я изменил:
К этому:
Я также внес несколько (личных) улучшений, и это версия, которую я использую:
источник
Спасибо, Натан. Вы сэкономили мне массу времени.
Однако я должен заметить, что это правило не готово для jQuery.noConflict (). Итак, нужно заменить все $ на jQuery, чтобы работать, скажем, с
var $j = jQuery.noConflict()
И у меня вопрос: как мне заставить его вести себя как встроенное правило? Например, если я ввожу адрес электронной почты, сообщение «Пожалуйста, введите действительный адрес электронной почты» автоматически исчезает, но если я заполняю одно из полей группы, сообщение об ошибке остается.
источник