Search code examples
laravellaravel-livewire

How to update the value of wire:model in real time


I have a form that looks like this:

enter image description here

When the user enters a value on appointment start time i want to increment that value by 30 min and display it in the appointment end time. This is my controller

//get data from db 
public function userId($appointmentId){
        $appointmentInfo = Appointments::with('user')->where('id',$appointmentId)->first();
        
        $this->userAppointmentName = $appointmentInfo->user->name;
        $this->description = $appointmentInfo->description;
        $this->subject = $appointmentInfo->subject;
        $this->chooseDate = Carbon::parse($appointmentInfo->start_appointment)->toDateString(); 
        $this->start_appointment = Carbon::parse($appointmentInfo->start_appointment)->format('H:i'); 
        $this->end_appointment = Carbon::parse($appointmentInfo->start_appointment)->addMinutes(30)->format('H:i');  
    }
public function addApointment($appointmentId){
        
        $this->start_appointment = Carbon::parse(strtotime("$this->chooseDate $this->start_appointment"))->format("Y-m-d H:i:s");
        
        $this->end_appointment = Carbon::parse(strtotime("$this->chooseDate $this->start_appointment"))->addMinutes(30)->format("Y-m-d H:i:s");
        
        $record = Appointments::where([
            ['id',$appointmentId],
            ['business_id',auth()->id()]])->first();

        $record->update([
                'status' => 'in_progress',
                'subject' => $this->subject,
                'description' => $this->description,
                'start_appointment' => $this->start_appointment, 
                'end_appointment' => $this->end_appointment, 
            ]);
    }

And this is in my blade file

<div class="grid md:grid-cols-2 gap-x-2">
                <div class="mb-4">
                    <label class="block mb-1"> Appointment Start Time </label>
                    <div class="relative">
                        <div class="flex items-center justify-center">
                            <div class="datepicker relative form-floating mb-3 xl:w-96">
                                <input wire:model = "start_appointment" type="time" class="form-control block w-full px-3 py-1.5 text-base font-normal text-gray-700 bg-white bg-clip-padding border border-solid border-gray-300 rounded transition ease-in-out m-0 focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none" placeholder="Select a date" />
                                <label for="floatingInput" class="text-gray-700">Select a time ex:12:30PM</label>
                                @if($errors->has("start_appointment"))<p style="color:red">{{ $errors->first("start_appointment") }}</p>@endif                      
                            </div>
                        </div>
                    </div>
                </div> 
                <div class="mb-4">
                    <label class="block mb-1"> Appointment End Time </label>
                    <div class="relative">
                        <div class="flex items-center justify-center">
                            <div class="datepicker relative form-floating mb-3 xl:w-96">
                                <input wire:model.lazy = "end_appointment" type="time" disabled class="form-control block w-full px-3 py-1.5 text-base font-normal text-gray-700 bg-white bg-clip-padding border border-solid border-gray-300 rounded transition ease-in-out m-0 focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none" placeholder="Select a date ex:1:30PM" />
                                <label for="floatingInput" class="text-gray-700"></label>
                                @if($errors->has("end_appointment"))<p style="color:red">{{ $errors->first("end_appointment") }}</p>@endif                      
                            </div>
                        </div>
                    </div>
                </div> 
            </div>

Solution

  • You could use wire:change attribute to listen to the changes of start_appointment, like so :

    <input wire:model="start_appointment" wire:change="startAppointmentChanged" ... />
    

    And in your Livewire component have something like :

    public function startAppointmentChanged() 
    {
       $this->end_appointment = Carbon::parse($this->start_appointment)->addMinutes(30)->format('H:i');  
    }
    

    To keep $end_appointment synced anytime $start_appointment changes.