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

隐身守侯 提交于 2021-02-17 06:46:24

问题


The new @error directive was introduced in Laravel 5.8.13. So, instead of doing this:

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

You can now do this

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

However, I'm having issues trying to target only the input fields where the error was made among several similar input fields. These fields are similar because they have the same name. But they are also in seperate forms and have different submit buttons.

My html blade file is setup with multiple inputs generated from a @forelse statement. I've created a simple error check to check if a negative number is entered and to redirect back to the same page with an error message. The @error directive is also used to insert a custom class to target input field for styling.

@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

The form submits to the update() method in AccountController.php

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

The problem is that when a negative number is entered in one input field, the error message shows up for every input with the same name, even when they are not in the same form.

I think making the input names unique will solve this, but this will make my backend logic more complex than is required.

Is there anyway of making the error message show for just the target input after the redirect, without having to use unique names for each input field?


回答1:


A solution would be doing the following:

  • store the value / posted form in a variable using the value of the submit button
  • ditch the error directive and use the old version
  • combine the old version with the variable to check wether you have the correct form or not

You'll get something like this:

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



回答2:


Interestingly, the @error directive is not programmatically tied to any input field by an input name. It is only spatially related to an input field by proximity and can be placed any where on the page.

Also, you can conveniently use any string within the @error directive as long as same is passed to the withErrors() call in the controller.

So, solving the problem of targeting the appropriate input among multiple ones becomes as simple as using any unique string (not necessarily the target input name) as key in the withErrors() method call and retrieving the error message by passing the same string to the @error directive. In my case, I chose to use the account id as the unique string.

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

And in the html blade template:

@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

NOTE: Using a non existent key in any @error directive breaks the code for other @error directives and will cause no error messages to be displayed.



来源:https://stackoverflow.com/questions/57987121/using-error-directive-to-target-the-previous-input-field-from-multiple-input-fi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!