Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you use confirm dialogues in a custom Laravel Nova tool?

Is it possible to use the built in Laravel Nova confirm dialogue in your own tool? All I would like to use is interact with it how Nova does itself.

The docs are quite light on the JS topic, as the only built in UI you seem to be able to work with is the toasted plugin: https://nova.laravel.com/docs/1.0/customization/frontend.html#javascript

Built in Laravel Nova confirm dialogue

like image 424
Thomas Nadin Avatar asked Feb 22 '19 09:02

Thomas Nadin


1 Answers

You can use <modal> component whenever you want.

Here is how it work internally in Nova:

<template>
    <modal
        data-testid="confirm-action-modal"
        tabindex="-1"
        role="dialog"
        @modal-close="handleClose"
        class-whitelist="flatpickr-calendar"
    >
        <form
            autocomplete="off"
            @keydown="handleKeydown"
            @submit.prevent.stop="handleConfirm"
            class="bg-white rounded-lg shadow-lg overflow-hidden"
            :class="{
                'w-action-fields': action.fields.length > 0,
                'w-action': action.fields.length == 0,
            }"
        >
            <div>
                <heading :level="2" class="border-b border-40 py-8 px-8">{{ action.name }}</heading>

                <p v-if="action.fields.length == 0" class="text-80 px-8 my-8">
                    {{ __('Are you sure you want to run this action?') }}
                </p>

                <div v-else>
                    <!-- Validation Errors -->
                    <validation-errors :errors="errors" />

                    <!-- Action Fields -->
                    <div class="action" v-for="field in action.fields" :key="field.attribute">
                        <component
                            :is="'form-' + field.component"
                            :errors="errors"
                            :resource-name="resourceName"
                            :field="field"
                        />
                    </div>
                </div>
            </div>

            <div class="bg-30 px-6 py-3 flex">
                <div class="flex items-center ml-auto">
                    <button
                        dusk="cancel-action-button"
                        type="button"
                        @click.prevent="handleClose"
                        class="btn text-80 font-normal h-9 px-3 mr-3 btn-link"
                    >
                        {{ __('Cancel') }}
                    </button>

                    <button
                        ref="runButton"
                        dusk="confirm-action-button"
                        :disabled="working"
                        type="submit"
                        class="btn btn-default"
                        :class="{
                            'btn-primary': !action.destructive,
                            'btn-danger': action.destructive,
                        }"
                    >
                        <loader v-if="working" width="30"></loader>
                        <span v-else>{{ __('Run Action') }}</span>
                    </button>
                </div>
            </div>
        </form>
    </modal>
</template>

<script>
export default {
    props: {
        working: Boolean,
        resourceName: { type: String, required: true },
        action: { type: Object, required: true },
        selectedResources: { type: [Array, String], required: true },
        errors: { type: Object, required: true },
    },
    /**
     * Mount the component.
     */
    mounted() {
        // If the modal has inputs, let's highlight the first one, otherwise
        // let's highlight the submit button
        if (document.querySelectorAll('.modal input').length) {
            document.querySelectorAll('.modal input')[0].focus()
        } else {
            this.$refs.runButton.focus()
        }
    },
    methods: {
        /**
         * Stop propogation of input events unless it's for an escape or enter keypress
         */
        handleKeydown(e) {
            if (['Escape', 'Enter'].indexOf(e.key) !== -1) {
                return
            }
            e.stopPropagation()
        },
        /**
         * Execute the selected action.
         */
        handleConfirm() {
            this.$emit('confirm')
        },
        /**
         * Close the modal.
         */
        handleClose() {
            this.$emit('close')
        },
    },
}
</script>

Here is simplified example:

<modal>
    <form
            autocomplete="off"
            class="bg-white rounded-lg shadow-lg overflow-hidden"
    >
        <div>
            <heading :level="2" class="border-b border-40 py-8 px-8">test</heading>
            test
        </div>
        <div class="bg-30 px-6 py-3 flex">
            <div class="flex items-center ml-auto">
                <button
                        type="button"
                        class="btn text-80 font-normal h-9 px-3 mr-3 btn-link"
                >
                    {{ __('Cancel') }}
                </button>

                <button
                        ref="runButton"
                        type="submit"
                        class="btn-danger"
                >
                    <span>{{ __('Run Action') }}</span>
                </button>
            </div>
        </div>
    </form>
</modal>

like image 185
Sanasol Avatar answered Oct 05 '22 02:10

Sanasol