在 Laravel 5.8 中提交后,使用 @error 指令定位多个输入字段中的前一个输入字段

Using @error directive to target the previous input field from multiple input fields after submit in Laravel 5.8

新的@error 指令是introduced in Laravel 5.8.13。所以,与其这样做:

// old
@if ($errors->has('email')) 
    <span>{{ $errors->first('email') }}</span> 
@endif

您现在可以这样做了

// new
@error('email') 
    <span>{{ $message }}</span> 
@enderror

但是,我在尝试仅定位几个相似输入字段中出现错误的输入字段时遇到了问题。这些字段 similar 因为它们具有相同的名称。但是它们也有不同的形式,并且有不同的提交按钮。

我的 html blade 文件设置了从 @forelse 语句生成的多个输入。我创建了一个简单的错误检查来检查是否输入了负数并重定向回带有错误消息的同一页面。 @error 指令还用于将自定义 class 插入目标输入字段以进行样式设置。

@forelse($accounts as $account)
    <form method="POST" action="{{ route('account.update', $account->id) }}">
        @csrf
        <div>
            <input type="number" name="credit" class="@error('credit') is-invalid @enderror" required>
            <input type="submit" class="btn" value="ok">
            @error('credit')
                <span class="invalid-feedback" role="alert">
                    <strong>{{ $message }}</strong>
                </span>
            @enderror
        </div>
    </form>
@empty
@endforelse

表单在AccountController.php

中提交给update()方法
public function update(Request $request, Account $account)
{
    if($request->input('credit') < 0)
    {
        return back()->withErrors(['credit'=>'enter a positive amount']);
    }
    // ... other logic
}

问题是,当在一个输入字段中输入负数时,错误消息会针对具有相同名称的每个输入显示,即使它们不是相同的形式。

我认为使输入名称唯一可以解决这个问题,但这会使我的后端逻辑比所需的更复杂。

是否可以在重定向后仅针对目标输入显示错误消息,而不必为每个输入字段使用唯一名称?

解决方案如下:

  • 使用提交按钮的值将值/发布的表单存储在变量中
  • 放弃错误指令并使用旧版本
  • 结合旧版本和变量来检查你的表格是否正确

你会得到这样的东西:

@if ($errors->has('email') && $submitted_form_identifier === $form_identifier) 
    <span>{{ $errors->first('email') }}</span> 
@endif

有趣的是,@error 指令 不是 通过输入名称以编程方式绑定到任何输入字段。它仅通过接近度与输入字段在空间上相关,并且可以放置在页面上的任何位置。

此外,您可以方便地在 @error 指令中使用任何字符串,只要将相同的字符串传递给控制器​​中的 withErrors() 调用即可。

因此,解决在多个输入中定位适当输入的问题变得像使用 any 唯一字符串一样简单(不一定是目标输入名称) 作为 withErrors() 方法调用中的键,并通过将相同的字符串传递给 @error 指令来检索错误消息。就我而言,我选择使用帐户 ID 作为唯一字符串。

AccountController.php中:

public function update(Request $request, Account $account)
{
    if($request->input('credit') < 0)
    {
        return back()->withErrors([$account->id=>'enter a positive amount']);
    }
    // ... other logic
}

并且在 html blade 模板中:

@forelse($accounts as $account)
    <form method="POST" action="{{ route('account.update', $account->id) }}">
        @csrf
        <div>
            <input type="number" name="credit" class="@error($account->id) is-invalid @enderror" required>
            <input type="submit" class="btn" value="ok">
            @error($account->id)
                <span class="invalid-feedback" role="alert">
                    <strong>{{ $message }}</strong>
                </span>
            @enderror
        </div>
    </form>
@empty
@endforelse

注意:在任何 @error 指令中使用不存在的键会破坏其他 @error 指令的代码,并且不会导致显示任何错误消息。