Search code examples
laravellaravel-livewire

Livewire temporarily disable action


What's the best way of preventing an action temporarily while something else is happening?

E.g a slow file upload and prevent the action 'store' from being submitted.

Tried using a public property but this is too slow.

<form wire:submit.prevent="store" enctype="multipart/form-data">
    <x-forms.filepond wire:model="file_upload" />

    <button wire:click.prevent="store" wire:loading.attr="disabled">
        <x-loader wire:loading wire:target="store" class="full-current mr-2 h-4 w-4" />
        <x-icons.save wire:loading.remove wire:target="store" class="full-current mr-2 h-4 w-4" />
        Save
    </button>
</form>

Solution

  • This is how I achieved with AlpineJS

    filepond component,

    @props(['key'])
    <div
            wire:ignore
            x-data
            x-init="
            () => {
                const pond = FilePond.create(document.getElementById('{{ $key }}'));
                pond.setOptions({
                    credits: false,
                    disabled: {{ $attributes->has('disabled') ? 'true' : 'false' }},
                    allowMultiple: {{ $attributes->has('multiple') ? 'true' : 'false' }},
                    server: {
                        process:(fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
                            @this.upload('{{ $key }}', file, load, error, progress)
                        },
                        revert: (filename, load) => {
                            @this.removeUpload('{{ $key }}', filename, load)
                        },
                    },
                    allowImagePreview: {{ $attributes->has('allowFileTypeValidation') ? 'true' : 'false' }},
                    imagePreviewMaxHeight: {{ $attributes->has('imagePreviewMaxHeight') ? $attributes->get('imagePreviewMaxHeight') : '256' }},
                    allowFileTypeValidation: {{ $attributes->has('allowFileTypeValidation') ? 'true' : 'false' }},
                    acceptedFileTypes: {!! $attributes->get('acceptedFileTypes') ?? 'null' !!},
                    allowFileSizeValidation: {{ $attributes->has('allowFileSizeValidation') ? 'true' : 'false' }},
                    maxFileSize: {!! $attributes->has('maxFileSize') ? "'".$attributes->get('maxFileSize')."'" : 'null' !!},
                    onaddfilestart: function(file) { submitButtonDisabled = true },
                    onprocessfiles: function() { submitButtonDisabled = false },
                    onupdatefiles: function (files) {
                        fileStatus = true;
                        files.forEach(function (file) {
                            if(file.status != 5) fileStatus = false;
                        });
                        if(fileStatus) submitButtonDisabled = false;
                    },
                });
                this.addEventListener('reset-pond', e => {
                    pond.removeFiles();
                });
            }
        "
    >
        <input type="file" id="{{ $key }}"/>
    </div>
    <x-inputs.error field="{{ $attributes->has('multiple') ? $key . '.*' : $key }}"/>
    

    (basically look at onaddfilestart, onprocessfiles, onupdatefiles filepond events)

    Then on the file upload component,

    1. add this to the root div x-data="{ submitButtonDisabled: false}"
    2. add this to the submit button x-bind:disabled="submitButtonDisabled"