51歳からのプログラム　備忘録　checkbox バリデーション old('name')

checkboxの状態を保持してバリデートし、エラーでリダイレクトした時に、保持した状態を反映させたい(`old('name')`を反映させたい)。

これがちょっとハマってしまったので、だらだらと、色々と、確認してみた。

・　`<input type="checkbox">`の送信内容の確認
・　Controllerでのバリデーション
・　jqueryでの入力チェック

準備
--

```php:
// route ----------------------------------
Route::get ('/test','Controller@get_test');
Route::post('/test','Controller@post_test');

// view -----------------------------------
<form action="/test" method="post">
    {{csrf_field()}}
    <input type="checkbox">
    <button>submit</button>
</form>

// Controller -----------------------------
public function post_test(Request $request)
{
    $rule=[];                          //ﾊﾞﾘﾃﾞｰｼｮﾝﾙｰﾙ
    $this->validate($request,$rule);   //ﾊﾞﾘﾃﾞｰｼｮﾝ

    $form=$request->all();
    unset($form['_token']);
    print_r($form);
}
```
viewのチェックボックスをチェックし、submitすると、

結果

```php
// Controller
Array()
```
バリデーションルールを設定してないので、バリデートされずに、`print_r($form)`が実行された。

`<input>`には、`name`も`value`も設定していないので、`$form`は空の配列として表示。

input に name を付けた
--
`<input checkbox>`をバリデーションに引っ掛けるために、`input`に`name`を付ける。（まだバリデーションは設定しない）


```php:
// view -----------------------------------
    <input type="checkbox" name="ch">
```
チェックボックスを**未チェック**で送信すると

```php
Array()
```
チェックボックスを**チェックして**送信すると

```php
Array( [ch]=>on )
```
キー[ch]に`on`が設定されていた。

input に value を設定して、バリデーションルールは適用せずにpostしてみる。
--

```php
// view
<input type="checkbox" name="ch" value="test">

// Controller -----------------------------
public function post_test(Request $request)
{
    $rule=[];                          //ﾊﾞﾘﾃﾞｰｼｮﾝﾙｰﾙ
    $this->validate($request,$rule);   //ﾊﾞﾘﾃﾞｰｼｮﾝ

    $form=$request->all();
    unset($form['_token']);
    print_r($form);
```
チェックボックスが**未チェック**だと、空の配列が送られる。

チェックボックスに**チェックを入れて**送信すると、

```php
Array( [ch]=>test )
```
キー[ch]に、値は`test`がセットされて送られた。

`checkbox`にvalueがセットされているか否かで、送られるハッシュ配列が変わるのですね。

＜checkboxの属性とか＞

valueの有無|送られる値|
----------|---------|
valueがない|`on`     |
valueがある|value値  |
valueがnull|null値   |

valueがない時のバリデーション
--
valueがないと、チェック時に送られるのは`on`。
`on`かどうかチェックするのは、`accept`で。
まずは、`accepted`でバリデートする。

```php:
// view -----------------------------
<input type="checkbox" name="ch">

// Controller -----------------------
public function post_test(Request $request)
{
    $rule=['ch'=>'accepted'];          //ﾊﾞﾘﾃﾞｰｼｮﾝﾙｰﾙ
    $this->validate($request,$rule);   //ﾊﾞﾘﾃﾞｰｼｮﾝ

    $form=$request->all();
    unset($form['_token']);
    print_r($form);
}
```
チェックボックス**未チェック**だと、バリデーションでリダイレクトされる。

チェックボックスを**チェックして**postすると、

```php:
Array( [ch]=>on )
```
キー[ch]に、`on`がセットされた。

未チェックをバリデーションに掛ける
--
未チェックの時にはバリられてリダイレクト、にしたいので、`required`のみでバリる。

```php:
// view
<input type="checkbox" name="ch">

// Controller
// 省略
    $rule=['ch'=>'required'];          //ﾊﾞﾘﾃﾞｰｼｮﾝﾙｰﾙ
    $this->validate($request,$rule);   //ﾊﾞﾘﾃﾞｰｼｮﾝ

// 省略
```
**未チェック**でpost送信すると、バリられます。
**チェックして**送信すると、

