How to know which submit button fired the onsubmit event - javascript

When you have more than one submit button in a form, is there a way to know which one fired the onsubmit event without adding code to the buttons themselves?
Edit: I need to do the check on the client-side, i.e. with JavaScript.

The "submit" event is not fired by the button, but its fired by the "form". A quick test proves this:
<form id="myform">
<input id="email" type="text" value="1st Email" />
<input id="action1" type="submit" value="Action 1" />
<input id="action2" type="submit" value="Action 2" />
</form>
<script type="text/javascript">
document.getElementById("myform").onsubmit = function(evt) {
var event = evt || window.event;
alert(event.target.id); // myform
alert(event.explicitOriginalTarget.id); // action2 (if action2 was clicked)
// but only works in firefox!
}
</script>
Although in firefox, you can use event.explicitOriginalTarget property on event to get the input (submit) that was clicked causing the submit event to be fired. (if you want to know)
So best options for you are:
Have a different value to your submit buttons OR
Have those as normal buttons and click handlers to them via javascript.

There is a submitter attribute on SubmitEvent object.
See example:
<!DOCTYPE html>
<html>
<body>
<form action="./test.html" onsubmit="myFunction(event)">
Enter name: <input type="text" name="fname">
<button id="firstButton" type="submit">Button 1</button>
<button id="secondButton" type="submit">Button 2</button>
</form>
<script>
function myFunction(event) {
// This should log id of the button that was used for submition
console.log(event.submitter.id);
// Prevent sending the form (just for testing)
event.preventDefault();
}
</script>
</body>
</html>
See https://developer.mozilla.org/en-US/docs/Web/API/SubmitEvent/submitter

Does having an event listener on each button count as adding code? Otherwise, there's no way to see what button triggered the submit event, unless you want to get down and dirty and calculate the mouse position during the event and compare it to button positions.
Otherwise, the next best thing would be to assign an event handler for the click event of button and assign the name of that button to a variable you can check in the form's submit event.

There are a couple of ways that I can think of.
You can use different values, and your unobtrusive javascript can help with it.
One discussion on this approach (using different values for each button) is here:
http://www.chami.com/tips/internet/042599I.html
I tend to go with using different name attributes for each button.
A blog on that is here: http://www.codetoad.com/javascript/multiple.asp
I don't follow either of these, which approach will work best is going to depend on different factors, such as, are you handling the submit buttons in javascript, or will the server get the form, then have to figure out what the user wanted.
Personally, I prefer to use the ajax approach, now, where I just attach events to the buttons after the page is loaded, using unobtrusive javascript, and then based on the user choice call out to the correct function, but that depends on whether you can add a script link to the html page.
UPDATE:
In order to do this with javascript, the simplest way is to attach an event on the click of the button, and then look at the name to decide how to handle it.
In actuality, the form never truly has to be submitted to the server, but you can handle everything in the background by wrapping up the parameters (options) and sending them to the server, and let the user know the results.

Sorry to warm up this very old thread. The question hadn't been answered here but only approaches for practical workarounds have been given here before.
But the event-object does carry information about which object has initiated it. In a handler b4submit(e) you can get the submit-button like this:
function b4submit(e) {
var but = e.originalEvent.explicitOriginalTarget;
...
}
And but is an HTML Object with all the attributes you've assigned it with, like name, id, value etc.
I came across this after some debugging, and I thought it might be of a wider interest as a clean solution for this issue.

For me the simplest option that worked for me is to use document.activeElement if you want to get the id use document.activeElement.id if you want to get the text content you can simply put document.activeElement.textContent
const onSubmit = () => {
console.log('document.activeElement', document.activeElement.id)
if (document.activeElement.textContent === 'Suivant') {
handleNext()
return
}
if (document.activeElement.textContent === 'Confirmer') {
console.log('Payer')
return
}
}

Related

stopping onclick event handler

