質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Bootstrap

BootstrapはウェブサイトデザインやUIのWebアプリケーションを素早く 作成する可能なCSSフレームワークです。 Twitter風のデザインを作成することができます。

Q&A

解決済

1回答

12007閲覧

bootstrap3でdata-toggle="buttons"使用時のラジオボタンリセット

chimotimo

総合スコア6

Bootstrap

BootstrapはウェブサイトデザインやUIのWebアプリケーションを素早く 作成する可能なCSSフレームワークです。 Twitter風のデザインを作成することができます。

0グッド

0クリップ

投稿2015/05/06 15:47

編集2015/05/06 22:55
<div class="btn-group" data-toggle="buttons" id="hoge"> <label class="btn btn-default"> <input type="radio" name="hogehoge" value="a">A </label> <label class="btn btn-default"> <input type="radio" name="hogehoge" value="b">B </label> <label class="btn btn-default"> <input type="radio" name="hogehoge" value="c">C </label> </div>

上記のように、bootstrap3でdata-toggle="buttons"を使用しています。
既に選択されているボタンを選択した場合に、
そのボタンを未選択状態にする(リセットする)には、
どうすればいいでしょうか。

リセットボタンやリンクを設置してリセットすることはできたのですが、
チェックボックスのように、選択済みボタンをクリックすると
リセットされるようにしたいのです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

どこまで トライされたか 書かれたほうがよかったかと思います。
ともあれ、わたしも最近似たようなことをしたので やってみました。

lang

1 $('input:radio[name=hogehoge]').parent('.btn').click(function (e) { 2 var face = $(this), 3 rbtn = $('input:radio', face), 4 b = (rbtn.is(':checked')) ? true : false; 5 if (b) {//元々チェックされていたら、全部リセットしましょう。 6 setTimeout(function () { 7 face.removeClass('active'); 8 rbtn.attr('checked', false); 9 }, 0); 10 } 11 });

(Firefox, Chrome, IE11 で動作検証済み)

ポイントは、
1.radioボタンのchangeイベントは、その上層の ".btn" labelの clickイベントより
あとに起きる。
2.changeイベントは、checked 属性が trueになるという変更が起きない限り 発火しない。

ということです。
これらを今回の問題にかんがみて整理すると、

1.すでに選ばれているradioボタンをまた選んでも radioボタンのchangeイベントは発火しない。
2.上位の".btn" label のclickイベントで 何かすればよい。

でよさそうです。がしかし。

3.bootstrap3 でも 同じタイミング、つまり ".btn" label のclickイベントで、
「もし activeでなく checked属性も設定されていなければ、changeイベントを発火する」、
とやっている。(Button.prototype.toggle メソッド)
しかもこれは オリジナル実装するclickイベントのロジックより"後に"処理が行われる。
(というのも document の onメソッド内で実行されているので)
したがって、頑張って 全部リセットしても、イベントが伝播して新たにクリックされたのと
同じ現象が起きる。

というわけで、うまくいかないのです。
そこで、bootstrap3の処理をかいくぐらなければいけないのですが、
e.preventDefault ではイベントは伝播しますのでうまくいかず、
e.stopPropagation では イベントは伝播しなくなるのでいいのですが、
bootstrap3は focusクラスの管理などいろいろやってますので、諸々きれいに処理できない。
また、documentより上位のオブジェクトもないので、ここをごちゃごちゃするのもうまくいかない。

というわけで、0ms後の setTimeout を使うことになります。
これは、「現在の実行行列が終了時に 0msで処理を追加する」ことを意味します。
今回の文脈では、「一通りのブラウザで起きている現在のイベント処理完了後に実行」ということに
なりますね。全部終わってからリセット処理をする、ということです。


ただ、setTimeout(f, 0) パターンは 便利なのですが、非常に管理しにくいので、
本当は余りお勧めしません。ごくごく限るか、ちゃんと管理台帳をつけるか しないと
後で 追えなくなってしまいます。

もう一つ。radioボタンの2回押しでの リセット は ユーザ体験として メジャーでないぶん
直観的ではなくなる危険性があるということにご注意ください。
わたしなら、こういう場合は、選択肢として「それ以外」とか「該当なし」を用意しておいて
それをデフォルトとしてactiveにする、という手法をとると思います。

投稿2015/05/09 07:25

編集2015/05/09 07:35
okayu3

総合スコア200

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

chimotimo

2015/05/11 06:07

丁寧にご説明いただきありがとうございました。 なるほどー、setTimeout(f, 0)ですか。 確かに管理が大変そうですね。。。 検討してみます。 radio2回押しキャンセルついては、チーム内でも揉めました。 ただ、通常のradioボタンであれば、 2回押しでキャンセルされるのは違和感があるけれども、 この場合は見かけ上ボタンになっているので、さほど違和感ないのではないかということで、 一旦紙芝居で作って、ユーザーに体感テストしてもらうことになったというのが経緯です。 いざやってみようとすると思いのほか苦戦して、質問させていただきました。 また、質問に至るまでどこまでトライしたかなのですが、 >1.すでに選ばれているradioボタンをまた選んでも radioボタンのchangeイベントは発火しない。 >2.上位の".btn" label のclickイベントで 何かすればよい。 ここまではchormeのデベロッパーツールを使用して、何とかわかりました。 しかし、clickイベントでやってみてもうまくいかない。。 この先の、『Button.prototype.toggle メソッドで 「もし activeでなく checked属性も設定されていなければ、 changeイベントを発火する」とやっている』というのはどのような思考プロセスで、 たどり着くものなのでしょうか。 後学のためにご教示いただければ幸いです。
okayu3

2015/05/11 07:14

いや、ソースを見ただけですよ(笑)。もう少し詳しく言うと、 bootstrapは、radioボタンを隠して、その手前にボタン風のものをCSSで描画させていますよね。ということは、radioボタンのイベントは発火するはずないのですが実際には発生している。ということは、triggerがどこかにある。どこだろう。と思ってBootstrapのソースを見た、ということですね。
chimotimo

2015/05/18 15:53

返信が遅くなってしまい申し訳ありません。 丁寧にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問