If I have the following event handler bound to my form:
form.addEventListener('submit', function(evt) {
evt.preventDefault();
console.log('submitted');
this.submit();
});
When the form is submitted by the client, the event handler is executed and the form is submitted without the event handler being executed again.
However, the same logic doesn't apply when attaching click handlers to anchor elements:
a.addEventListener('click', function(evt) {
evt.preventDefault();
console.log('clicked');
this.click();
});
The event handler is executed twice and the link is never followed.
I have two questions:
Why does it appear to work differently for submit vs click?
Why does the anchor's click handler only get executed twice and not indefinitely, if the event handler is being executed each time it's called?
Form submission and element click are different actions, they don't have to behave in the same way.
When using the submit method of the form, the standard says:
Submits the form, bypassing interactive constraint validation and without firing a submit event.
This can be seen also in the submission algorithm. Item 6 checks, whether the action comes from the submit method of the form, and skips the validation and event firing if the "submit()" flag is set.
element.click sets "click in progress flag", which is checked internally before creating a syntehtic click event which calls the hander function. This prevents a click on an element to lead to infinite recursive click event handler calls.
Related
There is focus-out event handler for a text-box and a submit button to post a form data.
Focus-out event handler having a ajax service call where validating text-box value.
My scenario is that entered a value in text-box(text-box is focused now) and making a click event. While making click event, text-box focus-out must be handled first and then click event handler must be handled.
How to ensure to run focus-out before button click event handler on a button click in JQuery?
I have a bootstrap popover that becomes active on focus of an input. The popover contains a button in it to perform an ajax request.
I have a blur function that closes the popover if the user clicks away from the input:
$(document).on('blur','.open-popover',function(){
$(".popover").attr("style","");
//and do other things too
});
I am trying to prevent the blur function above from running if the user presses the button in the popover:
$(document).on('click','button',function(){
//prevent the blur actions and
//do ajax stuff
});
Have you looked at stopImmediatePropagation? If using jQuery, then event handlers are fired in the order that they are bound. Just bind the click before the blur, and run stopImmediatePropagation within the click event.
// bind click event first
$(document).on('click','button',function(event){
// keeps the rest of the handlers from being executed and prevents the event from bubbling up the DOM tree.
event.stopImmediatePropagation();
});
// then attach blur
$(document).on('blur','.open-popover',function(){
$(".popover").attr("style","");
//and do other things too
});
Code:
var formElement = document.querySelector('form');
formElement.addEventListener('submit', function (e) {
e.preventDefault();
console.log('addEventListener event handler');
this.submit(); // not causing recursive call.
}, false)
</script>
Why isn't going as recursive event handling. I thought this.submit() will call the function/event handler (under which it exists) again. I don't face any issue with this , but just want to know how it is working and not as a recursive call.
Calling .submit on the form itself doesn't trigger an event, it just submits the form. therefore, the event handler doesn't get executed because there is no event.
We are currently binding to the click event of a submit button (there are reasons why we are not binding to the submit event for the form). Is it guaranteed that our JS will run before the form submits (as we are entering values into hidden fields that we want to submit) or do we need to prevent the form from submitting and then call the submit again?
$(function() {
$('#button').on('click', function() {
// Do some stuff here - needs to finish before the form submits
return true;
});
});
Thanks in advance!
It will work before the submit event is sent, but you are only listening for the click event. If the user hits enter, the form will be submitted without running your code. I think you should stick to the submit event. The callback function will receive as argument the event (and you can do things like e.preventDefault(); or e.stopPropagation();
$("form").on("submit",function(event){});
In my expierience the code in the click event will always run first.
I just ran a simple test on latest chrome with a loop that loops 10,000 times. The form did not submit until after the loop was finished (~5 seconds).
If you try to run some ajax call, or setTimeout in the click function though, the form will most likely submit before your callback/ajax is finished.
I have an application that uses backbone.js and jQuery for UI. I have a form on a page, attached to the form's text box blur event is a function that under certain conditions shows the user a popup and awaits it's input - the conditions are checked using an ajax call to a WCF service.
Everything works fine until i click the form's submit button while the focus is set on the text field - then the popup is displayed but behind it the form is submitted.
Of course the proper result would be cancelling the second event(if the popup is displayed the form definitely cannot be submitted)
How can I achieve this?
i can'T understand you but probably this is what you need: event.stopPropagation();
http://api.jquery.com/event.stopPropagation/
Or .off()
http://api.jquery.com/off/
You can bind to the submit event of the <form> and call its preventDefault() method to inhibit submission if the popup is visible:
$("form").submit(function(e) {
if ($("selector_matching_your_popup").is(":visible")) {
e.preventDefault(); // Cancel submission.
}
});
You can also return false from the handler instead of calling preventDefault(), but this will also stop the propagation of the submit event to ancestor elements, which you may not want.
Are you saying that the clicking of 'submit' is causing the popup to display - and this is not one of the 'certain conditions' where it should be displayed? I would consider adding a condition to the blur handler that checks to see if the submit button was clicked. Dont display the popup in this case.
Cancel the event in the onSubmit handler -
form.addEventListener("submit", function(evt){
evt.cancel()
//dont want to catch it again
form.removeEventListener(this)
popup.show()
//have the popup call submit when done, it wont be caught again
}