I have a Place Order button, that contains a click event that will run some tasks and place the order via ajax.
I would like to add another click event that will be triggered before the original event, and perform some actions and validations.
Depending on the outcome of it:
- I would like to prevent the other events to be triggered
- OR if success, just proceed and call the other click listeners.
However I’m struggling a lot to achieve that with PrototypeJS or pure JavaScript.
This would be a simple example, but of course I tried many different approaches, including overrigind Event.observe method, cloning the button, and so on.
Any idea is appreciated.
var button = $('onestepcheckout-place-order-button')
//Original event
button.observe('click', function(e) {
console.log('Order submitted')
})
// New event (I only have access to modify from here onwards)
button.observe('click', function(event) {
if (confirm('Are you sure?') === false) {
console.log('The order should not be submitted')
event.preventDefault()
event.stopPropagation()
return false
}
// The other events should be triggered (order submitted)
button.fire('click')
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.3/prototype.js"></script>
<button id="onestepcheckout-place-order-button" type="button"><span>Place order</span></button>
2
Answers
It turns out that, although prototype can store the events internally, we cannot have access to it like we can in jQuery.
My solution was to clone the original button and add an event to it and also to the form, using pure javascript.
This way I was able to inject a clone of the original button, but without it events attached, run my function and its validation, and trigger the original button
click()
event if the validation passes.Here's what I did:
I think you are running into a protection the browser puts in place, that prevents JS from artificially triggering click events that are not part of an original click event. For example, the browser will prevent you from triggering a click event on an element, if you trigger the event from a mouse move event.
In your scenario, because the
confirm()
method is triggered that interrupts the "flow" of the click event from one handler to the next.Here’s my suggestion, extract the order submitted handler into a separate method definition, so that method is called while passing the event to that method. The original click event listener can call that method, as well as the new one that has the "are you sure"
confirm()
call.