4

I have a page which uses jQuery & parsley plugin for form validation and submission. Below is the event handler for the form,

$('#formid').parsley().on('form:submit', function(event) {
    //handle form submit
});

I have another pure JavaScript listener function to be executed on submit of the form. Below is the code snippet,

document.getElementById("formid").addEventListener("submit",function(e){
   //Some code to be executed after form submit
});

I have a requirement not to use jQuery for the above function.

Now the problem is, parsley is stopping flow of events down the line by using event.stopImmediatePropagation();

Because of this, the second event handler is not getting executed. Is there a way I could make my pure javascript handler to execute first? I came across this jQuery solution to bindUp an event handler. But I need pure javascript solution. Any help is greatly appreciated.

Update: Here is JSFiddle for my problem.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Sathish Jayaram
  • 129
  • 3
  • 14
  • The full content of your question must be **in** your question, not just linked. Instead of jsFiddle, use Stack Snippets (the `<>` toolbar button) to put the full code necessary to demonstrate the issue in a runnable demo on-site. – T.J. Crowder Aug 27 '16 at 11:57
  • I went to copy your fiddle into your question for you as a Stack Snippet, and found you've tripped over jsFiddle's **surprising default** of wrapping everything in a `window.onload = function() { /*your code here*/};` wrapper. If you use the options to turn that wrapper off (it's an amazingly silly default), the issue you had with my answer goes away. – T.J. Crowder Aug 27 '16 at 12:01
  • You were right! Thank you. The code works if I change to onDOMReady. But in my case, I dont have control over this as my code is inside an external javascript file linked to the html page header. The parsley jQuery code is in the script tag within body of the html. So not able to control the sequence here. – Sathish Jayaram Aug 27 '16 at 12:16
  • Putting `script` tags referencing external files in `head` is not generally a good idea (unless you use `async` or `defer`), can't you move it? – T.J. Crowder Aug 27 '16 at 12:17
  • I have my code as an external JS file with async attribute in the page's head tag. Unfortunately I cant change this. My code has to be in external file. – Sathish Jayaram Aug 27 '16 at 12:20
  • It's not the external file part that's the problem, it's not having control over when your code runs that's the problem. Unfortunately, if you can't ensure it runs before the Parsley code does, you're kind of stuck. :-| – T.J. Crowder Aug 27 '16 at 12:28

3 Answers3

4

The only way is to ensure that the addEventListener handler is added before the jQuery handler. jQuery will use addEventListener to add its handler for the event (at which point it will use that single handler for all handlers for that event on that element), and since handlers added with addEventListener are processed in the order they were added, your non-jQuery handler will be executed first by the browser.

Example:

// The first addEventListener handler -- does get called
document.getElementById("the-button").addEventListener("click", function () {
    console.log("first addEventListener handler called");
}, false);

// The jQuery handler that stops immediate propagation
$("#the-button").on("click", function (e) {
    console.log("jQuery handler called");
    e.stopImmediatePropagation();
});

// The second addEventListener handler -- doesn't get called
document.getElementById("the-button").addEventListener("click", function () {
    console.log("this message won't be output");
}, false);
<input type="button" id="the-button" value="Click Me">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Pankaj Makwana
  • 3,030
  • 6
  • 31
  • 47
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thanks for this solution. But it didnt work for me. I added my listener before the listener with parsley but still the control goes to the parsley. Any idea on points I should look for? – Sathish Jayaram Aug 27 '16 at 11:22
  • @SathishJayaram: Can you create a [mcve] for that? I find it **very** hard to believe that a handler you've registered **first** with `addEventListener` is fired *after* the jQuery handler. If it were `attachEvent` (the old Microsoft thing), that would be different (it worked the other way around), but `addEventListener` very definitely works as described above. – T.J. Crowder Aug 27 '16 at 11:26
  • @Crowder Udated my question with fiddle link. Please have a look. – Sathish Jayaram Aug 27 '16 at 11:56
2

yes, you can do that. use Boolean true as third parameter to function addEventListener like below. it's binding the handler in capturing phase of the event. for more about capturing and bubbling phase of event see

document.getElementById("formid").addEventListener("submit",function(e){
   //Some code to be executed after form submit
}, true);
Community
  • 1
  • 1
Sufian Saory
  • 862
  • 9
  • 14
-1

hope this will help

First way

I don't know if this is going to work, try to refresh your propagation event :

var refEvent = event.originalEvent;
refEvent.cancelBubble = false;
refEvent.defaultPrevented = false;
refEvent.returnValue = true;
refEvent.timeStamp = (new Date()).getTime();

if (event.target.dispatchEvent){
    event.target.dispatchEvent(refEvent);
} else if (event.target.fireEvent) {
    event.target.fireEvent(refEvent);
}

then you can stop the propagation again after your handler executed by adding event.stopPropagation(); again to your handler this time

Second way

//Listener

var stoped = false;
if(stoped){
    event.stopPropagation();
}

//handler

var stoped = true

source : How to undo event.stopPropagation in jQuery?

Community
  • 1
  • 1
Simo
  • 431
  • 1
  • 7
  • 20
  • One pain point is the page is external. So I should not be modifying parsley function, the second way wont fit my case. I didnt quite understand the first way, what does the refEvent point to? – Sathish Jayaram Aug 27 '16 at 11:32