```php
Array( [ch] => on )
```

ちょっと　まとめ
--
バリデーションで、viewに返される連想配列

`<input type="checkbox">`の属性で

|valueがある場合|valueが無い場合|
|--------------|--------------|
|value値       |on            |


バリデーションは、Controllerで行うのか、関数ファイルを作ったり、includeしたりするのか、モデルで行うのか、Javascriptで行うのか
--
ミドルウェアで行う必要もなく、使いまわしもしないのなら、javascriptは同じファイル上で入力チェックできるので、`old('name')`を使わなくても、入力値を維持できる。controllerだとファイルを移動したりviewが遷移したりする。こういうケースなら、javascriptが軽くていいのだろうか？

・　Controllerで入力チェック（バリデーション）
・　Jqueryで入力チェック

を、してみる。
どっちがいいとか、分からいから、コードだけ考えてみた。

Controllerでバリデートして、既入力状態を反映させる
--
まず、controllerでバリデートして、old('name')を使って、チェックボックスの値を保持させてみる。

`view`に、`<input type="checkbox" name="ch2">`を追加する。

あわせて、controllerに、バリデーションルールを追加する。

```php:
// view -----------------------
<form action="/test" method="post">
    <input type="checkbox" name="ch1">
    <input type="checkbox" name="ch2">
    <button>submit</button>
</form>

// Controller -----------------
public function post_test(Request $request)
{
    $rule=['ch1'=>'accepted',
           'ch2'=>'accepted'];         //ﾊﾞﾘﾃﾞｰｼｮﾝﾙｰﾙ
    $this->validate($request,$rule);   //ﾊﾞﾘﾃﾞｰｼｮﾝ

    $form=$request->all();
    unset($form['_token']);
    print_r($form);
}
```
`<input>`にはvalueは設定していないので、バリデーションで返される値は、チェックされたキー名と、値`on`となる。

キー名と値によって、バリデーションで返された値で、`checkbox`を`checked`にするには、下記のように変更。

```php:
<form action="/test" method="post">
  {{csrf_field()}}
  <input type="checkbox" name="ch1" @php if(old('ch1')){echo 'checked="checked"';} @endphp>
  <input type="checkbox" name="ch2" @php if(old('ch2')){echo 'checked="checked"';} @endphp>
  <button>submit</button>
</form>
```
これで値を保持できた

jqueryで、チェック状態をチェック
--
jqueryで入力チェックするのに、`view`の`<button>`に`type`を付ける。

`type`を付けないと、button クリックで　subumit（送信）されてしまうそうなので、>https://qiita.com/kazu56/items/b2e9c15942e04a6ffda9)
そうならないように、type="button" で設定っす。
`<button type="button">submit</button>`

```php
// view ---------------------------------
<form action="/test" method="post">
    <input type="checkbox" name="ch1">
    <input type="checkbox" name="ch2">
    <button type="button">submit</button>
</form>
```

では、jqueryで、入力チェックです。
jqは、CDNなのかどうかは、おまかせです。

```php:
<script>
 $(function(){
   // 2つのチェックボックス　ch1 ch2　のチェック状態を確認
   $('button').on('click',function(){
     var ch1_val=$('input[name="ch1"]:checked').val();//ch1 のチェック状態　on があるかないか
     var ch2_val=$('input[name="ch2"]:checked').val();//ch2 のチェック状態　on があるかないか

     if(!ch1_val || !ch2_val){
        return false;
     }else{
       $('form').submit();
     }

   });
 });
</script>


<form action="/test" method="post">
  {{csrf_field()}}
  <br>
  <input type="checkbox" name="ch1"><br>
  <input type="checkbox" name="ch2"><br>
  <button type="button">button</button>
</form>
```

これで入力チェックはできてると思う。思います。
ご指導あればいただけたら幸いです。