Skip to content

Instantly share code, notes, and snippets.

@eolant eolant/Confirm.vue
Last active Nov 14, 2019

Embed
What would you like to do?
Vuetify Confirm Dialog component that can be used locally or globally
<template>
<v-dialog v-model="dialog" :max-width="options.width" :style="{ zIndex: options.zIndex }" @keydown.esc="cancel">
<v-card>
<v-toolbar dark :color="options.color" dense flat>
<v-toolbar-title class="white--text">{{ title }}</v-toolbar-title>
</v-toolbar>
<v-card-text v-show="!!message" class="pa-4">{{ message }}</v-card-text>
<v-card-actions class="pt-0">
<v-spacer></v-spacer>
<v-btn color="primary darken-1" text @click.native="agree">Yes</v-btn>
<v-btn color="grey" text @click.native="cancel">Cancel</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
/**
* Vuetify Confirm Dialog component
*
* Insert component where you want to use it:
* <confirm ref="confirm"></confirm>
*
* Call it:
* this.$refs.confirm.open('Delete', 'Are you sure?', { color: 'red' }).then((confirm) => {})
* Or use await:
* if (await this.$refs.confirm.open('Delete', 'Are you sure?', { color: 'red' })) {
* // yes
* }
* else {
* // cancel
* }
*
* Alternatively you can place it in main App component and access it globally via this.$root.$confirm
* <template>
* <v-app>
* ...
* <confirm ref="confirm"></confirm>
* </v-app>
* </template>
*
* mounted() {
* this.$root.$confirm = this.$refs.confirm.open
* }
*/
export default {
data: () => ({
dialog: false,
resolve: null,
reject: null,
message: null,
title: null,
options: {
color: 'primary',
width: 290,
zIndex: 200
}
}),
methods: {
open(title, message, options) {
this.dialog = true
this.title = title
this.message = message
this.options = Object.assign(this.options, options)
return new Promise((resolve, reject) => {
this.resolve = resolve
this.reject = reject
})
},
agree() {
this.resolve(true)
this.dialog = false
},
cancel() {
this.resolve(false)
this.dialog = false
}
}
}
</script>
@Izopi4a

This comment has been minimized.

Copy link

Izopi4a commented Mar 12, 2018

awesome, thanks

@joaovieirabr

This comment has been minimized.

Copy link

joaovieirabr commented Mar 24, 2018

Thanks. Helped me a lot.

@Dacredible

This comment has been minimized.

Copy link

Dacredible commented Apr 10, 2018

Nice work

@PatrLind

This comment has been minimized.

Copy link

PatrLind commented Apr 17, 2018

Perfect!

@mohammed-io

This comment has been minimized.

Copy link

mohammed-io commented Apr 21, 2018

It's awesome!

But it has a little issue, it doesn't trigger reject at all

cancel() {

    this.resolve(false); <---- it should be reject

    this.dialog = false;

}
@eolant

This comment has been minimized.

Copy link
Owner Author

eolant commented Apr 22, 2018

@mohammed-io thank you for your comment, but I would disagree on this as reject should handle errors that occur in the Promise handler. I think confirm dialog should resolve to true or false value as standard JS confirm function does rather than having false case in an error callback.

@Christilut

This comment has been minimized.

Copy link

Christilut commented May 10, 2018

Thanks for this! I prefer the reject way also, but it's personal I guess :)

@karljacques

This comment has been minimized.

Copy link

karljacques commented May 12, 2018

Thanks, this was helpful.

In the description to use this globally, I think this part:

