これで3時間くらいハマった。
前提
Laravel 5.1
問題
下記のようなチェックボックスを含む値をPOSTする状況でデフォルト値の設定に悩む。
-
users
の編集画面 -
users.is_active = 1
からusers.is_active = 0
に変更する -
users.is_active
用のチェックボックスをONからOFFに変更してPOST - 別の項目でバリデーションに引っかかり、入力画面に戻る
-
users.is_active
用のチェックボックスはOFFになっていてほしい
残念ながら、チェックボックスはONになっている。
<input type="checkbox" {{ (old('is_active', $user->is_active) ? 'checked' : '' }}>
としても、 old('is_active', $user->is_active)
は、チェックボックスをOFFにしていると old('is_active')
が null
のため、デフォルトの $user->is_active
が呼ばれてチェックが付いてしまう。
これと同じ問題。
解決策
Laravel Collective とか使えばいいのだろうか。試していないが同じ問題が起きそうなのでやめた。
ちょっとださいが、仕方がないので下記ヘルパーを作って解決した。
function is_checked(string $name, $value, $default) : string
{
$current_defaults = Input::old() ? old($name, 0) : $default;
return ($value == $current_defaults) ? 'checked' : '';
}
<input type="checkbox" name="is_acrive" value="1"
{{ is_checked('is_active', 1, $user->is_active) }}>
Multiple checkbox version:
function is_checked_multiple(string $name, $value, $defaults) : string
{
$current_defaults = Input::old() ? old($name, []) : (array)$defaults;
return in_array($value, $current_defaults) ? 'checked' : '';
}
@foreach ($plans as $plan)
<input type="checkbox" name="plans[]" value="{{ $plan->id }}"
{{ is_checked_multiple('plans', $plan->id, $user->plans->pluck('id') }}>
@endforeach
==
の曖昧比較なのは、 old()
の値は文字列になるから。
追記
@nunulk さんのご指摘の通り、 laravelcollective/html
では問題なく動作することを確認できました。
記述も短くなるしこれ使った方がいいな・・・