Включение и отключение переключателей в зависимости от выбора пользователя

Я хочу написать jQuery, чтобы включить только переключатели в зависимости от того, какие переключатели в настоящее время выбраны в соответствии с некоторой бизнес-логикой.

По сути, есть 3 группы из 3 переключателей, которые в конечном итоге выглядят примерно так (извините за многословие с этим примером HTML, но надеюсь, что это покажет, что я имею в виду):

<p>
  <label for="group_one">Group One</label>
</p>
<p>
  <div class="group_one">
    <div id="group_one_choice_one">
      <label for="group_one_choice_one">Choice One</label>
      <br />
      <input checked="checked" id="choice_one" type="radio" value="1" />
      <br />
    </div>
    <div id="group_one_choice_two">
      <label for="group_one_choice_two">Choice Two</label>
      <br />
      <input id="group_one_choice_two" type="radio" value="2" />
      <br />
    </div>
    <div id="group_one_choice_three">
      <label for="group_one_choice_three">Choice Three</label>
      <br />
      <input id="choice_three" type="radio" value="3"/ >
      <br />
    </div>
  </div>
</p>
<p>
  <label for="group_two">Group Two</label>
</p>
<p>
  <div class="group_two">
    <div id="group_two_choice_one">
      <label for="group_two_choice_one">Choice One</label>
      <br />
      <input checked="checked" id="choice_one" type="radio" value="1" />
      <br />
    </div>
    <div id="group_two_choice_two">
      <label for="group_two_choice_two">Choice Two</label>
      <br />
      <input id="group_two_choice_two" type="radio" value="2" />
      <br />
    </div>
    <div id="group_two_choice_three">
      <label for="group_two_choice_three">Choice Three</label>
      <br />
      <input id="choice_three" type="radio" value="3"/ >
      <br />
    </div>
  </div>
</p>
<p>
  <label for="group_three">Group Three</label>
</p>
<p>
  <div class="group_three">
    <div id="group_three_choice_one">
      <label for="group_three_choice_one">Choice One</label>
      <br />
      <input checked="checked" id="choice_one" type="radio" value="1" />
      <br />
    </div>
    <div id="group_three_choice_two">
      <label for="group_three_choice_two">Choice Two</label>
      <br />
      <input id="group_three_choice_two" type="radio" value="2" />
      <br />
    </div>
    <div id="group_three_choice_three">
      <label for="group_three_choice_three">Choice Three</label>
      <br />
      <input id="choice_three" type="radio" value="3"/ >
      <br />
    </div>
  </div>
</p>

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

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

Если пользователь должен был сначала выбрать (например) вариант «2» в группе «3», сценарий должен затем отключить вариант «2» как в группе «1», так и в группе «2». Если затем пользователь выбирает вариант «3» в группе «2», он должен включить вариант «1» только в группе «1» и так далее.

Любая помощь будет очень, очень признательна. Я бы опубликовал jQuery, который я пытался написать, чтобы решить эту проблему, но я не думаю, что очень хорошо справлялся с этим, и мне бы понравилась любая помощь в решении этой проблемы. Спасибо!


person btw    schedule 23.08.2009    source источник
comment
Проблема (?) с этим подходом заключается в том, что после того, как я сделал свой выбор, я не могу передумать, так как все кнопки отключены. Так хотя бы добавь кнопку очистки.   -  person Zed    schedule 23.08.2009
comment
Вы уверены, что ответом здесь являются радиокнопки, а не флажки?   -  person James Wiseman    schedule 23.08.2009


Ответы (5)


Я бы пропустил специальные занятия.

$("input[type=radio]").click(function() { 
  $("input[type=radio][value=" + $(this).val() + "]").attr("disabled", "disabled"); 
  $(this).removeAttr("disabled"); 
});

В зависимости от ваших требований вам может не понадобиться последняя строка — она просто повторно включает текущее радио. В вашем html также отсутствуют имена для ваших переключателей.

person Andy Gaskell    schedule 23.08.2009

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

Идея такова: всякий раз, когда вы нажимаете на радиостанцию, отключайте все радиостанции во всех группах с этим значением, кроме той, которая только что была нажата.

$(document).ready(function() {
    $("input[type=radio]").click(function() {
        var val = $(this).val();
        var $all_radios = $("input[type=radio]").filter("[value=" + val + "]");
        $all_radios.not($(this)).attr('disabled', 'disabled');
        return true;
    });
});
person JJ Geewax    schedule 23.08.2009

