Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you change the event firing order of the same event?

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 completely 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...

like image 783
adiktofsugar Avatar asked Feb 15 '12 23:02

adiktofsugar


1 Answers

If 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 accomplish 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.com/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?

like image 90
loganfsmyth Avatar answered Nov 07 '22 08:11

loganfsmyth