Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Lee989's avatar
Level 1

wire:dirty.remove.attr AND isDirty

First time using Livewire, i've got a super simple component for updating a string $value using a textarea and save button. It also has a preview() action which swaps the textarea out for a div containing Str::markdown($value)

The component has a save() action for storing to the database, and the save button is disabled until $value is dirty via:

wire:dirty.remove.attr="disabled"

The problem I have is that when I click to preview, the textarea value is synced to the $value, so as far as livewire is concerned it is not dirty, and the button get's disabled when re-rendering the component.

What I need is a way to detect if either the wire property is dirty, or if the property has not been saved. I added a public bool $isDirty to the component to track the database side of things.

<button
  wire:dirty.remove.attr="disabled"
  {{ ! $isDirty ? 'disabled' : ' ' }}
>

Whilst I can see in network requests that the HTML does not contain disabled when previewing a change (this is correct behaviour). Livewire takes over and adds the disabled attribute as a result of wire:dirty.remove.attr

This seems like it should be a simple thing to do. But i'm at a loss.

TLDR; I want to control the disabled attribute based on both wire:dirty AND component property isDirty... How?

0 likes
2 replies
Lee989's avatar
Level 1

I managed to find a solution, although the difficulty of such a simple thing doesn't instil in me a great deal of confidence to commit to Livewire for anything but playground projects. Hopefully, it's a learning curve issue though.

For anyone that needs an albeit horrible solution, a truncated version of my component containing the important bits:

class MyComponent extends Component 
{
   public string $content = '';
   public bool $isDirty = false;

   public function updated($property)
    {
        if ($property == 'content') {
            $this->isDirty = true;
        }
    }

   public function save() 
   {
       saveValueToDb($this->content);
       $this->isDirty = false;
   }
}
<button
            x-data="{
                dbDirty: $wire.entangle('isDirty'),
                get wireDirty() {
                    return (
                        $wire.__instance.canonical.content !==
                        $wire.__instance.reactive.content
                    )
                },
                get isDirty() {
                    return this.wireDirty || this.dbDirty
                },
            }"
            type="submit"
            class="some-tw-classes disabled:opacity-25"
            x-bind:disabled="!isDirty"
        >
            Save Changes
        </button>
1 like

Please or to participate in this conversation.