Jquery bind is amazing, but I don't know in what order the binding happens. My current problem is thus:
$(document.body).delegate('form', methods.checkForm);
$('form').bind('submit', methods.submitFormIfCheckedFormIsTrue);
methods.checkForm = function (e) {
if (!$(this).isVerified()) {
return false;
}
return true;
};
methods.submitFormIfCheckedFormIsTrue = function (e) {
e.preventDefault();
$.ajax("/submitForm", {
data:$(this).serialize(),
type:"post"
});
};
This is obviously not the actual code that I'm using, but it's pretty close. What happens is, the submitFormIfCheckedFormIsTrue function fires before, or during, the checkForm function, so the checking is pretty useless. My hack for it was to add the class "checked" to the form and the check if the form has that class in the other function...but then you click submit, it checks, then you have to click it again to submit it if everything went right...which is retarded.
Another thing that's important regarding this problem is that I'm they're in pletely different parts of my application, for reasons that can't change. Also, they're being loaded asynchronously.
The main thing I want to know then...is how to change the order, or set the priority of the events somehow...
Jquery bind is amazing, but I don't know in what order the binding happens. My current problem is thus:
$(document.body).delegate('form', methods.checkForm);
$('form').bind('submit', methods.submitFormIfCheckedFormIsTrue);
methods.checkForm = function (e) {
if (!$(this).isVerified()) {
return false;
}
return true;
};
methods.submitFormIfCheckedFormIsTrue = function (e) {
e.preventDefault();
$.ajax("/submitForm", {
data:$(this).serialize(),
type:"post"
});
};
This is obviously not the actual code that I'm using, but it's pretty close. What happens is, the submitFormIfCheckedFormIsTrue function fires before, or during, the checkForm function, so the checking is pretty useless. My hack for it was to add the class "checked" to the form and the check if the form has that class in the other function...but then you click submit, it checks, then you have to click it again to submit it if everything went right...which is retarded.
Another thing that's important regarding this problem is that I'm they're in pletely different parts of my application, for reasons that can't change. Also, they're being loaded asynchronously.
The main thing I want to know then...is how to change the order, or set the priority of the events somehow...
Share Improve this question asked Feb 15, 2012 at 23:05 adiktofsugaradiktofsugar 1,5091 gold badge14 silver badges17 bronze badges 4- Call the function you want to run second from within the first? – David Thomas Commented Feb 15, 2012 at 23:09
- Why not just call the ajax function and check inside the same function? – loganfsmyth Commented Feb 15, 2012 at 23:09
- It needs to be modularized. The check function is general across all forms, whereas the second function is unique to only the one particular form. I just posted that code as an example of what leads to the situation... – adiktofsugar Commented Feb 15, 2012 at 23:10
- Does this answer your question? How to order events bound with jQuery – starball Commented Jan 23, 2024 at 0:13
2 Answers
Reset to default 4If you are using 'delegate' the way you have it in your example, then the ajax submission is always going to run first, so the short answer to your question is "You Can't". Your delegate is attached to the 'body' element, so events attached to elements closer to the form in the DOM tree will fire first.
Events bubble from the form -> body, so there is no ordering when you are doing that.
One option would be to have your verification trigger a second event.
methods.checkForm = function (e) {
e.preventDefault()
if ($(this).isVerified()) {
$(this).trigger('form-verified');
}
};
Then instead of binding the other handler to 'submit'
, you would bind it to 'form-verified'
.
$('form').bind('form-verified', methods.submitFormIfCheckedFormIsTrue);
This is also another way to acplish ordering event if they are attached to the same element instead of using delegate.
Also, if you are using jQuery >= 1.7, then you should be using on
instead of bind
and delegate
. http://api.jquery./on/
Update
If both are bound to the same element, then they will be triggered in the order that they were attached to the element. Assuming checkForm is bound before the other one, then the issue is that return false;
does not stop other events from firing if they are attached to the same element. For that you also need e.stopImmediatePropagation()
.
methods.checkForm = function (e) {
e.preventDefault()
if (!$(this).isVerified()) {
e.stopImmediatePropagation();
}
};
There is also a useful answer over here if you ever have to tweak the ordering of events. jQuery event handlers always execute in order they were bound - any way around this?
In a general sense event handlers will be called in the order that they were bound, but only if they're bound at the same level. In your case you're binding one directly to the form while the other is a delegated handler bound at the document.body
level. The directly bound one will happen first and then the event bubbles up to be handled by the other.
If you bind both handlers at the same level with .delegate()
then they should be called in order:
$(document.body).delegate('form', 'submit', methods.checkForm);
$(document.body).delegate('form', 'submit',
methods.submitFormIfCheckedFormIsTrue);
Then in the first (generic) handler you should call the event.stopImmediatePropagation()
method to prevent other handlers being called (noting that simply returning false prevents the default and stops the event bubbling up further, but it doesn't stop other handlers at that level from running):
methods.checkForm = function (e) {
if (!$(this).isVerified()) {
e.stopImmediatePropagation();
return false;
}
return true;
};
(By the way, the code shown in the question left out the event (second param) from the .delegate()
call - I've put it in in my code.)
Or bind both handlers directly rather than using .delegate()
. And speaking of using .delegate()
, if you're using the latest version of jQuery you may like to switch over to using .on()
, the new do-everything event binding method.
"What happens is, the submitFormIfCheckedFormIsTrue function fires before, or during, the checkForm function"
Definitely before, not during. (In pretty much all browsers) JavaScript runs on a single thread, so you will not ever have two functions running simultaneously.