Проверка jQuery - изменение «обязательного» атрибута на основе других полей - PullRequest
2 голосов
/ 16 ноября 2009

Я использую плагин jQuery Validation (http://docs.jquery.com/Plugins/Validation) в форме, которую я создаю. Форма состоит из 6 наборов полей, каждый из которых содержит 3 текстовых ввода для адреса электронной почты, имени и фамилия. Упрощенная версия разметки выглядит так:

<form id="ref" action="submit.php" method="post">
    <fieldset id="ref_1">
        <input id="ref_1_email" type="text" />
        <input id="ref_1_fname" type="text" />
        <input id="ref_1_lname" type="text" />
    </fieldset>
    <fieldset id="ref_2">
        <input id="ref_2_email" type="text" />
        <input id="ref_2_fname" type="text" />
        <input id="ref_2_lname" type="text" />
    </fieldset>
    <fieldset id="ref_3">
        <input id="ref_3_email" type="text" />
        <input id="ref_3_fname" type="text" />
        <input id="ref_3_lname" type="text" />
    </fieldset>
</form>

и т. Д. До ref_6. Тем не менее, пользователю не обязательно заполнять каждое поле - он может только выбрать заполнение входных данных внутри fieldset # ref_1 и fieldset # ref_2 и оставить остальные пустыми. Но если они введут, например, адрес электронной почты для ref_1, потребуется также имя и фамилия для ref_1. Поэтому мне нужно проверить все 3 входа в наборе полей. Если они все не заполнены, их можно игнорировать, однако, если один из входных данных заполнен, его два соседа также должны быть заполнены. Все мои попытки до сих пор были очень громоздкими (следя за изменениями в каждой из них, а затем оценивая, не опустели ли они ...), любая помощь будет очень, очень признательна.

Спасибо

Обновление:

Я нашел сообщение с похожей проблемой, с предлагаемым решением:

$('#emailToName2').keyup(function () {
    $('#emailToAddress2').toggleClass('required', $(this).val());
});

Но для этого требуется, чтобы вышеуказанная логика была продублирована для каждого входа, что кажется мне излишним. Какой будет более динамичный подход?

Ура!

Ответы [ 5 ]

3 голосов
/ 17 ноября 2009

Вы можете написать свой собственный класс проверки, который оценивает, был ли завершен другой из двух вводов.

например.

jQuery.validator.addMethod('MyOwnValidator', function(value, element) {
    var required = false;
    $(element).parent().children('input').each(function() {
       if($(this).val() && $(this).attr('id') != $(element).attr('id')){
           required = true;
       }
    });
    return !required;
});

Это позволит оценить, имеет ли какой-либо из родственных входов значение, и делает ли это вызывающий вход обязательным.

3 голосов
/ 16 ноября 2009

Вы можете указать выражение или обратный вызов при указании того, что поле является обязательным. Плагин проверки затем оценит выражение или обратный вызов перед проверкой поля.

Вот пример:

$("#ref").validate({
  rules: {
    ref_1_email: {
      required: function(element) {
        return $("#ref_1_fname").val() || $("ref_1_lname").val();
      }
    }
  }
});
$("#ref_1_email").blur(function() {
  $("#ref_1_fname").valid();
  $("#ref_1_lname").valid();
});

Вероятно, вы можете провести некоторый рефакторинг, чтобы вам не приходилось повторять все это для каждого поля ...

0 голосов
/ 06 октября 2011

Просто исследовал это для проекта. Согласно документации, следующее должно делать то, что вы хотите.

При первом вызове validate в вашей форме, сделайте это так:

$("#emailRecsForm").validate({
   rules: {
       ref_1_email: {
         required: ("#ref_1_fname:filled" || "#ref_1_lname:filled"),
         email: true
       },
       ref_1_fname: {
         required: ("#ref_1_email:filled" || "#ref_1_lname:filled")
       },
       ref_1_lname: {
         required: ("#ref_1_email:filled" || "#ref_1_fname:filled")
       },

       ref_2_email: {
         required: ("#ref_2_fname:filled" || "#ref_2_lname:filled"),
         email: true
       },
       // And so on...
   }
});

Также убедитесь, что у каждого из ваших input s есть атрибут name, идентичный его id.

Я сам на самом деле не пробовал, но, судя по документам (см. required(dependency-expression)), должно работать.

0 голосов
/ 18 ноября 2009

Вы не можете сделать все это в одном цикле, так как вам нужно проверить братьев и сестер, прежде чем переключать класс. Однако вы можете определить небольшую функцию цикла, которая может проверять и применять, но вам придется вызывать ее несколько раз для поддержания логики.

Попробуйте это:

var loop = function(target, fn) {
    var t = 0, fn = fn || function(){};
    $(target).siblings().andSelf().each(function(i, el) {
        t += $(el).val().length;
        fn(el);
    });
    return t;
}
$('fieldset input').each(function() {
    $(this).bind('blur', function(e) {
        if(loop(e.target)) {
            loop(e.target, function(el) {
                $(el).toggleClass('required', !$(el).val().length);
            })
        } else {
            loop(e.target, function(el) {
                $(el).removeClass('required');
            })
        }
    });
});
0 голосов
/ 16 ноября 2009

Не пробовал и не правильно написал:

$("#ref input").keyup(function () {
 $(this).parents("fieldset").children("input").toggleClass("required", $(this).val());
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...