IE bug triggers click for 2 buttons? - javascript

I am trying to trigger the submit button when a user presses enter. Works great for all browsers except Internet Explorer 9. Strange thing is that IE insists on also triggering the click for another button I never told it to. Am I doing something wrong or how to fix this?
Below is my code. Pressing enter in IE triggers the submit click as expected, but for some reason also triggers the "some button" click (even without my keypress listener):
$('input[type=submit]').click(function () {
alert('Submit click');
});
//SIMULATE CLICK IF ENTER PRESSED IN SEARCH
$('input[type=text]').keypress(function (event) {
var keycode = event.keyCode || event.which;
if (keycode == 13) $('input[type=submit]').click();
});
//ROUTE CLEAR HANDLER
$('button').click(function () {
alert('Button click');
});
You can see the bug in action here: http://jsfiddle.net/h64xD/

Here are a couple of things to consider:
IE9 counts the <button/> element as type="submit" by default. So to make it non-submit, you have to be explicit:
<button type="button">Some button</button>
If you do that, you will notice that the emulated click event now doesn't trigger the <button/> but still fires 2 events. The reason is that, because you haven't explicitly defined a <form/> element, IE9 assumes the controls as being in a form, and thus pressing enter in the textbox triggers 2 events:
the one that you are emulating
the default form submit button behaviour
So again to get around this issue, you have to be explicit:
<button type="button">Some button</button>
<form><input type="text" /></form>
<input type="submit" value="Submit" />
Now, these are the reasons that you are seeing the behaviour in IE. #MrSlayer's answer caters to the second issue of stopping the keypress event after you have satisfactorily handled it, using preventDefault()

The Enter key has a default behavior to submit, so you need to prevent the default behavior from executing. Because the button tag is, by default, type="submit" it is executing that button when the Enter key is pressed.
//SIMULATE CLICK IF ENTER PRESSED IN SEARCH
$('input[type=text]').keypress(function (event) {
var keycode = event.keyCode || event.which;
if (keycode == 13)
{
event.preventDefault();
$('input[type=submit]').click();
}
});

How about triggering the form's submit instead of a button click?
$('input[type=text]').keypress(function(e) {
var keycode = event.keyCode || event.which,
frm = $(this).closest('form');
if (keycode == 13) {
e.stopPropagation();
frm.submit();
return false;
}
return true;
});
--EDIT--
Updated Slightly to stop the event propagation.

First off, you don't need to manually attach an event to submit a form when the user presses enter - the browser already handles that.
Oddly enough, this was to do with the order of the elements, implicit form-associations, as well as the fact that IE handles buttons as submit elements.
Try swapping the order of these buttons to see what I mean:
<input type="text" />
<input type="submit" value="Submit" />
<button>Some button</button>
Naturally, the browser is already instructed to listen to respond to the Enter on a text-input. This results in the browser clicking the associated submit button. Further, since you haven't explicitly provided a form, or associated elements with one another via their form attribute, the browser is attempting to make that relationship for you.
In your code, the <button> element was assumed to be the submit button of the text-input (because it was the first submit button in the implicit form). As such, anytime you press Enter on the text-input, the browser naturally raises the click event of the associated button.
If you re-order the elements, as I have above, we see the opposite take place. IE associates the other <input> element with the text-box. And pressing Enter on the text-box implicitly raises the click event on the submit input.
You can confirm this behavior by comparing the .form attributes of various elements. For instance, adding some id values will give us easier access to these:
<button id="fiz">Some Button</button>
<input id="foo" type="text" />
<input id="bar" type="submit" value="Submit" />
Then run some quick comparisons:
var button = document.getElementById("fiz");
var text = document.getElementById("foo");
var submit = document.getElementById("bar");
button.form === text.form; // true
submit.form === text.form; // true
button.form === submit.form; // true
So in the end, it's up to you to remove the ambiguity between the two buttons, by declaring the <button> element to be type='button', or by placing it after the intended submit button.

Related

Remotely preventDefault() a Form in another Function

