Pasindu Ruwandeniya
Pasindu Ruwandeniya

Reputation: 637

Run Livewire click method based on whether a checkbox is checked or not

I have a Livewire component like below

<div class="mr-3">
    <input type="checkbox" name="milestoneMark" value="{{ $milestoneId }}" x-model="milestone" wire:click="mark()">
</div>

The component class have below code

class CheckMilestone extends Component
{

    public $milestoneId;

    public function mark()
    {
        $milestone = Milestone::where('id', $this->milestoneId)
            ->first();

        $user = User::where('id', auth()->id())
            ->first();

        $user->milestones()->attach($milestone);

    }

    public function unMark()
    {
        $milestone = Milestone::where('id', $this->milestoneId)
            ->first();

        $user = User::where('id', auth()->id())
            ->first();

        $user->milestones()->detach($milestone);

    }

    public function render()
    {
        return view('livewire.check-milestone');
    }
}

My requirement is execute mark() method when the checkbox is unchecked and execute unMark() when the checkbox is checked

I tried below but didn't work

<div class="mr-3">
    <input type="checkbox" name="milestoneMark" value="{{ $milestoneId }}" x-model="milestone" {!!  'checked' ? wire:click="mark()" : wire:click="unMark()" !!} >
</div>

I try to use as less JavaScript as possible so if you can please give me a solution without JS, but if there isn't any other way to fix this I'm okay to use JS. TIA!

Upvotes: 2

Views: 5606

Answers (2)

TsuLee
TsuLee

Reputation: 1

Or you can use wire:model.live="milestoneMark" to send live value to livewire component and then intercept the new value on change using the Lifecycle function updatedMilestoneMark() then you do your stuff depending on the $milestoneMark value

Lifecycle Hooks : https://laravel-livewire.com/docs/2.x/lifecycle-hooks

Live-updating fields: https://livewire.laravel.com/docs/forms#live-updating-fields

Good luck!

Upvotes: 0

Yinci
Yinci

Reputation: 2480

You have nothing to base your checked situation from. I personally would do the following:

class CheckMilestone extends Component
{

    public $milestoneId;
    public bool $checked = false;

    public function processMark()
    {
        if ($this->checked) {
            $this->mark();
        } else {
            $this->unMark();
        }

    }

    // Rest of your code here
}
<div class="mr-3">
    <input type="checkbox" wire:model="checked" wire:change="processMark()" wire:loading.attr="disabled">
</div>

To explain; we use wire:model to link the value of the checkbox to the Livewire component. We use wire:change to detect the change event triggered when you (de)select the checkbox, and fire the processMark method. Purposely we don't change the HTML as to not cause unexpected behaviour. We use wire:loading to add the disabled attribute while the checked variable is being updated, so we can't quickly uncheck it while it's processing.

Upvotes: 6

Related Questions