mounted() {
   *   this.$root.$confirm = this.$refs.confirm.open;`

Should actually be this:

mounted() {
   *   this.$root.$confirm = this.$refs.confirm;
@eolant

This comment has been minimized.

Copy link
Owner Author

eolant commented May 13, 2018

@karljacques Thanks for the comment :) It's probably a matter of preference. Since it has only one method I thought it's a bit easier to call it with just this.$root.$confirm(title, message, options).then(confirm => {})

@ibanjo

This comment has been minimized.

Copy link

ibanjo commented Jun 4, 2018

Great one, really!

@nizantz

This comment has been minimized.

Copy link

nizantz commented Jun 9, 2018

Awesome. This helped!!

@jshowatt

This comment has been minimized.

Copy link

jshowatt commented Jul 23, 2018

This is great! Thanks for sharing.

@Peraluna

This comment has been minimized.

Copy link

Peraluna commented Aug 3, 2018

Very good!!! Simple and it works!

@sergiofactvs

This comment has been minimized.

Copy link

sergiofactvs commented Oct 7, 2018

Guys, you must setup the z-index prop, for confirm in dialogs forms.

@eolant

This comment has been minimized.

Copy link
Owner Author

eolant commented Nov 8, 2018

@sergiofactvs Sorry, took me a while to get this sorted. I've added a parameter for z-index.

@tripflex

This comment has been minimized.

Copy link

tripflex commented Dec 8, 2018

@eolant thanks this is awesome! Created a component from this I called DialogLoader that I use along with this one, to handle showing a loader and snackbar when performing actions:

https://gist.github.com/tripflex/19760cdb19260f95412dc751f9c37e79

@circlefind

This comment has been minimized.

Copy link

circlefind commented Jan 12, 2019

Error use await:

if (await this.$refs.confirm.open('Delete', 'Are you sure?', { color: 'red' })) {
}
else {
}

@eolant

This comment has been minimized.

Copy link
Owner Author

eolant commented Jan 14, 2019

@circlefind thanks for your comment. Can you please be more specific in what kind of error you found and what versions of libraries are you using? One suggestion though is to make sure that function you're calling this method in have async keyword e.g. async mounted().

@GibranLara

This comment has been minimized.

Copy link

GibranLara commented Jan 21, 2019

Thank you!

@claudiojuniorfabiao

This comment has been minimized.

Copy link

claudiojuniorfabiao commented Mar 18, 2019

Muito bom, obrigado pelo exemplo!

@lemon5920

This comment has been minimized.

Copy link

lemon5920 commented Mar 22, 2019

Awesome! It's very helpful.

@sergevdz

This comment has been minimized.

Copy link

sergevdz commented Apr 7, 2019

Thank you so much!!!

@Yogi-p

This comment has been minimized.

Copy link

Yogi-p commented May 2, 2019

getting error as "Property 'open' does not exist on type 'Vue | Element | Vue[] | Element[]'.
Property 'open' does not exist on type 'Vue'"

@eolant

This comment has been minimized.

Copy link
Owner Author

eolant commented May 6, 2019

@Yogi-p thanks for your comment, I can't seem to be able to reproduce your issue. Can you please double check if you using it according to the instructions provided and if you still have the error, can you please set up a sandbox for me to check?

@cdecinkoKnight

This comment has been minimized.

Copy link

cdecinkoKnight commented May 31, 2019

How would I call this from a delete v-icon on a row of data in a Vuetify data table?

@HizkiasAbraham

This comment has been minimized.

Copy link

HizkiasAbraham commented Jun 7, 2019

Thanks, it worked for me...

@martinkrulltott

This comment has been minimized.

Copy link

martinkrulltott commented Jun 11, 2019

Thanks, love this solution. Should really be part of the official docs.

@eolant

This comment has been minimized.

Copy link
Owner Author

eolant commented Jun 19, 2019

@cdecinkoKnight in theory you would bind v-icon's @click event to a method and then call dialog from it as shown in examples in the comments.

@fabionfd

This comment has been minimized.

Copy link

fabionfd commented Oct 8, 2019

I'm trying to use this on Nuxt,
imported the component and placed it on my default layout, but no success, getting the same error as @Yogi-p . Anyone ever did it?

@eolant

This comment has been minimized.

Copy link
Owner Author

eolant commented Oct 9, 2019

@fabionfd as this is not in TS, you might struggle a bit to converting it to TS. I didn't make it work all the way, but here is an example how to get rid of this error: https://codesandbox.io/embed/example-options-api-minimal-xt21i

@rom-23

This comment has been minimized.

Copy link

rom-23 commented Oct 10, 2019

Thanks , good job ;)

@edrichhans

This comment has been minimized.

Copy link

edrichhans commented Oct 19, 2019

Thank you for this!! <3 <3 <3

@i-defranca

This comment has been minimized.

Copy link

i-defranca commented Nov 1, 2019

Maybe it would be useful to add an option without the cancel button, when it's a simple message with an ok button. But I think for most users the vuetify snackbar it's enough.
And thank you, of course! I was having trouble making a global component and this code helped me :)

@eolant

This comment has been minimized.

Copy link
Owner Author

eolant commented Nov 1, 2019

@i-defranca since this is not a library you can do any modifications you want :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.