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

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

ただいまの
回答率

90.61%

  • Bootstrap

    922questions

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

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

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 6,078

chimotimo

score 1

<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"を使用しています。
既に選択されているボタンを選択した場合に、
そのボタンを未選択状態にする(リセットする)には、
どうすればいいでしょうか。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

どこまで トライされたか 書かれたほうがよかったかと思います。
ともあれ、わたしも最近似たようなことをしたので やってみました。
    $('input:radio[name=hogehoge]').parent('.btn').click(function (e) {
        var face = $(this),
            rbtn = $('input:radio', face),
            b = (rbtn.is(':checked')) ? true : false;
        if (b) {//元々チェックされていたら、全部リセットしましょう。
            setTimeout(function () {
                face.removeClass('active');
                rbtn.attr('checked', false);
            }, 0);
        }
    });
(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/11 15:07

    丁寧にご説明いただきありがとうございました。

    なるほどー、setTimeout(f, 0)ですか。
    確かに管理が大変そうですね。。。
    検討してみます。

    radio2回押しキャンセルついては、チーム内でも揉めました。
    ただ、通常のradioボタンであれば、
    2回押しでキャンセルされるのは違和感があるけれども、
    この場合は見かけ上ボタンになっているので、さほど違和感ないのではないかということで、
    一旦紙芝居で作って、ユーザーに体感テストしてもらうことになったというのが経緯です。
    いざやってみようとすると思いのほか苦戦して、質問させていただきました。

    また、質問に至るまでどこまでトライしたかなのですが、
    >1.すでに選ばれているradioボタンをまた選んでも radioボタンのchangeイベントは発火しない。
    >2.上位の".btn" label のclickイベントで 何かすればよい。
    ここまではchormeのデベロッパーツールを使用して、何とかわかりました。
    しかし、clickイベントでやってみてもうまくいかない。。

    この先の、『Button.prototype.toggle メソッドで
    「もし activeでなく checked属性も設定されていなければ、
    changeイベントを発火する」とやっている』というのはどのような思考プロセスで、
    たどり着くものなのでしょうか。
    後学のためにご教示いただければ幸いです。

    キャンセル

  • 2015/05/11 16:14

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

    キャンセル

  • 2015/05/19 00:53

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

    キャンセル

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

  • ただいまの回答率 90.61%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Bootstrap

    922questions

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