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

nam_co's avatar

Disable submit button Livewire Validation

Hi, Im using livewire Real-time Validation for each field and it works, but I haven't been able to disable the submit btn until all fields are validated

 public $name;
 public $email;
 public $disabled = true;

    protected $rules = [
        'name' => 'required|min:6',
        'email' => 'required|email',
    ];

    //Individual validation
    public function updated($propertyName)
    {
        $this->validateOnly($propertyName);
    }

    public function submit()
    {
        $this->validate();
	//SUBMIT
     }

where can I put "$this->disabled = false;" to allow the user to press submit

Appreciate any help thanks

0 likes
17 replies
nam_co's avatar

I tried this and it works but, it shows all the error messages of the fields once I do the first one, not good

public function updated($propertyName)
    {
        $this->disabled = true;
        $this->validateOnly($propertyName);
	//checking to show the submit button
        $validated = $this->validate(); //shows all errors
        $this->disabled = false;
    }
chaudigv's avatar

Simply add this to your submit button wire:loading.attr="disabled". You don't need additional boolean variable to do so.

Check livewire loading states for more info.

vladimir's avatar

@chaudigv And how that disables submit button? This disabling button only when form has been clicked, or processed.

nam_co's avatar

Hi chaudigv thanks for the answer, but that will only disable the button while livewire is updating something, no really if the whole form is validated

cristache's avatar

@nam_co Did you find a solution to disable the submit button until form is filled and valid? I'm interested in a solution, too. Thanks.

cristache's avatar

Hello, I did something like this and it works ok for me:

	public $isDisabled = true;

    public function updated($propertyName)
    {
        $this->validateOnly($propertyName);

		// Create an array with all your props
        $props = ['prop1', 'prop2', 'prop3', 'prop4']; 
        $errors = array_filter($props, fn($prop) => empty($this->$prop));

        if(count($errors) == 0) $this->isDisabled = false;
    }

Hope it will help you :)

nam_co's avatar

Hi @cristache , I did this baby setting the variable btn_submit to 1 (disabled) 2 (user can submit) 3 (submitting)

    public function updated($propertyName)
    {
        $this->validateOnly($propertyName);
        $this->validate();
        $this->btn_submit = 2;
    }


    public function submit()
    {
        $this->validate();
        $this->btn_submit = 3;
		$this->user->name = $this->name;
        $this->user->update();
        $this->btn_submit = 1;
    }
1 like
nam_co's avatar

Hi cristache, Sorry I just saw your question, I did kind of find a way, I will search for it and post it... but is not the cleanest way

1 like
JKB's avatar

Hello, this is my solution, no need of calling $this->validate(); inside updated.

public $name;
public $email;

// Array to save the valid state of all the inputs to validate. False by default.
public $valid = ["name" => false, "email" => false];

// Used to enable/disable the submit button
public $can_submit = false;

protected $rules = [
    'name' => 'required|string|max:255',
    'email' => 'required|email|max:255',
];

public function updated($propertyName)
{
    //can_submit is false if validation fails 
    $this->can_submit = false;

    $this->valid[$propertyName] = false;
    $this->validateOnly($propertyName);

    //This input is valid
    $this->valid[$propertyName] = true;

    //We can submit if all inputs are valid
    $this->can_submit = true;
    foreach($this->valid as $property) {
        if(!$property) {
            $this->can_submit = false;
            break;
        }
    }
}

In view:

<button type="submit" class="btn btn-success float-right" {{ $can_submit ? '' : 'disabled' }}>
        <i wire:loading wire:target='submitForm' class="fas fa-spin fa-spinner mr-2"></i> Envoyer
</button>
1 like
superbiche's avatar

Found an elegant way of doing it without displaying every error that $this->validate() triggers:

(I'm using constants from a ButtonState class, DISABLED = 0, ENABLED = 1, LOADING = 2, ymmv)

public int $buttonState;

public function mount(Property $property): void
{
    $this->buttonState = ButtonState::STATE_DISABLED;
}

public function updated($propertyName)
{
    $this->validateOnly($propertyName);
    try {
        // Validate in a try/catch block to intercept the validation error.
        $this->validate();
        // If no exception was thrown, the form is valid, so we enable the button.
        $this->buttonState = ButtonState::STATE_ENABLED;
    } catch (ValidationException $e) {
        // If the global validation failed, keep the button disabled.
        $this->buttonState = ButtonState::STATE_DISABLED;
    }
}

public function submit(): void
{
    $data = $this->validate();
    $this->buttonState = ButtonState::STATE_LOADING;
    // Submit the form, then you probably want to enable it again.
    $this->buttonState = ButtonState::STATE_ENABLED;
}

Then in your Blade template:

<button
    type="submit"
    class="btn {{ $buttonState === \App\Constants\ButtonState::STATE_LOADING ?  'is-loading'  :  ''  }}
    {{ $buttonState === \App\Constants\ButtonState::STATE_DISABLED ? 'disabled' : '' }}
>
    {{ __('Submit') }}
</button>
1 like
Slon's avatar
<button type="submit" @if($errors->any()) disabled @endif>Save</button>
2 likes
gilesbennett's avatar

@jlzandrad Not really - it doesn't disable the button on first load (when, technically, the form is invalid).

1 like
vladimir's avatar

@Slon this is not correct. When you have empty form - upon anding on form page, button will be enabled.

alfrednutile's avatar

I tried that but still had the error. It seemed to confuse the out @if @endif in the page.

I ended up with this

<x-primary-button-dark
		<x-primary-button-dark
                                type="button" wire:click="openModalProxy('bulk-import-remove-modal')"
                                :disabled="count($selected) < 1"
                            >Remove
 </x-primary-button-dark>

The primary-button-dark.blade.php just happens to be simple like this

<button
    {{ $attributes->merge(['type' => 'submit',
        'class' => 'inline-flex items-center
        uppercase
        tracking-widest
        bg-primary px-2.5 py-2.5
        text-md disabled:bg-teal-400
        font-medium hover:bg-teal-700 text-white
        focus:outline-none focus:ring-2
        disabled:opacity-20
        focus:ring-teal-700 focus:ring-offset-2']) }}
>
    {{ $slot }}
</button>

da_Mask's avatar

@alfrednutile You might have better luck if you wrap your disable evaluation inside double curly braces, so :

  :disabled="{{count($selected) < 1}}"
1 like
mfodor's avatar

My solution is:

Action::make('save')
    ...
    ->disabled(function () {
        try {
            $this->validate();

            return false;
        } catch (\Throwable) {
            return true;
        }
    }),

Please or to participate in this conversation.