Edited at

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

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

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

・ <input type="checkbox">の送信内容の確認

・ Controllerでのバリデーション

・ jqueryでの入力チェック


準備

// 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すると、

結果

// Controller

Array()

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

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


input に name を付けた

<input checkbox>をバリデーションに引っ掛けるために、inputnameを付ける。(まだバリデーションは設定しない)

// view -----------------------------------

<input type="checkbox" name="ch">

チェックボックスを未チェックで送信すると

Array()

チェックボックスをチェックして送信すると

Array( [ch]=>on )

キー[ch]にonが設定されていた。


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

// 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);

チェックボックスが未チェックだと、空の配列が送られる。

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

Array( [ch]=>test )

キー[ch]に、値はtestがセットされて送られた。

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

<checkboxの属性とか>

valueの有無
送られる値

valueがない
on

valueがある
value値

valueがnull
null値


valueがない時のバリデーション

valueがないと、チェック時に送られるのはon

onかどうかチェックするのは、acceptで。

まずは、acceptedでバリデートする。

// 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すると、

Array( [ch]=>on )

キー[ch]に、onがセットされた。


未チェックをバリデーションに掛ける

未チェックの時にはバリられてリダイレクト、にしたいので、requiredのみでバリる。

// view

<input type="checkbox" name="ch">

// Controller
// 省略
$rule=['ch'=>'required']; //バリデーションルール
$this->validate($request,$rule); //バリデーション

// 省略

未チェックでpost送信すると、バリられます。

チェックして送信すると、

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に、バリデーションルールを追加する。

// 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となる。

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

<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>

// 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なのかどうかは、おまかせです。

<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>

これで入力チェックはできてると思う。思います。

ご指導あればいただけたら幸いです。