Twitter Bootstrap получает состояние группы кнопок-флажков

Есть несколько вопросов, связанных с группами переключателей / флажков Twitter Bootstrap, но ни один из них не касается нового соглашения Bootstrap (я использую v3.3.4) или моего решения моего вопроса.

Старая конвенция была объявить <div class="btn-group"> что окружало ряд <button> и окружающий див также имел data-toggle атрибут либо buttons-checkbox или же buttons-radio выглядеть примерно так:

<div class="btn-group" data-toggle="buttons-checkbox">
    <button type="button" class="btn btn-primary">Btn 1</button>
    <button type="button" class="btn btn-primary">Btn 2</button>
    <button type="button" class="btn btn-primary">Btn 3</button>
</div>

Однако соглашение о создании таких групп изменилось, что можно увидеть на странице Bootstrap Javascript для кнопок ( http://getbootstrap.com/javascript/):

<div class="btn-group" data-toggle="buttons">
  <label class="btn btn-primary active">
    <input type="checkbox" autocomplete="off" checked> Checkbox 1 (pre-checked)
  </label>
  <label class="btn btn-primary">
    <input type="checkbox" autocomplete="off"> Checkbox 2
  </label>
  <label class="btn btn-primary">
    <input type="checkbox" autocomplete="off"> Checkbox 3
  </label>
</div>

Как вы можете видеть, кнопки теперь фактически являются метками с дочерними полями ввода типа checkbox или же radio которые оформлены в стиле кнопок.

Я хотел бы создать .on('click') событие, которое фиксирует состояние только что нажатой кнопки, однако логика, которая следует за ней, странным образом задом наперед (и реализация этого в Javascript, по-видимому, неполна, по крайней мере, на мой взгляд - объяснение, которому нужно следовать). Скажем, я хотел бы настроить прослушиватель для второй метки / флажка / кнопки и определить, активна ли / помечена ли метка / флажок / кнопка - я бы настроил следующий код:

$('#label2').on('click', function(){
  console.log($(this).hasClass('active'));
});

Я ожидаю, что приведенный выше код, когда кнопка была нажата, чтобы "активировать" ярлык / флажок / кнопку, чтобы напечатать true на консоль. Это печатает ложь. Это потому что .on('click') слушатель срабатывает до изменения состояния кнопки, и поэтому мне придется инвертировать логику для любых действий, которые я хотел бы предпринять, основываясь на состоянии кнопки. Кажется назад для меня. (Иллюстрация jsFiddle: http://jsfiddle.net/mmuelle4/qq816po7/)

Существуют и другие библиотеки, которые используют этот "разумный" способ, например, библиотека Bootstrap Switch ( http://www.bootstrap-switch.org/). Библиотека Bootstrap Switch имеет switchChanged событие, которое ловит изменение переключателя после щелчка, но предоставляет состояние кнопки / флажка после щелчка.

Я думал, что нашел решение, зарегистрировав .on('change') обработчик, а не .on('click') обработчик, но я получил тот же результат.

Кроме того, если <label> нажата, вложенная <checkbox> никогда не устанавливает / отменяет checked собственность - давай Bootstrap! Зачем даже использовать флажок, если состояние инертно? Похоже, довольно явный случай несоответствия, когда <label> может иметь класс active но <checkbox> не иметь checked набор атрибутов... (это то, что я имел в виду ранее, когда говорил, что реализация этого на Javascript выглядит неполной)

Сейчас мне просто нужно инвертировать логику в моем обработчике, но это просто раздражает меня. В целом, я предполагаю, что мой вопрос: кто-нибудь сталкивался с этим и нашел лучшее решение (все еще просто использующее jQuery и Bootstrap, без альтернативных библиотек), которое не требует инвертированной логики?

РЕДАКТИРОВАТЬ: есть решение ниже, но мой комментарий о <checkbox> не имея checked Атрибут породил немного другой вопрос / обсуждение. Можно выполнить .is(':checked') запрос на вложенном <checkbox> чтобы получить правильное состояние в .on('change') обработчик, но если вы проверяете DOM, этот атрибут фактически никогда не устанавливается на <checkbox>, Меня беспокоит, что DOM не отражает состояние, которое я получу с .is(':checked') запрос...

РЕДАКТИРОВАТЬ 2: Еще одна странная вещь, которую я обнаружил, это то, что с уходом от использования <button> Для группы кнопок радио или чекбокса необходимо принять различные меры для извлечения и изменения некоторых свойств "искусственных" кнопок. В моем случае я хотел бы отключить / включить кнопки на основе различных пользовательских вводов, но установив disabled свойство флажка не работает:

$('input').prop('disabled', true) //Doesn't render the button disabled

Это потому, что кнопка теперь на самом деле <input> содержится в <label> который стилизован под кнопку, так что теперь disabled должен быть установлен на <label>, Это немного расстраивает, но не слишком сложно сделать с помощью jQuery .parent() метод (потому что я храню указатель на вход). Что расстраивает, так это то, что в случае кнопки я могу использовать .prop('disabled', true/false) способ изменить disabled собственность, но я не могу сделать то же самое, потому что теперь это <label>,

Это описано в jQuery's attr документация ( http://api.jquery.com/attr/), "Для извлечения и изменения свойств DOM, таких как проверенное, выбранное или отключенное состояние элементов формы, используйте метод.prop()". <button> по-видимому, элемент формы, в то время как <label> нет (хотя я бы подумал, что так и будет). Теперь в моем коде я должен сознательно помнить, чтобы использовать .prop('disabled', true/false) для настоящих кнопок и .attr('disabled', true/false) для искусственных кнопок. Мне бы хотелось увидеть, как Bootstrap отходит от обычных кнопок... (и, может быть, это такие вещи, как .is(':checked') может работать, но это, безусловно, делает для некоторых других головных болей...)

EDIT3: только что узнал, что после "нового соглашения" использования <input> завернутый в <label> не требуется. Вы по-прежнему можете использовать кнопку, и ожидаемое поведение радио / флажка... так много головной боли даром. Почему бы тебе не показать оба варианта, Bootstrap???

1 ответ

Решение

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

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

$('label > input[type=checkbox]').on('change', function () {
    console.log($(this).is(':checked'));
});

ДЕМО: http://jsfiddle.net/qq816po7/1/

Другие вопросы по тегам