<input>のHTMLタグにおける文字列の入力(type=”text,emailなど”)と違ってチェックボックス(type=”checkbox”)は、値をそのまま表示しません。オン・オフのチェックマークとしてUIで表示する必要あります。また、フォームの投稿の際には、チェックボックスがオフの状態つまりチェックされていない状態だと値もフォームのリクエストに入ってきません。今回は、チェックボックスのコンポーネントの作成の話です。

入力画面

以下のような画面でチェックボックスのコンポーネントx-checkboxを使います。

この画面のブレードはこんな感じです。

<x-layout>
    <div class="container">
      <div class="row justify-content-center">
        <div class="col-md-8">
          <div class="card">
            <div class="card-header">登録</div>

            <div class="card-body">
              <x-form action="{{ route('checkbox') }}">

                <div class="row mb-3">
                  <x-label name="email">メールアドレス</x-label>
                  <div class="col-md-6">
                    <x-input type="email" name="email" required autocomplete="email"  />
                  </div>
                </div>

                <div class="row mb-3">
                  <x-label name="dummy"></x-label>
                  <div class="col-md-6">
                    <x-checkbox name="subscribe" value="Y">メルマガを購読する</x-checkbox>
                  </div>
                </div>

                <div class="row mb-0">
                  <div class="col-md-6 offset-md-4">
                    <x-button type="submit" class="m-2" level="primary">登録</x-button>
                  </div>
                </div>
              </x-form>
            </div>
          </div>
        </div>
      </div>
    </div>
  </x-layout>

フォームでバリデーションエラーが起こったとき

先の画面でバリデーションのエラーが起こった時は、以下のように、ユーザーが選択したチェックの状態を保つ必要あります。

そのためには、inputにおけるcheckedの属性の表示を、以下のようにold()$valueの値で比較すればいいですね。

props([
    'name',
    'value',
    'checked' => 'false',
])
<div class="form-check">
  <input
      type="checkbox"
      id = "{{ $name }}"
      name="{{ $name }}"
      value="{{ $value }}"
      {{ old($name) == $value ? 'checked' : '' }}
      {{ $attributes->merge(['class' => 'form-check-input']) }}
  >
  <label class="form-check-label" for="{{ $name }}">{{ $slot }}</label>
</div>

投稿時のチェックがオンなら、値のYが返されるので、old('subscribe') = 'Y'となり、$valueの’Y’と同じで、checkedが属性となりエラー表示の画面ではチェックはオンになります。反対に、チェックがオフなら、何も値がないので、old('subscribe') = nullとなり、checkedの属性は表示されなく、エラー表示の画面ではチェックはオフになります。

初期画面のデフォルト

さて、先の画面では、できればメルマガを受け取ってもらいたいので、チェックボックスをわざわざオンにしてもらうのではなく、最初からチェックをオンにして表示したいです。

デフォルトとしてチェックボックスをオンとするには、ブレードで以下のようにcheckedを指定します。

<x-checkbox name="subscribe" value="Y" :checked="true">メルマガを購読する</x-checkbox>

checkedはコンポーネントのプロパティなので、コンポーネントの属性としては、:checkedにphpの式を文字列で指定します。指定している”true”も文字列ではなくブーリアンのtrueとしてコンポーネントに渡されます。ちなみに、以下も同じ結果となります。

<x-checkbox name="subscribe" value="Y" :checked="1=1">メルマガを購読する</x-checkbox>

デフォルトをオフとしたいなら、最初のように:checkedを指定しません。コンポーネントにおいて、'checked' => falseとしているので、自動的にfalseとなります。もちろん、以下のように、”false”を渡してもOKです。

<x-checkbox name="subscribe" value="Y" :checked="false">メルマガを購読する</x-checkbox>

同様に、これが新規画面でなく編集画面なら、以下のようにDBからの値を使用し反映できます。

<x-checkbox name="subscribe" value="Y" :checked="$member->subscribe == 'Y'">メルマガを購読する</x-checkbox>

By khino