There are many many questions here on SO about how to properly persist checkbox fields in Laravel after form submission (
example,
example,
example
), this question is not about that.
Please note I am also well aware of Laravel's old()
old()
old()
<input type='text' name='unicorns' value='{{ old('unicorns', $model->unicorns) }}'>
old('unicorns')
null
$model->unicorns
old('unicorns')
<input type='checkbox' name='unicorns' value='1' @if old('unicorns', $model->unicorns) checked @endif>
0
old('unicorns')
1
true
1
old('unicorns')
old()
$model->unicorns
1
true
old()
old()
$errors
The $errors variable is bound to the view ...
$errors
old()
This is the clunky and complicated solution I referred to in the question, which I'm using as I can't find anything better. If anyone can suggest a better solution I'd be happy to accept (and use!) it.
I have an Html
helper, created as described in this question, and aliased in config/app.php
as described in the first part of this answer to that question. I added a static method to it:
namespace App\Helpers;
use Illuminate\Support\ViewErrorBag;
class Html {
/**
* Shortcut for populating checkbox state on forms.
*
* If there are failed validation errors, we should use the old() state
* of the checkbox, ignoring the current DB state of the field; otherwise
* just use the DB value.
*
* @param string $name The input field name
* @param string $value The current DB value
* @return string 'checked' or null;
*/
public static function checked($name, $value) {
$errors = session('errors');
if (isset($errors) && $errors instanceof ViewErrorBag && $errors->any()) {
return old($name) ? 'checked' : '';
}
return ($value) ? 'checked' : '';
}
}
Now in my views I can use it like so:
<input type='checkbox' name='unicorns' value='1' {{ \Html::checked('unicorns', $model->unicorns) }}>
This correctly handles all combinations of DB and submitted state, on initial load and after failed validation.