Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jakubjv's avatar

Why form validation doesnt work? Livewire 3

Hello everyone, ihave a problem with validation of verification modal. I think i set up everything right, but when user insert verification code to modal and code is worng or less digts than 6, it wont show up any errors, modal close and display is shadow.. I will provide a code, maybe am missing something, its my first project with livewire so sorry if is it stupid question.

This is component

<?php

namespace App\Livewire;

use Livewire\Component;
use App\Models\Reservation;
use App\Mail\ReservationMail;
use Illuminate\Support\Facades\Mail;
use App\Models\AvailableBusinessHour;

class Booking extends Component
{
    public $full_name;
    public $email;
    public $phone_number;
    public $reservation;

    public $selectedService;
    public $available_business_hour_id;
    public $selectedBusinessHourId;
    public $verification_code;
    public $successMessage;
    public $successMessageVisible;
    public $successMessageTimeout = 3000;
    public $verificationCodeSubmitted = false;


    public function render()
    {
        $this->available_business_hour_id = AvailableBusinessHour::whereDoesntHave('reservation')->orderBy('day')->orderBy('from')->get();
        return view('livewire.booking', [
            'emptyOption' => 'Vyber si čas rezervace',
        ]);
    }

    public function store()
    {
        $this->validate([
            'full_name' => 'required|string|max:250',
            'email' => 'required|email|max:250',
            'phone_number' => 'required|phone:CZ',
            'selectedService' => 'required',
            'available_business_hour_id' => 'required|unique:reservations',
        ], [
            'available_business_hour_id.unique' => 'Tento termín byl již obsazen, vyber jiný pokud je nějaký dostupný.',
            'available_business_hour_id.required' => 'Výběr času objednání je povinné pole.',
            'phone_number.phone' => 'Chybný formát telefonního čísla.',
            'selectedService.required' => 'Toto je povinné pole',
        ]);

        $selectedBusinessHour = AvailableBusinessHour::find($this->selectedBusinessHourId);

        $verification_code = rand(100000, 999999);

        $reservation = Reservation::create([
            'full_name' => $this->full_name,
            'email' => $this->email,
            'phone_number' => $this->phone_number,
            'service' => $this->selectedService,
            'available_business_hour_id' => $this->selectedBusinessHourId,
            'day' => $selectedBusinessHour['day'],
            'from' => $selectedBusinessHour['from'],
            'to' => $selectedBusinessHour['to'],
            'verification_code' => $verification_code
        ]);

        session(['verification_code' => $verification_code, 'current_reservation_id' => $reservation->id]);


        $this->sendReservationConfirmationMail($reservation);


        $this->dispatch('show-verification-modal');

        $this->reset(['full_name', 'email', 'phone_number', 'available_business_hour_id']);
    }

    public function sendReservationConfirmationMail($reservation)
    {
        Mail::to($reservation->email)->send(new ReservationMail($reservation));
    }

    public function services()
    {
        return ["Stříhání vlasů", "Stříhání + úprava vousů", "Barvení vousů", "Junior střih", "Úprava vousů"];
    }

    public function confirmReservation()
{
    $this->validate([
        'verification_code' => 'required|digits:6',
    ], [
        'verification_code.required' => 'Zadejte prosím verifikační kód.',
        'verification_code.digits' => 'Verifikační kód musí mít 6 čísel.',
    ]);

    $user_entered_code = $this->verification_code;

    $reservation = Reservation::where('verification_code', $user_entered_code)
        ->where('is_confirmed', false)
        ->where('id', session('current_reservation_id'))
        ->latest()
        ->first();

    if ($reservation) {
        $reservation->update(['is_confirmed' => true]);
        $this->reset(['verification_code']);
        $this->successMessage = 'Rezervace proběhla úspěšně.';
        $this->successMessageVisible = true;
        $this->dispatch('hide-verification-modal');
    } else {
        $this->addError('verification_code', 'Neplatný verifikační kód nebo rezervace již byla potvrzena.');
    }
}

}

this is template,, Modal is in the second part of template.

