Godofbrowser / vuejs-dialog

A lightweight, promise based alert, prompt and confirm dialog
MIT License
351 stars 111 forks source link

Not able to pass data to function #5

Closed scriptmint closed 6 years ago

scriptmint commented 6 years ago

Hello, After lots of search, I finally ended up with your package & I must say you have done great job. I found some thing which you may add.

Here is my code to delete an entity.

<button v-confirm="{ok: delete(item)}">Delete</button>

When I am passing data to delete function, it doesn't work. However if I don't pass data, it works. Is there any chances you will make it work?

Godofbrowser commented 6 years ago

Hello @ScriptMint Thanks for commending the plugin. Regarding this issue, it was very obvious from the moment the directive method was added as seen below:

<button v-confirm="{ok: makeAdmin, cancel: doNothing}">Make Admin</button>
methods: {
    makeAdmin: function() {
        // Who are we going to make an admin???

    },
    doNothing: function() {
        // Do nothing or some other stuffs
    }
}

However, calling delete(item) like in your case will probably need to process the delete method with the hope of returning a function that will then be used as a callback for the directive's ok property.

Something similar to (WORKAROUND):

<button v-confirm="{loader: true, ok: deleteItem(item)}">Delete</button>
methods: {
           deleteItem: function(item) {
                return dialog => this.serverDeleteItem(item, dialog)

                // or

                // let vm = this
                // return function(dialog){
                //    vm.serverDeleteItem(item, dialog)
                // }
            },
            serverDeleteItem: function(item, dialog) {
                // This will do the actual delete
                // and after deleting from the server
                // you can stop/close the dialog if you are using a loader
                setTimeout(() => {
                    dialog.close()
                    console.log(item)
                }, 1500)
            }
}
Godofbrowser commented 6 years ago

An alternative (still considering implementation) might be to make the element available withing the dialog object returned to the callback. This make it possible to retrieve just any item from the element's attributes.

A simple example:

<button v-confirm="{loader: true, ok: deleteItem}" :item="item">Delete</button>
methods: {
           deleteItem: function(dialog) {
                // After clicking proceed, 
                // the dialog will be returned with the elem
                // (in this case <button>)
                console.log(dialog.elem.item)
            }
}

What do you think?

scriptmint commented 6 years ago

Hello, Thanks for very quick response. However, in 2nd case, the dialog is only returning true or false. It doesn't contain element info. Any hint?

Godofbrowser commented 6 years ago

Yes, the 2nd is not yet implemented that's why I added (still considering implementation)

scriptmint commented 6 years ago

Ok. Waiting for this update!

Godofbrowser commented 6 years ago

Alright. I hope the first works for you in the meantime.

scriptmint commented 6 years ago

Yes, its working only when I comment out dialog.close() (Says dialog.close() is not a function). Writing two function for small thing is little pain. I hope you will come back with some quick solution! Thanks again!

justinbkay commented 6 years ago

I think I have an issue relating to this. I have a table of items. I'm able to delete an item from the table using the plugin as a directive.

<td>
    <button v-confirm="{
            loader: true,
            ok: dialog => delete_domain(dialog, domain.id),
            cancel: doNothing,
            message: 'Domain will be deleted. Delete Domain Forever?'}"
            class="btn btn-danger btn-xs">delete</button>
</td>

The issue I have is that if I delete an item, it doesn't bind the id value that I'm passing, so it will start deleting incorrect items which is a pretty bad deal. It seems like I need to be able to use v:bind on the button and then access that attribute from the v-confirm. Make sense?

Godofbrowser commented 6 years ago

Hello @justinbkay , please confirm that the key attribute is set uniquely for each item in the loop since you're dealing with a list of items. Ex:

<td v-for="domain in domains" :key="domain.id">
    <button v-confirm="{
            loader: true,
            ok: dialog => delete_domain(dialog, domain.id),
            cancel: doNothing,
            message: 'Domain will be deleted. Delete Domain Forever?'}"
            class="btn btn-danger btn-xs">delete</button>
</td>

Also, can you share the method delete_domain(dialog, domain.id) ?

EDITED

Ability to access the button attributes makes sense. I'll find time to resolve this issue once and for all

justinbkay commented 6 years ago

I didn't have the :key="domain.id" which when added seems to fix my issue. Sorry, I'm just learning Vue.

Godofbrowser commented 6 years ago

I'm glad it works 😄

Godofbrowser commented 6 years ago

Dialog now returns a node which is the element the directive was bound to. Please see the documentation for more details