UI Improvements using Livewire

In this Tutorial, we will see how to update Button UI when the Form is submitted or button is clicked like below GIF using Livewire. This is similar to how Github handles form action on its website.

If you are using Breeze or Jetstream package, it come up with a button component which you can use like below:

    <x-button wire:click="verify">
        Verify
    </x-button>

This will show above output to the User. And when you click the button, verify method of the component will be fired. However, there is no Feedback to the User.

We can tell Livewire to include disabled property when the Button is clicked using wire:loading.attr

    <x-button wire:click="verify" wire:loading.attr="disabled">
        Verify
    </x-button>

This disabled property will be added as soon as the button is clicked and removed automatically when the AJAX Call is completed. Because we are using the button component provided by Breeze or Jetstream, a CSS Property which changes the opacity will automatically be added like below.

We can even change the Text of the Button as long as it is disabled. In order to do so, we will use Livewire Property called wire:loading. You can wrap any element within this Property and it will only be shown when the AJAX Call is in progress.

    <x-button wire:click="verify" wire:loading.attr="disabled"> 
        Verify
        <span wire:loading>
            Verifying...
        </span>
    </x-button>

So Verifying... Text will be shown as long as the AJAX Call is in progress. We also want to hide Verify Text when the AJAX Call is in progress. We can do so using wire:loading.remove, which removes an element when AJAX Call is in progress.

    <x-button wire:click="verify" wire:loading.attr="disabled"> 
        <span wire:loading.remove>
                Verify
            </span>
        <span wire:loading>
            Verifying...
        </span>
    </x-button>

Now our button gives the following output when it is clicked.

This way the User gets a nice feedback when he clicks the button as the Opacity and Text changes during the progress of the AJAX Call. And moreover the button is also disabled so User can not click on it twice accidentally.

However, lets say we have 2 such buttons on the page like below:

    <x-button wire:click="verify" wire:loading.attr="disabled"> 
        <span wire:loading.remove>
                Verify
            </span>
        <span wire:loading>
            Verifying...
        </span>
    </x-button>
    
    <x-button wire:click="deleteProject" wire:loading.attr="disabled">
        <span wire:loading.remove>
            Remove
            </span>
        <span wire:loading>
            Removing...
        </span>
    </x-button>

Now, we will run into issue that if we click on Verify Button, it will get disabled and its text will also change. However, you will notice that text of other button also changes from Remove to Removing. Same issue happens when you click on 2nd Button.

Fortunately, Livewire provides an easy way to fix this using wire:target. Using this property you can explicitly tell Livewire when to implement wire:loading and wire:loading.remove. So for the Verify Button we only want Loading Indicators to change when verify method is called. We can do so using below:

wire:target="verify"

Similarly for Remove button we can specify wire:target as below:

wire:target="deleteProject"

Our final HTML now becomes like below:

    <x-button wire:click="verify" wire:loading.attr="disabled"> 
        <span wire:loading.remove wire:target="verify">
            Verify
        </span>
        <span wire:loading wire:target="verify">
            Verifying...
        </span>
    </x-button>
    
    <x-button wire:click="deleteProject" wire:loading.attr="disabled">
        <span wire:loading.remove wire:target="deleteProject">
            Remove
            </span>
        <span wire:loading wire:target="deleteProject">
            Removing...
        </span>
    </x-button>

We can even implement the wire:loading and wire:loading.remove when the Form is submitted. We just need to specify the wire:target with same action as Form Submit. So in below HTML, we are calling the method formSubmit when the Form is submitted and we are specifying the same as wire:target.

    <form wire:submit.prevent="formSubmit">
        .
        .
        .
        <x-button wire:loading.attr="disabled" wire:target="formSubmit">
            <span wire:loading.remove wire:target="formSubmit">
                Submit
            </span>
            <span wire:loading wire:target="formSubmit">
                Submitting...
            </span>
        </x-button> 
    </form>

This will give us the same output as the Image at the start of the Tutorial.

Hope you have enjoyed this tutorial.

Leave a Reply

Your email address will not be published. Required fields are marked *