-
-
Save blackfyre/ccd2a207948912594b5ac6cf67a11ef8 to your computer and use it in GitHub Desktop.
<template> | |
<modal @modal-close="handleClose"> | |
<form | |
@submit.prevent="handleConfirm" | |
slot-scope="props" | |
class="bg-white rounded-lg shadow-lg overflow-hidden" | |
style="width: 460px" | |
> | |
<slot :uppercaseMode="uppercaseMode" :mode="mode"> | |
<div class="p-8"> | |
<heading :level="2" class="mb-6">{{ __('General Modal') }}</heading> | |
<p class="text-80 leading-normal">{{__('General modal contents')}}</p> | |
</div> | |
</slot> | |
<div class="bg-30 px-6 py-3 flex"> | |
<div class="ml-auto"> | |
<button type="button" data-testid="cancel-button" dusk="cancel-general-button" @click.prevent="handleClose" class="btn text-80 font-normal h-9 px-3 mr-3 btn-link">{{__('Cancel')}}</button> | |
<button id="confirm-delete-button" ref="confirmButton" data-testid="confirm-button" type="submit" class="btn btn-default btn-danger">{{ __(uppercaseMode) }}</button> | |
</div> | |
</div> | |
</form> | |
</modal> | |
</template> | |
<script> | |
export default { | |
name: "GeneralModal", | |
methods: { | |
handleClose() { | |
this.$emit('close') | |
}, | |
handleConfirm() { | |
this.$emit('confirm') | |
}, | |
}, | |
/** | |
* Mount the component. | |
*/ | |
mounted() { | |
this.$refs.confirmButton.focus() | |
}, | |
} | |
</script> | |
<style scoped> | |
</style> |
<template> | |
<div> | |
<button @click="openModal">{{__('Open Modal')}}</button> | |
<portal to="modals"> | |
<transition name="fade"> | |
<general-modal | |
v-if="modalOpen" | |
@confirm="confirmModal" | |
@close="closeModal" | |
/> | |
</transition> | |
</portal> | |
</div> | |
</template> | |
<script> | |
import GeneralModal from './parts/modals/GeneralModal.vue'; | |
export default { | |
props: ["resourceName", "resourceId", "field"], | |
data() { | |
return { | |
modalOpen: false | |
} | |
}, | |
components: { | |
GeneralModal | |
}, | |
mounted() { | |
}, | |
methods: { | |
openModal() { | |
this.modalOpen = true; | |
}, | |
confirmModal() { | |
this.modalOpen = false; | |
}, | |
closeModal() { | |
this.modalOpen = false; | |
} | |
} | |
}; | |
</script> |
Hello everyone, today i face one problem that I can't use improted component inside this <modal>
tag, maybe I do something wrong, I wanted to use vuedraggable to make some functionality inside my project, but i couldn't because <draggable>
tag is not initialize like draggable component. After I tried to make my own component just with test content like "Hello world" and import that component and use it inside <modal>
tag, the same result. Laravel Nova
If i need two modals in my tool.vue, i need to make two but this does not work I mean if i have two components GeneralModal and TableModal both using difference betwen componentes is only the contenu in the Nova modal's slot, how could I have two modals ?
thanks for this mehn
Thank you for your sharing; I fixed it for Nova 4 like this:
Similar to your implementation but changed to match laravel/nova/resources/js/components/Modals/DeleteResourceModal.vue
GeneralModal.vue
<template>
<Modal @modal-close="handleClose"
:show="show"
role="alertdialog"
size="sm">
<form
@submit.prevent="handleConfirm"
class="mx-auto bg-white dark:bg-gray-800 rounded-lg shadow-lg overflow-hidden"
>
<slot/>
<ModalFooter>
<div class="ml-auto">
<LinkButton
type="button"
data-testid="cancel-button"
dusk="cancel-delete-button"
@click.prevent="handleClose"
class="mr-3"
>
{{ __('Cancel') }}
</LinkButton>
<LoadingButton
ref="confirmButton"
dusk="confirm-delete-button"
:processing="working"
:disabled="working"
component="DangerButton"
type="submit"
>
{{ confirmButtonText }}
</LoadingButton>
</div>
</ModalFooter>
</form>
</Modal>
</template>
<script setup>
import {ref, watchEffect} from 'vue'
const props = defineProps({
confirmButtonText: {
type: String,
default: 'Delete'
}
})
const emit = defineEmits(['close', 'confirm'])
const confirmButton = ref(null)
watchEffect(() => {
// Only focus when mounted (e.g. if hidden through :show)
if (confirmButton.value) {
confirmButton.value.focus()
}
})
const handleClose = () => {
emit('close')
};
const handleConfirm = () => {
emit('confirm')
};
</script>
Tool.vue
...
<GeneralModal
:show="modalOpen"
confirmButtonText="Delete"
@close="closeModal"
@confirm="confirmModal">
<ModalHeader>Delete resource</ModalHeader>
<ModalContent>
<p class="leading-normal">
Are you sure you want to delete the resource?
</p>
</ModalContent>
</GeneralModal>
...
@bmoex thanks for the snippet. any idea how to trigger the auto close on click away functionality? I can see that Nova 4 native modals have it
@bmoex thanks for the snippet. any idea how to trigger the auto close on click away functionality? I can see that Nova 4 native modals have it
You really can't do that without modifying the nova code as it usually involves a click listener on the backdrop.
@henryavila
Thanks for the background, this puts things into perspective 😄
Haven't developed a Card before, but the match between the Card & Tool vue files seems reasonable.
As for placing the
GeneralModal.vue
file is totally up to you! At some point, you'll have to reference it in your card vue file.