Twitter Bootstrap 4 では、サーバーサイドでチェックした入力エラーのメッセージを表示するための「invalid-feedback」クラスが用意されており、 項目ごとに分かりやすく表示されるようになっています。
しかしながら、ラジオボタンやチェックボックスで選択肢が複数ある場合に、 公式サイトの説明 の通りにHTMLを出力しても、期待通りにならないことがありました。
その場合への対処方法をご紹介します。
例えば、次のような「お名前」欄があり、エラーチェックの前後で下図のようにエラーメッセージが表示されると分かりやすいですね。
エラーチェック前
エラーチェック後HTMLの構造も比較してみましょう。
赤文字が追加になった部分です。
<div class="form-group row"> <label class="col-sm-3 col-form-label">お名前</label> <div class="col-sm-9"> <input type="text" name="name" class="form-control" value=""> </div> </div>
<div class="form-group row"> <label class="col-sm-3 col-form-label">お名前</label> <div class="col-sm-9"> <input type="text" name="name" class="form-control is-invalid" value=""> <div class="invalid-feedback">お名前が入力されていません。</div> </div> </div>【修正方法】
ここまでは問題なくスマートに表示されていますね。
次に、複数の選択肢を持つラジオボタンについて見てみましょう。
公式サイトの説明 の通りに、<input>タグに「is-invalid」クラスを記述して、その兄弟要素として「invalid-feedback」クラスを持つ<div>タグでエラーメッセージを指定します。
エラーチェック前
エラーチェック後 あれ???かなり残念なことになっています…。
では、HTMLの構造も比較してみましょう。
実際には、各選択肢はPHPなどでループして出力していますが、上記の【修正方法】である、
は変えておらず、HTMLの構造は同様です。
なお、下の例ではcustom-controlを使用していますが、標準のformでも同じです。
<div class="form-group row"> <label class="col-sm-3 col-form-label">性別</label> <div class="col-sm-9"> <div class="custom-control custom-radio custom-control-inline"> <input class="custom-control-input" type="radio" name="sex[]" id="form_sex_10" value="10" /> <label class="custom-control-label" for="form_sex_10" id="form_sex_10">男性</label> </div> <div class="custom-control custom-radio custom-control-inline"> <input class="custom-control-input" type="radio" name="sex[]" id="form_sex_20" value="20" /> <label class="custom-control-label" for="form_sex_20" id="form_sex_20">女性</label> </div> <div class="custom-control custom-radio custom-control-inline"> <input class="custom-control-input" type="radio" name="sex[]" id="form_sex_30" value="30" /> <label class="custom-control-label" for="form_sex_30" id="form_sex_30">回答しない</label> </div> </div> </div>
<div class="form-group row"> <label class="col-sm-3 col-form-label">性別</label> <div class="col-sm-9"> <div class="custom-control custom-radio custom-control-inline"> <input class="custom-control-input is-invalid" type="radio" name="sex[]" id="form_sex_10" value="10" /> <label class="custom-control-label" for="form_sex_10" id="form_sex_10">男性</label> <div class="invalid-feedback">性別が選択されていません。</div> </div> <div class="custom-control custom-radio custom-control-inline"> <input class="custom-control-input is-invalid" type="radio" name="sex[]" id="form_sex_20" value="20" /> <label class="custom-control-label" for="form_sex_20" id="form_sex_20">女性</label> <div class="invalid-feedback">性別が選択されていません。</div> </div> <div class="custom-control custom-radio custom-control-inline"> <input class="custom-control-input is-invalid" type="radio" name="sex[]" id="form_sex_30" value="30" /> <label class="custom-control-label" for="form_sex_30" id="form_sex_30">回答しない</label> <div class="invalid-feedback">性別が選択されていません。</div> </div> </div> </div>なお、選択肢が1つだけの場合は、上記のHTML構造でも見た目上、問題ありません
それでは、どのようにすればスマートになるのでしょうか。
実際のCSSのクラス定義を調べた結果、【修正方法】のNo.2を保てるHTML構造にすれば解決できることが分かりました。
他の解決方法として、CSSのクラスをオーバーライドすることもできますが、下の方法の方がシンプルで弊害もなく、手間が少ないと思います。
<div class="form-group row"> <label class="col-sm-3 col-form-label">性別</label> <div class="col-sm-9"> <div class="custom-control custom-radio custom-control-inline is-invalid"> <input class="custom-control-input is-invalid" type="radio" name="sex[]" id="form_sex_10" value="10" /> <label class="custom-control-label" for="form_sex_10" id="form_sex_10">男性</label> </div> <div class="custom-control custom-radio custom-control-inline is-invalid"> <input class="custom-control-input is-invalid" type="radio" name="sex[]" id="form_sex_20" value="20" /> <label class="custom-control-label" for="form_sex_20" id="form_sex_20">女性</label> </div> <div class="custom-control custom-radio custom-control-inline is-invalid"> <input class="custom-control-input is-invalid" type="radio" name="sex[]" id="form_sex_30" value="30" /> <label class="custom-control-label" for="form_sex_30" id="form_sex_30">回答しない</label> </div> <div class="invalid-feedback">性別が選択されていません。</div> </div> </div>【最終的な修正方法】
以上、お役に立てれば幸いです。