I am trying to override the button click event for autoform-remove-item button as shown below, as I am trying to show a warning message ( before ) the user can remove any item in the Autoform array. Then if the user confirmed the item removal then the button click event shall continue normally. But I can't figure out how to override the click event of the button in a way to pause code below it (which I have no access to) until the user confirm / reject the deletion? Any help what I might be missing here? Thanks
Template.salesInvoice.events({
'click .autoform-remove-item': function(e){
e.preventDefault();
bootbox.dialog({
message: "Are you sure you wish to delete this item?",
title: "New Journal",
buttons: {
eraseRecord: {
label: "Yes!",
className: "btn-danger",
callback: function() {
}
},
doNotEraseRecord: {
label: "No!",
className: "btn-primary",
callback: function() {
//Continue with the normal button click event
}
}
}
});
}
});
The click event I am trying to override:
'click .autoform-remove-item': function autoFormClickRemoveItem(event, template) {
var self = this; // This type of button must be used within an afEachArrayItem block, so we know the context
event.preventDefault();
var name = self.arrayFieldName;
var minCount = self.minCount; // optional, overrides schema
var maxCount = self.maxCount; // optional, overrides schema
var index = self.index;
var data = template.data;
var formId = data && data.id;
var ss = AutoForm.getFormSchema(formId);
// remove the item we clicked
arrayTracker.removeFromFieldAtIndex(formId, name, index, ss, minCount, maxCount);
},
After running in circles for an hour or so, this is what I found out. Blaze installs it's event-listeners in-side the parent-element of the templateInstance
. The property they are storred under is called $blaze_events
. It's easy to use, but undocumented. Here's how you can use it:
The handlers are stored inside an array ($blaze_events.handlers
). So to find a specific one I wrote this function:
retrieveBlazeEvent = function retrieveBlazeEvent (parentElement, eventType, selector) {
var returnHandler
parentElement.$blaze_events[eventType].handlers.forEach(function (eventHandler) {
if(eventHandler.selector === selector)
return (returnHandler = eventHandler) && false
})
return returnHandler
}
Usage:
client/test.html
<template name="test">
<p>Hi!</p>
</template>
client/main.html
{{ > test }}
client/main.js
Template.test.events({
'click p': function () {
console.log('PIII')
}
})
retrieveBlazeEvent(document.body, 'click', 'p')
The event-handler returned by retrieveBlazeEvent
has a function unbind
. So here's an example
retrieveBlazeEvent(document.body, 'click', 'p').unbind()
The event-handler will still be there after you call this function. To revert it you can simply call bind
on the same object.
Say we have a simple p
-element. A click-event is being listened to:
Template.test.events({
'click p': function () {
console.log('PIII')
}
})
To trigger the event-handler we'll need a p
-element that matches this selector. We'll also need the template instance to retrieve the correct parent node. Then we need to call the event-handler with the view as its context. We also need to bind create a stub for the event, that contains currentTarget
. This function does all that for you:
triggerEvent = function triggerEvent (eventType, elementSelector, context) {
var context = context || document
var element = context.querySelector(elementSelector)
var eventStub = {
currentTarget: element
}
var view = Blaze.getView(element)
retrieveBlazeEvent(view._domrange.parentElement, eventType, elementSelector)
.delegatedHandler
.call(view, eventStub)
return true
}
Can't you just show the bootbox confirm in the code where the collection is removed? Then only remove it from the collection when the user confirms it. For example, I think this should help:
'click .autoform-remove-item': function autoFormClickRemoveItem(event, template) {
bootbox.dialog({
message: "Are you sure you wish to delete this item?",
title: "New Journal",
buttons: {
eraseRecord: {
label: "Yes!",
className: "btn-danger",
callback: function() {
var self = this;
var name = self.arrayFieldName;
var minCount = self.minCount; // optional, overrides schema
var maxCount = self.maxCount; // optional, overrides schema
var index = self.index;
var data = template.data;
var formId = data && data.id;
var ss = AutoForm.getFormSchema(formId);
arrayTracker.removeFromFieldAtIndex(formId, name, index, ss, minCount, maxCount);
}
},
doNotEraseRecord: {
label: "No!",
className: "btn-primary",
callback: function() {
//Continue with the normal button click event
}
}
}
});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With