UI Improvements using Livewire
Tags: laravel, livewire
Published: 2021-05-27 13:09:50

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

![Preview](https://media.giphy.com/media/SCo3ff6YfIQRfMnDrP/giphy.gif)

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

```
    <x-button wire:click="verify">
        Verify
    </x-button>
```
![Verify](http://www.ascsoftwares.com/wp-content/uploads/2021/05/image-1.png)

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 when the button is clicked.

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.

![Verify Disabled](http://www.ascsoftwares.com/wp-content/uploads/2021/05/image.png)

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.

![Verifying](http://www.ascsoftwares.com/wp-content/uploads/2021/05/image-2.png)

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. For similar articles, you can follow me on [Twitter](https://twitter.com/TheLaravelDev)