LoginSignup
1
0

More than 5 years have passed since last update.

Angular7とBootstrap4でラジオボタンの実装が意外に大変だった件について

Posted at

Angular7とBootstrap4を使ってサイトを開発しています。
両者については、なんとなく掴んだ感が出てきていたのですが、性別をラジオボタンで実装するのに、意外と手間取りました。
インターネットを調べてもあまり参考になるものが出てこなかったのですが、こういうのはフロント開発の方にすれば普通のことなんでしょうか。

目指したもの

通常ラジオボタンと言えば、これです。
sex1.png

これでも支障はないんです。でも、今時ってこんな感じの方がかっこいいですよね?
sex2.png

実装してみましょう

かっこいい方を実装するためには、data-toggleというものを使うといいらしいのです。そこで以下のように実装しました。

signin.component.pug
.row
    .col-lg-4
        p.labeltext 性別
    .col-lg-8
        .btn-group.btn-group-toggle.form-control(data-toggle="sexbuttons")
            label.btn.btn-sm.btn-outline-secondary
                input.sr-only(type="radio" name="sex" id="man" autocomplete="off" '[value]'="0" '[(ngModel)]'="model.sex" '#sex'="ngModel" required '(change)'="model.sex=0" '[checked]'="model.sex===0")
                | 男性
            label.btn.btn-sm.btn-outline-secondary
                input.sr-only(type="radio" name="sex" id="woman" autocomplete="off" '[value]'="1" '[(ngModel)]'="model.sex" '#sex'="ngModel" required '(change)'="model.sex=1" '[checked]'="model.sex===1")
                | 女性

これだと、かっこいいラジオボタンとしては表示されるのですが、クリックしても黒くなりません。

クリックしたら切り替わる実装

原因は、data-toggleの指定でした。buttonsって決まってるんですね。

signin.component.pug
.row
    .col-lg-4
        p.labeltext 性別
    .col-lg-8
        .btn-group.btn-group-toggle.form-control(data-toggle="buttons")
            label.btn.btn-sm.btn-outline-secondary
                input.sr-only(type="radio" name="sex" id="man" autocomplete="off" '[value]'="0" '[(ngModel)]'="model.sex" '#sex'="ngModel" required '(change)'="model.sex=0" '[checked]'="model.sex===0")
                | 男性
            label.btn.btn-sm.btn-outline-secondary
                input.sr-only(type="radio" name="sex" id="woman" autocomplete="off" '[value]'="1" '[(ngModel)]'="model.sex" '#sex'="ngModel" required '(change)'="model.sex=1" '[checked]'="model.sex===1")
                | 女性

クリックした方が黒くなる!よしよし。
双方向データバインディングをしているのですが、クリックした方の値が設定されません。
ラジオボタンとしては完璧なはずだ。本にもそう書いてある。
うーん。

その正体はラベルにあった

かっこいいラジオボタンって、コントロール的にはラジオボタンをクリックしている訳ではないのです。なんとラベルをクリックしていたのです!
ということは、このように実装すれば行けるはず。

signin.component.pug
.row
    .col-lg-4
        p.labeltext 性別
    .col-lg-8
        .btn-group.btn-group-toggle.form-control(data-toggle="buttons")
            label.btn.btn-sm.btn-outline-secondary('(click)'="model.sex=0" '[class.active]'="model.sex===0")
                input.sr-only(type="radio" name="sex" id="man" autocomplete="off" '[value]'="0" '[(ngModel)]'="model.sex" '#sex'="ngModel" required)
                | 男性
            label.btn.btn-sm.btn-outline-secondary('(click)'="model.sex=1" '[class.active]'="model.sex===1")
                input.sr-only(type="radio" name="sex" id="woman" autocomplete="off" '[value]'="1" '[(ngModel)]'="model.sex" '#sex'="ngModel" required)
                | 女性

つまりラベルの方のclickイベントで値を設定するのと、値に合わせてactiveクラスを追加するかどうかを決めます。

奥が深い・・・。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0