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'));
});