Reputation: 113385
I want to make a general jQuery code which will catch all the submit
events of <form>
subelements including the container element (in case it's a form).
The cases are:
<form>
<button>hi</button>
</form>
<div>
<form>
<button>submit</button>
</form>
</div>
What's the cleanest code to do this?
My current solution is the following:
function submit(e) {
// do something
}
$(containerSelectorOrjQueryObject).on("submit", "form", submit);
$(containerSelectorOrjQueryObject).on("submit", submit);
However, I'd be happy to know if there is a better solution, using just one on
call.
Upvotes: 5
Views: 136
Reputation: 5926
You can use a class attribute for this as a way to set up a delegate to catch the submit event of any child form no matter what the parent element is. Because it is a delegate, this will also catch anything fired by elements that have been dynamically added as well.
Example that includes a single form scenario, multiple forms in div scenario, and a button to add a form dynamically:
var alreadyAdded;
function submit(e) {
// do something
alert(e.target.name);
return false;
}
$("body").on("submit", ".outerContainer", submit);
$("#addAnotherDynamically").on("click", function(e) {
if (typeof(alreadyAdded) === "undefined") {
alreadyAdded = true;
$("#test2").append("<form name='form4'><button>submit 4</button></form>");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<body>
<form id="test1" name="form1" class="outerContainer">
<button>submit 1</button>
</form>
<div id="test2" class="outerContainer">
<form name="form2">
<button>submit 2</button>
</form>
<form name="form3">
<button>submit 3</button>
</form>
</div>
<br>
<button id="addAnotherDynamically">Add another form</button>
</body>
Upvotes: 1
Reputation: 4873
Submit events, like other event, bubbles across the DOM, so attaching an submit event listener to the form
itself or to any of its parents will work and you can even cancel your submit there.
To always get the form
in which the submit was triggered use e.target
instead of this
within the event listener method.
See this example:
function onSubmit(e){
e.preventDefault();
document.getElementById('d3').innerHTML += 'Submit catched in ' + e.currentTarget.tagName + '#' + e.currentTarget.id + ' for ' + e.target.tagName + '#' + e.target.id + '<br/>';
}
$(function(){
$('#d1').on('submit', onSubmit);
$('#f2').on('submit', onSubmit);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="d1">
<form id="f1">
<input type="submit" value="Event Listener on DIV" />
</form>
</div>
<div id="d2">
<form id="f2">
<input type="submit" value="Event Listener on Form" />
</form>
</div>
<div id="d3">
</div>
Running it and clicking on the buttons you can see that using the same on
call you can attach evest to the form itself or its parent and it will work as expected.
So, you can go with only the line below and it will work fine:
$(containerSelectorOrjQueryObject).on("submit", submit);
Upvotes: 0