9

I'm using Laravel Livewire in my project, I use wire:loading for loading the state while clicking. I iterated all the tasks in foreach loop but the loading state applies for all components. Here is the code.

enter image description here

Blade file

GitLab: https://gitlab.com/tasklog/tasklog/-/blob/master/resources/views/livewire/home/tasks.blade.php

<button type="button" wire:click="togglePraise({{ $task->id }}, {{ $task->user->id }})">
    
    <span class="small text-black-50 font-weight-bold">
        {{ $task->task_praise->count() }}
    </span>
    <div wire:loading wire:target="togglePraise">
        Processing...
    </div>
</button>

Controller file

GitLab: https://gitlab.com/tasklog/tasklog/-/blob/master/app/Http/Livewire/Home/Tasks.php

public function togglePraise($id, $user_id)
{
    if (Auth::check()) {
        if (Auth::user()->id === $user_id) {
            session()->flash('message', 'Forbidden!');

            return;
        }
        $isPraised = TaskPraise::where([
            ['user_id', Auth::user()->id],
            ['task_id', $id],
        ])->count();
        if ($isPraised === 1) {
            TaskPraise::where([
                ['user_id', Auth::user()->id],
                ['task_id', $id],
            ])->delete();

            return true;
        } else {
            TaskPraise::create([
                'task_id' => $id,
                'user_id' => Auth::user()->id,
            ]);

            return true;
        }
    } else {
        return session()->flash('message', 'Forbidden!');
    }
}
Yogi
  • 609
  • 1
  • 8
  • 21

3 Answers3

4

I know the question was before the realease of v2, yet adding the answer for v2 for reference.

as per the Livewire docs if you're using v2, you may specify the action and its parameters in the wire:target directive. For your example, it would be like this:

wire:target="togglePraise({{ $task->id }}, {{ $task->user->id }})"
Fahd Yousri
  • 401
  • 3
  • 12
0

I was unable to do it by loading targets to actions with parameters so I used jquery with the livewire

Button in the table loop with default d-none loading icon class

  <div class="col-3">
    <button  class="btn btn-sm btn-default btn-save ">
     Save <span class="loading-icon d-none">
     <i class="fa fa-circle-o-notch fa-spin" style="font-size:14px"></i></span> 
 </button></div>

Javascript code to call livewire and enable loading

$('.btn-save').click(function (e) {
  e.preventDefault();
  $('.parameter-value').removeClass("error-field");
  var row  = $(this).closest('tr');
  row.find('.loading-icon').removeClass('d-none');
  var parameter = row.data('parameter');
  var value = $.trim(row.find('.parameter-value').val())
  if(value == ""){
     row.find('.parameter-value').addClass('error-field');
   }else{
     row.find('.parameter-value').removeClass('error-field');
    //Livewire call
    @this.addParameterValue(parameter,value);
   }
});

before LiveWire function ends dispatch browser event

public function addParameterValue($parameterID,$value)
{
    ...
    $this->dispatchBrowserEvent('parameter_value-saved');
}

Handle Browser event from javascript end and remove hide loading icon inside

 window.addEventListener('parameter_value-saved', event => {
     $('.loading-icon').addClass('d-none');
 })
Pravin Shinde
  • 271
  • 1
  • 3
  • 15
0

I had the same issue as you. After researching, I decided to make 2 wire:click, IDK if this is the best way to solve this but yeah that's what I do

<div wire:loading wire:target="LoadingAnimation({{$loop->iteration}})">
   // icon loading or teks for showing this row load sth
</div>

......

<div wire:click="LoadingAnimation({{$loop->iteration}})">
   <a wire:click="setUpdateid({{$author->id}})">
     // your content here , teks or maybe an icon
   </a>
</div>

If you have any questions let me know, Happy coding!

Edit: Don't forget to make the method inside the class, like the LoadingAnimation and the setUpdateid

m4n0
  • 29,823
  • 27
  • 76
  • 89
christmex
  • 91
  • 1
  • 10