Search code examples
laravellaravel-bladelaravel-livewire

I do not understand how to use livewire attribute validation return value


This is what i see in the frontend:

enter image description here

The problem is the following. I have a form in livewire:

<div class="striped">
<div x-data="{showDeleteButton: false}" class="account-list grid">
    <div class="card-item-name">
        {{ $account->name }}
    </div>
    <div class="account-amount flex">
        <span class="pt-1 mr-1">&euro;</span>
        <x-input wire:model.live="amount"
                 type="text"
                 @class(['border border-red-600' => $errors])
                 x-bind:class="parseFloat($wire.amount) < 0 ? 'text-red-600' : ''"
                 class="text-right"
        />
        @if($errors)
            {{ $errors }}
        @endif
        <div class="ml-1">
            @include('components.balance.buttons.delete-button-account-item')
        </div>
    </div>
</div>

As can bee seen in the screenshot the following:

@if($errors)
     {{ $errors }}
@endif

is displayed as:

{"amount":["Geef een getal op in euros gescheiden door een comma"]}

How can i make use of this information in the following line?:

@class(['border border-red-600' => $errors])

I want a red border if the validation fails. My validation is as follows:

 public function updated($name, $value)
{
    $this->validate([
        'amount' => ['required', new IsEuroAmount]
    ]);

    Account::find($this->account->id)->update([
        'amount' => Item::convertEurosToEuroCents($value)
    ]);

    $this->dispatch('account-updated');
}

this being my custom Rule:

namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

class IsEuroAmount implements ValidationRule
{
    /**
     * Run the validation rule.
     *
     * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail
     */
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if (!preg_match('/^(-)?\d{1,6}(,\d{0,2})?$/', $value)) {
            $fail('Geef een getal op in euros gescheiden door een comma');
        }
    }
}

i tried json_decode but that throws an error (Array to string conversion)

$errors->amount

does not work either nor:

$errors->amount->count()

nor:

@class(['border border-red-600' => 1])

nor:

 @class([ 'border' => 1, 'border-red-600' => 1])

this works but not on the error condition (if an element has a class attribute, @class does not work):

 @class([ 'text-right','border' => 1, 'border-red-600' => 1])

This worked for me:

@class([ 'text-right','border' => $errors->count(), 'border-red-600' => $errors->count()])

But in this case there is only 1 field so this will work but not with multiple fields

Who knows what to do with multiple fields?


Solution

  • This is the only good answer:

    $errors->get('%field%')
    

    therefore i get:

    @class(['text-right','border' => $errors->get('amount'), 'border-red-600' => $errors->get('amount')])