ブログ

Bootstrap 4 のradioやcheckboxでスマートにエラーメッセージを表示するには 2020.03.03

Twitter Bootstrap 4 では、サーバーサイドでチェックした入力エラーのメッセージを表示するための「invalid-feedback」クラスが用意されており、 項目ごとに分かりやすく表示されるようになっています。

しかしながら、ラジオボタンやチェックボックスで選択肢が複数ある場合に、 公式サイトの説明 の通りにHTMLを出力しても、期待通りにならないことがありました。
その場合への対処方法をご紹介します。

1.1行テキスト欄でのサンプル

例えば、次のような「お名前」欄があり、エラーチェックの前後で下図のようにエラーメッセージが表示されると分かりやすいですね。

エラーチェック前
エラーチェック後

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>
		
【修正方法】
  1. <input>タグに「is-invalid」クラスを記述します(フォームが赤く表示されるようになります)。
  2. さらに、(同じ親要素の)兄弟要素として、「invalid-feedback」クラスを持つ<div>タグでエラーメッセージを表示できます。

ここまでは問題なくスマートに表示されていますね。

2.複数の選択肢を持つラジオボタンでは?

次に、複数の選択肢を持つラジオボタンについて見てみましょう。

公式サイトの説明 の通りに、<input>タグに「is-invalid」クラスを記述して、その兄弟要素として「invalid-feedback」クラスを持つ<div>タグでエラーメッセージを指定します。

エラーチェック前
エラーチェック後



あれ???




かなり残念なことになっています…。


では、HTMLの構造も比較してみましょう。

実際には、各選択肢はPHPなどでループして出力していますが、上記の【修正方法】である、

  1. <input>タグに「is-invalid」クラスを記述します(フォームが赤く表示されるようになります)。
  2. さらに、(同じ親要素の)兄弟要素として、「invalid-feedback」クラスを持つ<div>タグでエラーメッセージを表示できます。

は変えておらず、HTMLの構造は同様です。
なお、下の例ではcustom-controlを使用していますが、標準のformでも同じです。

HTMLの比較(赤文字が追加)
エラーチェック前
<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構造でも見た目上、問題ありません

3.最終的な対処方法

それでは、どのようにすればスマートになるのでしょうか。

実際のCSSのクラス定義を調べた結果、【修正方法】のNo.2を保てるHTML構造にすれば解決できることが分かりました。

  1. <input>タグに「is-invalid」クラスを記述します(フォームが赤く表示されるようになります)。
  2. さらに、(同じ親要素の)兄弟要素として、「invalid-feedback」クラスを持つ<div>タグでエラーメッセージを表示できます。

他の解決方法として、CSSのクラスをオーバーライドすることもできますが、下の方法の方がシンプルで弊害もなく、手間が少ないと思います。

対処したHTML(赤文字が追加)
エラーチェック後
<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>
		
【最終的な修正方法】
  1. <input>タグに「is-invalid」クラスを記述します(フォームが赤く表示されるようになります)。
  2. <input>タグの親要素にも「is-invalid」クラスを記述しておきます。
  3. <input>タグの親要素の兄弟要素として、「invalid-feedback」クラスを持つ<div>タグを1つ記述し、エラーメッセージを表示します。

以上、お役に立てれば幸いです。