验证失败后,Laravel复选框状态

问题描述 投票:2回答:5

关于如何在表单提交后正确地保留Laravel中的复选框字段(qazxsw poi,qazxsw poi,qazxsw poi),这里有很多问题,这个问题与此无关。

请注意我也很清楚exampleexample。我的问题是关于example似乎不适用于复选框的特殊情况。

我正在编写一个编辑表单,更新数据库中已有的数据。表单最初将使用DB中的值填充。

验证失败后重新填充表单输入的标准方法是使用Laravel's old() method。对于大多数输入类型,类似以下工作:

it accepts a default value

在初始页面加载时(在提交表单之前),这很好。由于尚未提交任何内容,old()old(),因此将使用<input type='text' name='unicorns' value='{{ old('unicorns', $model->unicorns) }}'> 的默认值,文本字段的值将反映当前的DB状态。

在提交未通过验证的新值后,即使新值为空字符串,old('unicorns')也将是新值,并且文本字段的值再次反映提交状态,如我们所愿。

但是,当取消选中的复选框未显示在请求中时,这会分解复选框。考虑:

null

在初始页面加载时,这可以正常工作,就像文本字段一样。但在验证失败后,对于复选框从其初始状态更改的2种情况:

  • 案例1:DB状态$model->unicorns(未选中),提交状态检查。 old('unicorns')将是<input type='checkbox' name='unicorns' value='1' @if old('unicorns', $model->unicorns) checked @endif> ,所以测试评估0,复选框被检查 - 好的!
  • 案例2:DB状态old('unicorns')(已选中),提交状态未选中。由于1为null,true回落到默认值1old('unicorns')),因此测试评估old(),并选中复选框 - 但我们只是取消选中它!失败!

(在其他2种情况下没有问题,其中复选框不会从DB中的状态更改)。

怎么解决这个?

我最初认为最好的方法是测试是否存在验证错误 - 如果是,请使用$model->unicorns值,没有默认回退;如果没有,请使用1和默认回退。测试验证失败的一种方法是检查true。这似乎有效,但它old(),(来自Laravel文档):

注意:$ errors变量绑定到视图...

我想为此创建一个全球帮手,而old()将无法在那里工作。无论如何,这种方法感觉......笨重而且太复杂。

我错过了什么吗?是否有一种巧妙的Laravel解决方法?奇怪的是,$errors根本不适用于这种特殊情况。

这不是一个新问题,其他人如何处理这个?

php laravel laravel-5.2
5个回答
1
投票

这是我在问题中提到的解决方案。它运作良好,6个月后,它似乎并不像我发布问题时那样笨重。我很高兴听到其他人如何做到这一点。

我有一个only works within a view AFAICT助手,创建为$errors,并在old()的第一部分描述的Html别名。我添加了一个静态方法:

described in this question

现在在我看来,我可以像这样使用它:

config/app.php

这在初始加载和验证失败后正确处理DB和提交状态的所有组合。


0
投票

我有类似的情况,我的解决方案是在复选框字段之前添加一个隐藏字段。所以,在你的情况下,它将是这样的:

this answer to that question

这样,当未勾选复选框时,该字段的值仍将出现在后请求中。勾选后,复选框的值将覆盖隐藏字段中的值,因此顺序很重要。您不应该使用此方法使用自定义类。

那对你有用吗?


0
投票

从Do not Panic的回答中,你可以在刀片中这样做:

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' : '';
    }
}

希望能帮助到你。


0
投票

我这样做

<input type='checkbox' name='unicorns' value='1' {{ \Html::checked('unicorns', $model->unicorns) }}>

-1
投票

在持久化复选框状态时,我实际上做了一个简单的三元运算符:

<input type='hidden' name='unicorns' value='0'>
<input type='checkbox' name='unicorns' value='1' {!! old('unicorns', $model->unicorns) ? ' checked' : '' !!}>

编辑:

<input type="checkbox" class="form-check-input" value='true'
@if ($errors->any())
{{ old('is_private') ? 'checked' : '' }}
@else
{{ isset($post) && $post->is_private ? 'checked' : '' }}
@endif
>
© www.soinside.com 2019 - 2024. All rights reserved.