<section id="booking">
    <div class="container">
        @if ($successMessageVisible && !$verificationCodeSubmitted)
            <div x-data="{ show: true }" x-init="setTimeout(() => show = false, {{ $successMessageTimeout }})" x-show="show" class="alert alert-success">
                {{ $successMessage }}
            </div>
        @endif
        <form wire:submit.prevent="store">
            @csrf
            <div class="col-12 mb-4">
                <h1 class="modal-title fs-5 text-center" id="bookingModalLabel">Objednej se</h1>
                <p class="">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Lorem, ipsum
                    dolor sit amet consectetur adipisicing elit.</p>
            </div>
            <div class="form-group col-12">
                <input type="text" wire:model="full_name" id="full_name" name="full_name" class="form-control"
                    placeholder="Celé jméno*" required>
            </div>
            <div class="form-group col-12">
                <input type="email" wire:model="email" id="email" name="email" class="form-control"
                    placeholder="Email*" required>
            </div>
            <div class="form-group col-12">
                <input type="text" wire:model="phone_number" id="phone_number" name="phone_number"
                    class="form-control" placeholder="Tel. číslo ve formátu +420700700700" required>
                @error('phone_number')
                    <span class="text-danger">{{ $message }}</span>
                @enderror
            </div>
            <div class="form-group col-12">
                <select wire:model="selectedService" class="form-control">
                    <option value="">Vyberte službu</option>
                    @foreach ($this->services() as $service)
                        <option value="{{ $service }}">{{ $service }}</option>
                    @endforeach
                </select>
                @error('selectedService')
                    <span class="text-danger">{{ $message }}</span>
                @enderror
            </div>

            <div class="form-group col-12 mt-3">
                <select wire:model="selectedBusinessHourId" class="form-control">
                    <option value="">{{ $emptyOption }}</option>
                    @foreach ($available_business_hour_id as $time)
                        <option value="{{ $time['id'] }}">{{ $time['formattedDayAndDate'] }} od {{ $time['from'] }} do
                            {{ $time['to'] }}</option>
                    @endforeach
                </select>
                @error('available_business_hour_id')
                    <span class="text-danger">{{ $message }}</span>
                @enderror
            </div>
            <div class="form-group col-12 text-center">
                <div class="cta-btns">
                    <button type="submit" class="btn btn-service me-sm-2">Odeslat</button>
                </div>
            </div>
        </form>

    </div>

        <div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"
            data-bs-backdrop="static" data-bs-keyboard="false">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h1 class="modal-title fs-5" id="exampleModalLabel">Zádání potvrzovacího kódu</h1>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <div class="modal-body">
                        <div class="verification-code-container">
                            <h5>Aby byla vaše rezervace brána jako platná, musíte zadat potvrzovací kód, který vám byl
                                zaslán na zadaný e-mail.</h5>
                            <form wire:submit.prevent="confirmReservation">
                                <input type="text" wire:model="verification_code" id="verification_code"
                                    name="verification_code" class="form-control" placeholder="Potvrzovací kód"
                                    required>
                                @error('verification_code')
                                    <span class="text-danger">{{ $message }}</span>
                                @enderror
                                <div class="cta-btns">
                                    <button type="submit" class="btn btn-service me-sm-2" wire:submit.prevent="confirmReservation">Odeslat</button>
                                </div>
                            </form>
                        </div>
                    </div>

                </div>
            </div>
        </div>

</section>

@script
    <script>
        $wire.on('show-verification-modal', () => {
            $('#exampleModal').modal('show');
        });

        $wire.on('hide-verification-modal', () => {
            $('#exampleModal').modal('hide');
        });

    //     $wire.on('hide-verification-modal', () => {
    //     // Počkejte 3 sekundy před zavřením modálního okna
    //     setTimeout(() => {
    //         $('#exampleModal').modal('hide');
    //     }, 3000);
    // });

        $wire.on('verification-code-submitted', () => {
            $('[x-data]').find('.alert-success').hide();
            $('[x-data]').find('.alert-success').show();
        });
    </script>
@endscript

If anyone has any idea how to solve it i will be glad for that. thank you for help :)

0 likes
7 replies
alden8's avatar
alden8
Best Answer
Level 1

@jakubjv -- consider adding wire:ignore.self to the modal's div to prevent Livewire from automatically re-rendering it when errors occur, potentially closing the modal: HTML

<div class="modal fade" id="exampleModal" wire:ignore.self ...>

-- ensure you're correctly displaying errors within the modal's form using Alpine.js or Blade:

@error('verification_code')
    <span class="text-danger">{{ $message }}</span>
@enderror

-- event dispatching:

---- verify that the verification-code-submitted event is triggered only when validation passes in the confirmReservation method

--- if you intend to keep the modal open on validation errors, remove the dispatch('hide-verification-modal') line within the else block

-- livewire debugging:

--- use dd($this->verification_code) within the confirmReservation method to inspect the submitted value and ensure validation is working as expected

--- check for any JavaScript errors or warnings related to Livewire or Alpine.js that might interfere with validation or modal behavior

1 like
jakubjv's avatar

@alden8 Omg.. iam idiot..i forgot about wire:ignore.self, it works perfectly with that,,thank you very much for advice!! :) It's perfect now.

1 like
martinbean's avatar

@jakubjv It’s called the alden8-couldn't-be-bothered-to-write-his-own-response tool.

1 like

Please or to participate in this conversation.