I have some working code that I'm now using in slightly different context. The working part is that I use objects onclick event to bring up a form to send an e-mail. When this in an HTML page, it works fine. I would have a lot of buttons that look like this:
<button id="mail-c1" onclick="initMailFormButton(this.id, 'someone','somedomain.com','a subject')">Someone's Name</button>
The entire form is created in javascript and has its own submit and cancel buttons but is within the button element. In order to be able to enter data into the form, I need to kill the onclick event then restore it after I've submitted or cancelled the e-mail. The onclick handler starts out with:
function initMailFormButton(mailId, eName, eDomain, eSubject) {
myFormLocation = document.getElementById(mailId);
stopFormClick(myFormLocation);
where the stopFormClick function is:
function stopFormClick(myFormLocation) {
saveOnclick = myFormLocation.onclick;
myFormLocation.onclick = null;
}
This has the bug that it doesn't handle someone opening multiple forms at once, but that's not my immediate concern. I'll fix it outside of this discussion.
The submit and cancel buttons in the generated form both restore the onclick event handler so you can open and close the form multiple times quite happily.
My new case is that I'm generating HTML page from a database. I'm using HTML datasets to store the previously hard-coded information like so:
emailButton.setAttribute("data-mailname", emailName);
emailButton.setAttribute("data-maildomain", emailDomain);
emailButton.addEventListener("click", function() { initMailFormButton(this.id, this.dataset.mailname, this.dataset.maildomain, ""); }, false);
The information being retrieved is correct and the form appears in the correct location. However, I can't enter information because the original onclick handler kicks in when I click in the first form field and generates another form...
The only clue I have is that when I look at the value of the onclick event being saved in the static HTML pages, it has the expected value but it is null in the generated pages. I find this confusing because I am passing the (unique) element id to the routine so it should be getting to the correct element.
Can anyone help me on this one. Meanwhile, I'll fix the event handler bug I mentioned above.
OK. So it's that there is a difference between click and onclick. The onclick event handler wasn't set so it is null. I changed setting the click event listener to setting the onclick attribute as:
emailButton.onclick =
function() { initMailFormButton(this.id, this.dataset.mailname, this.dataset.maildomain, ""); };
and everything works nicely.
To handle the limitation I'd noted earlier, I made the saveOnclick variable into an associative array keyed by the button id. Now people can have as many buttons clicked as they want - although wanting to have more than one is probably rare.

Javascript bind submit event

I'm trying to bind an submit event to a button that can't be type="submit" needs to be type="button"
I'm trying these to make the required attr validation works
So, can you say what I'm doing wrong here? I'm Googling a lot but didn't find anything yet.
https://jsfiddle.net/2gfnqv6e/28/
With this code, you can trigger the submit event :
submitBtn.addEventListener('click', function () {
form.dispatchEvent(submitEvent);
});
However the HTML5 form validation won't work because it requires an actual submit button.
Updated JSFiddle

Why submitting a form overrides setting location.href in a submit button click handler?

This question is inspired by this post.
In a nutshell: Why window.location.href is not redirecting to a new page (example.com) when executing the code below?
<form>
<input type="submit" id="submit" value="Submit">
</form>
<script>
document.getElementById('submit').addEventListener('click', function (e) {
window.location.href = "http://www.example.com";
});
</script>
I've always believed, that setting window.location.href immediately loads a new page, but in this case it doesn't. Submitting the form just reloads the page instead, and setting a new location seems to be totally ignored. Why? How? What I'm missing here?
Please notice, that I'm aware of several ways how to prevent form submitting in this case, rather I'd like to know, why setting location.href is ignored, what is the mechanism behind the behavior? I've tried to search explanation from the standard, but haven't found anything so far.
Additional information
This seems to happen in all major browsers (Chrome, Firefox, IE11, Edge ...), but not when the code is run in a Stack snippet (because it's sandboxed, and won't send forms anyway). A console.log put in the function shows, that the click handler is executed before the actual submission is executed.
A jsFiddle reproducing the issue.
You can see easier here what is happening step by step if you will try tu change location drunning form submission
JSFIDDLE
If you will check your browser network tab than you can see that the submit request is cancelled (but still sent) by redirect request. I believe that same situation occurs when you trying to do it onclick or onsubmit the first request just cancelling the next one and prevent window.location.href redirection.
I belive the key thing here is not to view the problem as 'form submission vs page redirect', but as an event-listeners issue.
What you are doing is to attach an event listener to an html element. And it seems that the policy of DOM elements is to execute all the event listeners first, and then the event itself . In your case, the page is redirected to the url you provided, because you set window.location inside the listener, then the submit event itself takes place, so the same blank page is reloaded
The fact that "event flow process will complete after all listeners have been triggered" is stated here: http://www.w3.org/TR/DOM-Level-2-Events/events.html
So far I haven't figgured out a way to execute the listeners after the event , but if that can be done, that is all you need to make this example work
The main issue is that there is nothing preventing the submit button from actually submitting the form. You would need a return false somewhere for that to happen. I'm not fully certain whether the Submit button logic or the click handler is happening first, but regardless, the form post is taking precedence.
I was able to get the following to work:
<html>
<head>
<script type="text/javascript">
function redirect() {
window.location.href = "http://www.example.com";
return false;
}
</script>
</head>
<body>
<form method="GET" action="">
<input type="submit" id="submitbtn" value="Submit" onclick="return redirect()" />
</form>
</body>
</html>
This example does remove the programmatic addition of the click event, but if that's a hard requirement it should be possible to add that back in.

Capturing jQuery form submit event

I don't know what is wrong with that, because I was following at every step the tutorial from jquery.com regarding the form submit event.
My Javascript:
[Ofc. latest jQuery library is included].
<script type="text/javascript">
$("form#addFav").submit(function(event) { event.preventDefault(); alert("hello"); });
</script>
Have also tried with the $(document).ready() event:
$(document).ready(function(){
$("form#addFav").submit(function(event) { event.preventDefault(); alert("hello"); });
});
Here is my HTML form code:
<form action="" id="addFav">
<input type="text" name="name" class="thin-d"/>
<input type="submit" value="Send"/>
</form>
So, regarding the above Javascript code, it is supposed to work (I mean it should prevent default action [submitting form] and send the alert then), but it all doesn't work - have tried with thousands of combinations, but I fail'd. So I'm waiting for your solutions. I'd appreciate every one.
You probably have some syntax error or somthing like that somewhere else, because what you have just works.
Are you sure there aren't any JS errors?
P.S. I would alwyas go for the latter code to ensure that the elements are in the DOM before trying to attach events.
For anyone else who has the same problem, and still struggling to solve this issue, try to see if you have illegally reused the id, and try changing the form id to something unique.
I had accidentally given the id to two different DOM elements and the event was being bound to the first element with the respective id and my form was the second one so it was never captured. This had me pulling my hairs for quiet a long.
I just recently ran into the same issue. Jquery on submit would not work on the form, however just changing it to click event worked fine. Still at a loss why .on(submit) or .submit() events will not recognize the form.
$("form#addFav").click(function (event) {
event.preventDefault(); alert("hello");
$(this).submit();
});
this question is old but.. you might have had another submit events firing before yours fired. If these other events contained "return false;" statement then the event execution got interrupted and your code never fired. To put your code BEFORE these events you might use ONSUBMIT form attribute where you can put code that will fire before or at the same time as other events.

Intercept form onSubmit

Is there any way we can intercept the html form's onsubmit event?
In my web application, there are several screens containing forms etc. The issue we are facing is when the user presses any button multiple times, the server gets overloaded with same requests.
Some of the forms have event handlers already attached to them(like onSubmit, button.onClick etc).
One way can be to "inject" my button disable code by going through all the screens.
But what I am looking for is a generic solution which can be applied to all the screens by just including the script where the function is written.
I know I can setup callback using jQuery (capturing onSubmit for form), but in the issue in this case is if any screen has a onSubmit registered already, it may not get called.
Any help in this regard appreciated!
I think this piece of code is a good place to start. It should be placed in separate file and included where you want to use it (if you appear to have global list of scripts - its a good place for it)
var suppressed_items = [];
function allowOnlyOne(item,e){
if (jQuery.inArray(item, suppressed_items)==-1){
//hi little item, I haven't saw you before, please go on... but I remember you
suppressed_items.push(item);
return true;
}
else{
//Hey, you have been submitted already, stay where you are!
return false; //or e.preventDefault(), it's a matter of faith :)
}
}
jQuery(document).ready(function(){
//don't worry, it won't replace your `ready` handlers, but just append new handler
jQuery("from").submit(function(e){
return allowOnlyOne(jQuery(this),e);
});
});
You can use the allowOnlyOne function with any item you wish. So, for example to allow single click on all hyperlinks, inside that ready handler add:
jQuery("a").click(e){
return allowOnlyOne(jQuery(this),e);
}
I hope you get the basic idea: catch the event, get the ID of the element that trigger it, fed it to AllowOnlyOne along with event.
Of course you can wrap it all around into self-executing closure to achieve incapsulation and so on...
If you already have jQuery I suggest you use it... All you need to do is make sure is that your form's onsubmit do not have a "return false" or else it can block jQuery's on submit.
Here's what you need to do:
Remove any return false from your form's onsubmit (if any). Don't worry we'll take care of this later in jQuery.
Add a class to your forms... something like "disableOnSubmit". Example:
<form action="something" onsubmit="yourExistingCode" class="disableOnClick">
</form>
OR
<form action="something" onsubmit="yourExistingCode" class="someOtherClass disableOnClick">
</form>
Implement a code similar to:
<script type="text/javascript">
$(document).ready(function(){
$('form.disableOnClick').submit(function(e){
// preventDefault() does the same as "return false;". It
// will not submit the form. If you're not using return false
// and want the form to be submitted remove the line below
e.preventDefault();
// Now diable any submit button
$('input[type=submit], button[type=submit]').attr('disabled, 'disabled');
});
});
</script>

Categories