Сделано и протестировано, вот jQuery:

$(document).ready(function() {
    $('input:radio').click(function() {
       //reset all the radios
       $('input:radio').removeAttr('disabled');
       if($(this).is(':checked')) {
           var val = $(this).val();
           //disable all the ones with the same value
           $('input:radio').each(function() {
               if(val == $(this).val()) {
                   $(this).attr('disabled',true);
               }
           });
           //let's not disable the one we have just clicked on
           $(this).removeAttr('disabled');
       }
    });
});

и модифицированная разметка:

<p>
  <label for="group_one">Group One</label>
</p>
<p>
  <div class="group_one">
    <div>
      <label for="group_one_choice_one">Choice One</label>
      <br />
      <input checked="checked" name="group_one" type="radio" value="1" />
      <br />
    </div>
    <div>
      <label for="group_one_choice_two">Choice Two</label>
      <br />
      <input name="group_one" type="radio" value="2" />
      <br />
    </div>
    <div>
      <label for="group_one_choice_three">Choice Three</label>
      <br />
      <input name="group_one" type="radio" value="3"/ >
      <br />
    </div>
  </div>
</p>
<p>
  <label for="group_two">Group Two</label>
</p>
<p>
  <div class="group_two">
    <div>
      <label for="group_two_choice_one">Choice One</label>
      <br />
      <input checked="checked"  name="group_two"  type="radio" value="1" />
      <br />
    </div>
    <div>
      <label for="group_two_choice_two">Choice Two</label>
      <br />
      <input name="group_two" type="radio" value="2" />
      <br />
    </div>
    <div>
      <label for="group_two_choice_three">Choice Three</label>
      <br />
      <input name="group_two" type="radio" value="3"/ >
      <br />
    </div>
  </div>
</p>
<p>
  <label for="group_three">Group Three</label>
</p>
<p>
  <div class="group_three">
    <div>
      <label for="group_three_choice_one">Choice One</label>
      <br />
      <input checked="checked" name="group_three" type="radio" value="1" />
      <br />
    </div>
    <div>
      <label for="group_three_choice_two">Choice Two</label>
      <br />
      <input name="group_three" type="radio" value="2" />
      <br />
    </div>
    <div>
      <label for="group_three_choice_three">Choice Three</label>
      <br />
      <input name="choice_three" type="radio" value="3"/ >
      <br />
    </div>
  </div>
</p>

Изменения в разметке:

  • Избавился от внутренних DIV IDов.
  • Изменены атрибуты ID радиостанций на NAME, чтобы они вели себя как радиокнопки.
person karim79    schedule 23.08.2009

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

Я бы сделал все идентификаторы уникальными, а затем дал бы вашим радиобоксам имя класса - например, class="choice_three".

Вы можете дать своим div идентификатор, выбор по идентификатору быстрее, чем по классу, например, id="group_three".

Затем, чтобы выбрать переключатель, просто используйте следующий код:

$("#group_three .choice_three").attr("disabled", "disabled");

Обратите внимание, что расстояние между #group_three и .choice_three важно.

Или еще быстрее:

$("#group_three input:radio.choice_three").attr("disabled", "disabled");

Также следует отметить, что метка «для» должна быть для переключателя, а не для div.

person James Wiseman    schedule 23.08.2009
comment
Поскольку я сам новичок в jQuery, не могли бы вы сказать мне, что означает сегмент .attr("disabled, "disabled");? - person David says reinstate Monica; 23.08.2009
comment
Таким образом вы можете отключить атрибут - person James Wiseman; 23.08.2009
comment
@ Джеймс, спасибо, ... есть ли причина, по которой "disabled" появляется дважды? - person David says reinstate Monica; 23.08.2009
comment
Да, когда вы отключаете элемент в HTML, правильная разметка отключена = отключена. В jQuery .attr() может принимать 2 параметра: имя атрибута и значение атрибута. В приведенном выше примере мы устанавливаем для атрибута disabled значение disabled. - person James Wiseman; 24.08.2009

Если вы добавите специальные классы к одному и тому же выбору, например. class="choice_one", а затем в обработчике событий вы можете:

if ($this).hasClass("choice_one") { $(".choice_one").attr("disabled", "disabled"); }
else if ($this).hasClass("choice_two") { ... }
...
person Zed    schedule 23.08.2009