I'm not really sure how to ask/word this question but...
How can I prevent a form from submitting from another jQuery function? Basically, I have input fields with auto-complete functionality where the end-user can navigate through the results by using the up-and-down arrow keys. The end-user can press the Enter key to make a selection however that makes the form submit. I would like to prevent that from happening.
$('body').on('click keyup', '.inputField1', function(e) {
if(e.keyCode===13){
// Attempting to remotely prevent the form from submitting
var form = $(this).closest('form');
form.preventDefault();
form.stopPropagation();
return false;
}
// auto-complete logic below
// ...
});
Please note that I've tried adding the logic above under $('#myForm1').submit(function(e){ ... but the enter key was not detected upon input.
Assuming you're trying to prevent the form submitting when the user hits "enter" while an input field is in focus:
You want to attach this handler to the input field itself, and should use the keydown or keypress event rather than keyup (which happens after the form submission has started). What you're preventing isn't the form submit, but the default action of the event which triggers the form submit, so call preventDefault() on the event, not on the form.
event.keyCode and event.which are deprecated, but still universally supported. The currently "correct" way to do this would be if (event.key === "Enter") but this may not work in some older browsers (and note that current IE and Edge still use nonstandard identifiers for some keys.)
// It's not necessary to delegate the event from 'body', unless the form field is added to the DOM after this is called.
$('.inputField1').on('keydown', function(e) {
if (e.keyCode === 13) {
e.preventDefault();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="https://example.com">
<input class="inputField1">
<input type="submit">
</form>
Your problem is keyup on the input triggers before submit on the form.
If you change your event to keypress you'll find you can intercept the submit event before form submission.
Also, you should be using event.which instead of event.keyCode - jQuery standarizes .which but I don't think it does the same for .keyCode.
The following code sample will show this in action. The first text field will intercept when you press enter, the second will not.
(function($) {
$(function() {
$('body').on('keypress', '.a', function(event) {
if(event.which == 13) {
alert('You pressed enter');
event.preventDefault();
}
});
});
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="get" action="https://www.stackoverflow.com" onsubmit="alert('submit event');return false;">
<input class="a" type="text">
<input class="b" type="text">
<input type="submit">
</form>

Trying to add some form control when enter is clicked on an HTML field, getting inconsistent results

I have an HTML form that I'm running with Firefox that looks something like this:
<form name="transfer" id = "transferForm" action='transfer.php' method='POST'>
<div>
<input id="itemSelect" name="itemSelect"/>
<input type="number" name="quantity" id="quantity" value="1"
onkeypress="return isNumberKey(event)"/>
<input type="button" value="Add" id="addButton" style="width:83px"
onclick="addItem()"/>
</div>
<div>
<span id="myForm"></span>
<button id='save' name = 'save' style="width:205px">Save</button>
<button id='transfer' name='transfer' style="width:205px"/>Transfer</button>
</div>
</form>
A few things to note:
-itemSelect is a dojo/dijit combobox that is initialized elsewhere.
-The function addItem(), found in the addButton, runs some javascript that creates new elements in the span myForm each time the add button is clicked. These are processed by transfer.php when the save or transfer button is clicked.
Everything works fine, but I want to add some user friendly controls so the form can work without mouse clicking. I want the user to be able to press 'Enter' when in the "quantity" field, and have the form run the addItem() javascript and move focus back to "itemSelect".
This is the javascript I added. First, to disable the default submit on enter of the form:
<script language="JavaScript">
window.addEventListener('keydown',function(e)
{if(e.keyIdentifier=='U+000A'||e.keyIdentifier=='Enter'||e.keyCode==13)
{if(e.target.nodeName=='INPUT'&&e.target.type=='text')
{e.preventDefault();return false;}}},true);
Then I add an event listener to "quantity"
document.getElementById("quantity").addEventListener("keyup", function(event) {
event.preventDefault();
if (event.keyCode == 13) {
//document.getElementById("addButton").click();
addItem(); //Same results using this or the line above
document.getElementById("itemSelect").focus(); //move focus back to the combo box
}
});
</script>
At first glance it appears to work, however I get two different glitches.
With this code in place, if I press enter to run the addItem() function the line gets added on the form between the span tags, but when I click "save" or "transfer" to submit the lines added this way do not not POST. In transfer.php lines that were already added show up (), but any new line added by clicking enter does not go through. However if I just click the "addButton" to add a line instead of pressing enter then it POST's just fine.
When I test adding lines with the keyboard, pressing TAB-ENTER-TAB-ENTER..., it works fine but after on about the 4th cycle the form suddenly submits to transfer.php.
So what could be going wrong with #1, and how does #2 happen?
Try the below:
Remove inline event handlers from your HTML
Seperation of concerns
Know the difference between onKeyPress Vs. onKeyUp and onKeyDown
Stackoverflow question
Prevent form submission on enter:
document.getElementById("transferForm").addEventListener("keypress", function (e) {
e = e || event;
var txtArea = /textarea/i.test((e.target || e.srcElement).tagName);
return txtArea || (e.keyCode || e.which || e.charCode || 0) !== 13;
})
Call addItem on quantity input enter
document.getElementById("quantity").addEventListener("keypress", function (event) {
var keyCode = event.keyCode || event.which;
if (keyCode === 13) {
event.preventDefault();
addItem(); // addItem function call
}
});
call addItem on add button click
document.getElementById("addButton").addEventListener("click", addItem);
function addItem() {
// addItem code
}
Mitigate browser inconsistencies with javascript libraries like jQuery
In your code you might have noticed about getting the keycode value using which.
However jQuery normalises event.which depending on whether event.which, event.keyCode or event.charCode is supported by the browser:

javascript: a button element is not working on click()

I AM NOT TRYING TO SUBMIT A FORM USING JAVASCRIPT!!" The above remark is misleading, inappropriate and confused
I have a html form that contains several elements (all with unique #id) which when clicked using the mouse correctly submits the form with the action=value pair.
<html><body><form id="frm-table" name="frm-table" method=get>
<!-- the form has an action url to call php script that interprets passed values and serves new dynamic page -->
<!-- #20140820 - #id and #name added to form -->
<button id="cancel-btn" type="submit" name="action" value="cancel"><img src="http://foo.localhost/img/cancel16.png" alt="Cancel" title="Cancel" class="btn" name="btn_c" /></button>
<!-- several other inputs eg type=text and buttons type=submit -->
</form></body>
I have a js script that captures a document ESC keydown and as example: displays an alert to confirm capture.
document.onkeydown = function(evt) {
evt = evt || window.event;
var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
if (evt.keyCode == 27) {
if (document.getElementById('cancel-btn') != null) {
// alert('Esc key pressed.'); //just to test capturing ESC key - OK
// testing suggestion 201408211700
document.getElementById('frm-table').action = 'http://foo.localhost/index.php?page=bg'
document.getElementById('frm-table').submit(); //suggestion does not work - form not submitted
// document.getElementById('cancel-btn').click(); //original does not work
}
evt.returnValue=false;
}
if ((evt.keyCode == 13) && (node.type=="text")) {return false;}
};
When the alert is replaced by a .click() nothing happens.
I do not understand why the native click event is not firing.
I am aware there is no click event on a button element, however it does accept and action a mouseclick on it. Calling a function to submit the form (by adding a listener event to the button does not work - it submits the form but the posted values do not include the button action=value pair.
So is there another js command to trigger the button element''s native functionality? Is important to note that the button is one of several type=submit buttons all of which give a different action-value pair.
[Ed] In an attempt to clarify:
I am not trying to add a handler to the button element just trying to replicate the native type=submit function of the button. (mouse clicking the button submits the form with the important action=value pair without any js)
I only have the option of adding javascript at my disposal not changing the dynamic generation of the page as it is part of a much larger application.
So although I thank those who have responded, the answers, so far, they do not resolve the question.
Tested in Firfox31 and IE9
That is because the <button> does not have an onclick handler on it, so it won't be triggered.
Instead of
document.getElementById('cancel-btn').click();
you can just do
document.forms[0].reset();
which will also reset the form.
Unless the button that is called cancel-btn actually has to submit the form in which case you need:
document.forms[0].submit();

How to stop element with first onclick event to be fired when enter key is pressed first time

I was fixing a bug in a jsp page in which even though a function is defined with onkeypress event to click a particular button (actually its an image of button with onclick property associated with it) when the page is opened first time and then enter key is pressed its throwing an error.
When I debugged the code then I find out that actually two calls are made simultaneously. i.e. the first button with onclick property is also clicked.
Here is just a sample code:
<html>
<head>
</head>
<body>
<div onkeypress =handleEnter()>
name <input type="text" src='Create.gif' >
</br>
<input type="image" src='Create.gif' onclick="alert('not done')">
<input type="image" src='Create.gif' onclick="alert('done')">
</div>
</body>
<script>
function handleEnter()
{
if(window.event.keyCode==13)
{
alert('nothing');
event.cancelBubble=true;
}
}
</script>
</html>
on pressing enter key both functions are getting called.
The following will probably work. By preventing the default action of the keypress it should stop the browser from triggering the standard "form submit" — which is what I think is happening.
function handleEnter(e)
{
e || (e = window.event); /// support for both ie and non-ie browsers
if(e.keyCode==13)
{
alert('nothing');
// old ie support
e.cancelBubble = true;
e.returnValue = false;
// non-ie
e.preventDefault && e.preventDefault();
e.stopPropagation && e.stopPropagation();
}
}
You have to bear in mind though that if you are preventing default for enter on the whole page, it will stop it working for textareas and other places where enter might be used. If this is a problem you could decide whether or not to prevent the default action depending on:
var elm = e.srcElement || e.target;
elm should contain the triggering element of the event. scrElement is for old IE and target is for non-IE browsers. For example, you could use this to shortcircuit your code before reaching the prevent default.
if ( elm.nodeName == 'textarea' ) return;
I don't have IE8 lying around to test this however, but considering the following link, it is likely to work:
http://support.microsoft.com/kb/298498
I know this is an old question, but I did not find any other questions/answers for this, and I was having this same issue with buttons.
But for some reason when I look at the "event" that is passed into javascript function, there is no keyCode passed in with it, so I can not distinguish which key was pressed. FYI "event" was only passing in isTrusted property (and nothing else), but that is another question for another time...
My solution was that I just added a button with onclick="return false;" and style="display:none;" in front of all the other elements so that the ENTER key affects this element and is essentially ignored, and is invisible. With onclick='return false;' the form will NOT be submitted. With onclick='return true;' the form WILL be submitted.
<button id='prevent-onclick-on-enter' style='display:none;' onclick='return false;'/>
<input type="image" src='Create.gif' onclick="alert('not done')">
<input type="image" src='Create.gif' onclick="alert('done')">
SECOND ANSWER
So this is maybe for a slightly different issue that only involves BUTTONS (not INPUTS), but this may be good to know for some people (like me) that did not know this...
When you have a button in a form, it defaults to type "submit" which means the first button in a form will have its onclick event triggered by the ENTER key. To prevent this from happening, simply assigm type="button" to the button, and enter key will no longer affect it.
as jsherk mentioned, any unintended onclick should have type="button" and will stop firing when enter is pressed

Pressing Enter Always Submits Form

I have a simple text box and button type input on my page.
<input id="sText" type="text" />
<input id="sButton" type="button" value="button" />
I capture a button click using jQuery.
$("[id$=sButton]").click(function () {
...do Stuff
});
The above code works just fine as long as I manually click the button. I started running into problems when I wanted to use the "enter" key to click the button. No matter what I do, I cannot prevent the enter key from performing it's default submit function.
The first thing I did was change the input type from "submit" to "button".
I tried setting the form's onsubmit to onsubmit="return false;"
I tried using jQuery to capture the enter key event:
$("#sText").keyup(function (event) {
if (event.keyCode == 13) {
alert("Enter!");
// $("#sButton").click();
}
});
Every time I press the enter key, it's like I'm submitting the form, the whole page refreshes. The above jQuery code does capture the "enter" keystroke, but the form still submits and refreshes the page.
I'm not sure whats going on.
You need to cancel the action.
event.preventDefault();
BUT I believe you can only kill the form submission with keydown, not keyup.
Epascarello is right, you need to cancel the for submit with the code he gave you. But you should also change the button back to a submit type so that the ENTER key and Clicking the button do the same thing. That way you only have to handle the cancellation of the submit in one area.
<input id="sButton" type="submit" value="Submit" />
JQuery:
$("#YourFormId").submit(function(event){
event.preventDefault();
...do Stuff
});
This way one function handles the ENTER key and the button click.
EDIT: Put the event.preventDefault() as the first statement.

Categories

Resources