2015-04-15 13 views
11

Istnieje kilka pytań związanych z grupami przycisków Boot na Twitterze, ale żaden z nich nie wydaje się być zgodny z nową konwencją Bootstrap (używam wersji 3.3.4) lub moją odpowiedzią na moje pytanie.Twitter Bootstrap otrzymujący stan pola wyboru grupy przycisków

Stary Konwent zadeklarować <div class="btn-group"> że pośród wielu <button> „s, a otaczająca div miał również atrybut data-toggle z obu buttons-checkbox lub buttons-radio aby wyglądać mniej więcej tak:

<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> 

jednak Konwencja o tworzenie tego rodzaju grup zmienił się, jak można zobaczyć na stronie Bootstrap JavaScript dla przycisków (http://getbootstrap.com/javascript/#buttons-checkbox-radio):

<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> 

Jak widać, przyciski są teraz w rzeczywistości etykietami z podrzędnymi polami wejściowymi typu checkbox lub radio, które mają wyglądać jak przyciski.

Chciałbym założyć .on('click') zdarzenie rejestruje stan przycisku, który właśnie został kliknięty, jednak logika że następuje to dziwnie tyłu (i wdrożenie Javascript tego jest pozornie niepełne, przynajmniej w moich oczach - - wyjaśnienie do naśladowania). Powiedzmy, chciałbym założyć słuchacza na etykiecie/przycisk/drugiego wyboru i określić, czy przycisk/label/pole jest aktywne/sprawdzane - ja założyć następujący kod:

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

Spodziewam się powyższego kodu, gdy przycisk został naciśnięty, aby "aktywować" etykietę/pole wyboru/przycisk, aby wydrukować true na konsolę. Drukuje fałsz. Wynika to z faktu, że detektor .on('click') zostaje wywołany przed zmianą stanu przycisku, a zatem musiałbym odwrócić logikę dla wszelkich działań, które chciałbym podjąć na podstawie stanu przycisku. Wydaje mi się, że jest odwrotnie. (JsFiddle ilustracji: http://jsfiddle.net/mmuelle4/qq816po7/)

Istnieje kilka innych bibliotek tam, że zapadki to „rozsądny” sposób, takie jak biblioteki Przełącznik Bootstrap (http://www.bootstrap-switch.org/). Biblioteka Switch Bootstrap ma zdarzenie switchChanged, które przechwytuje zmianę przełącznika po kliknięciu, ale podaje stan przycisku/pola wyboru po kliknięciu.

Pomyślałem, że znalazłem rozwiązanie, rejestrując instrukcję obsługi .on('change'), a nie obsługującą .on('click'), ale otrzymałem ten sam wynik.

Ponadto, jeśli kliknięto na <label>, zagnieżdżony <checkbox> nigdy nie ustawia/nie resetuje właściwości checked - c'mon Bootstrap! Dlaczego warto korzystać z pola wyboru, jeśli stan jest obojętny? Wydaje się całkiem oczywistym przypadkiem niespójności, w którym <label> może mieć klasę active, ale <checkbox> nie ma zestawu atrybutów checked ... (co miałem na myśli wcześniej, kiedy powiedziałem, że implementacja JavaScript jest pozornie niekompletna)

Na razie muszę po prostu odwrócić logikę w moim treserze, ale to tylko irytuje mnie. Ogólnie rzecz biorąc, myślę, że moje pytanie jest ktoś doświadczył tego i znalazł lepsze rozwiązanie (nadal tylko przy użyciu jQuery i Bootstrap, brak alternatywnych bibliotek), który nie wymaga odwróconej logiki?

EDIT: Jest poniżej rozwiązanie, ale mój komentarz o <checkbox> nie posiadające atrybut checked zrodził nieco inne pytanie/dyskusji. Można wykonać zapytanie .is(':checked') na zagnieżdżonym <checkbox>, aby uzyskać poprawny stan w obsłudze .on('change'), ale jeśli sprawdzasz DOM, atrybut ten nigdy nie jest faktycznie ustawiony na <checkbox>. Martwi mnie, że DOM nie odzwierciedla stan, który otrzymam z kwerendy .is(':checked') ...

EDIT2: Kolejny dziwny kaprys, że odkryłem jest, że wraz z odejściem z użyciem <button> „s dla radio lub grupa przycisków wyboru, należy podjąć różne działania w celu pobrania i zmiany niektórych właściwości przycisków "faux". W moim przypadku, chciałbym włączyć/wyłączyć przyciski na podstawie różnych wejść użytkowników, ale ustawiając właściwość wyboru disabled nie działa:

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

To dlatego, że przycisk jest teraz faktycznie <input> zawarte wewnątrz <label>, który jest stylizowany jako przycisk, więc teraz disabled musi być ustawiony na <label>. To trochę frustrujące, ale niezbyt trudne do zrobienia przy użyciu metody jQuery .parent() (ponieważ przechowuję wskaźnik na wejściu). Frustrujące jest to, że w przypadku przycisku mogę użyć metody .prop('disabled', true/false), aby zmienić właściwość disabled, , ale nie mogę zrobić tego samego, ponieważ teraz jest to<label>.

Jest to opisane w attr dokumentacji jQuery (http://api.jquery.com/attr/) „aby odzyskać i zmienić właściwości DOM takie jak sprawdzone, Wybrane lub stan disabled elementów formularza, użyj metody .prop().” A <button> jest najwyraźniej elementem formy, podczas gdy <label> nie jest (chociaż wydaje mi się, że będzie). Teraz w moim kodzie muszę świadomie pamiętać o użyciu przycisków .prop('disabled', true/false) i .attr('disabled', true/false) dla przycisków faux. Chciałbym zobaczyć rozumowanie Bootstrap dla dokonywania odejście od zwykłych przycisków ... (a może to jest tak, że takie rzeczy jak .is(':checked') może pracować, ale na pewno sprawia, że ​​dla niektórych innych bólów głowy ...)

Edit3: Właśnie dowiedziałem się, że po "nowej konwencji" używania <input> w opakowaniu <label> 's jest niewymagany. Nadal możesz użyć przycisku i spodziewane zachowanie radio/checkbox nastąpi ... tyle bólu głowy za nic. Dlaczego nie popisałbyś się dwiema opcjami, Bootstrap ???

Odpowiedz

7

Pasek startowy już zajmuje się wyzwalaniem zdarzeń na oryginalnych elementach, które się konwertują. Więc nie musisz się martwić o sprawdzanie klasy.

Wszystko co musisz zrobić, to ustawić na wydarzenia w oryginalnym wejściu i sprawdzić stan tego pierwotnego wejścia

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

DEMO: http://jsfiddle.net/qq816po7/1/

+0

Great! To jest tak proste, jak powinno być, ale (może to moje oczy) Nie widziałem tego w ogóle w dokumentacji Bootstrap! Najwyraźniej moje testy nie były dokładne, ponieważ zaznaczony atrybut został ustawiony ...Mógłbym przysiąc, że widziałem, jak siedział tam, nie zmieniając się ... tak czy owak - dzięki! – MandM

+0

Właściwie, jestem pewien, że widziałem, że siedział tam, nie zmieniając się! W chrome, jeśli otworzysz narzędzia programistyczne w połączonym jsfiddle i przejrzysz etykietę/checkbox, nigdy nie ma atrybutu checkbox, który zostanie zastosowany do . Właśnie dlatego założyłem (wiem, że wiem, nigdy nie zakładam), że test '.is (": checked ") zwróci false. Jaka czarna magia się tutaj dzieje? – MandM

+0

Tak, również sprawdziłem, czy to się nie zmienia, ale to nie znaczy, że nie robią czegoś w JS, aby utrzymać je w synchronizacji. –

Powiązane problemy