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:
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>
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:
var button = document.getElementById('onestepcheckout-place-order-button')
var form = document.getElementById('orderForm')
// some code will add one or more event listeners to the original button
button.addEventListener('click', function(e) {
console.log('Button clicked will submit form via ajax')
//ajax (the order may be placed via ajax. replace the webhook.site url with yours if you want to see it in action there)
new Ajax.Request('https://webhook.site/25fab621-3f15-4d9f-ad87-3a746113adf2', {
method: 'POST',
data: {
name: 'John Doe',
email: ' '
}
})
}, false)
// clone the button
var newButton = button.cloneNode(true)
// replace old button for the new button (with no events attached)
button.parentNode.replaceChild(newButton, button)
// just a generic function to validate and prevent default
var validateAndPreventDefault = function(event) {
event.preventDefault() // prevent the default behavior of the form/button
if (confirm('Are you sure?') === false) {
// add condition here
// if some condition is not met, prevent the form from being submitted
console.log('The order should not be submitted')
return false
}
console.log('The order will bet submitted')
button.click() // trigger the click event on the old button
return true
// The other events should be triggered (order submitted)
}
// add the event listener to the form and the button, preventing the default behavior in both cases
form.addEventListener('submit', validateAndPreventDefault, false)
newButton.addEventListener('click', validateAndPreventDefault, false)
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.3/prototype.min.js"></script>
<form id="orderForm" method="post" action="#">
<!-- type button-->
<button id="onestepcheckout-place-order-button" type="button"><span>Place order</span></button>
<!-- type submit-->
<button id="onestepcheckout-place-order-button-original" type="submit"><span>Submit button</span></button>
</form>