I have a page with two buttons. One is a <button> element and the other is a <input type="submit">. The buttons appear on the page in that order. If I'm in a text field anywhere in the form and press <Enter>, the button element's click event is triggered. I assume that's because the button element sits first.
I can't find anything that looks like a reliable way of setting the default button, nor do I necessarily want to at this point. In the absence of anything better, I've captured a keypress anywhere on the form and, if it was the <Enter> key that was pressed, I'm just negating it:
$('form').keypress( function( e ) {
var code = e.keyCode || e.which;
if( code === 13 ) {
e.preventDefault();
return false;
}
})
As far as I can tell so far, it seems to be working, but it feels incredibly ham-fisted.
Does anyone know of a more sophisticated technique for doing this?
Similarly, are there any pitfalls to this solution that I'm just not aware of?
Thanks.
Using
<button type="button">Whatever</button>
should do the trick.
The reason is because a button inside a form has its type implicitly set to submit. As zzzzBoz says, the Spec says that the first button or input with type="submit" is what is triggered in this situation. If you specifically set type="button", then it's removed from consideration by the browser.
It is important to read the HTML specifications to truly understand what behavior is to be expected:
The HTML5 spec explicitly states what happens in implicit submissions:
A form element's default button is the first submit button in tree order whose form owner is that form element.
If the user agent supports letting the user submit a form implicitly (for example, on some platforms hitting the "enter" key while a text field is focused implicitly submits the form), then doing so for a form whose default button has a defined activation behavior must cause the user agent to run synthetic click activation steps on that default button.
This was not made explicit in the HTML4 spec, however browsers have already been implementing what is described in the HTML5 spec (which is why it's included explicitly).
Edit to add:
The simplest answer I can think of is to put your submit button as the first [type="submit"] item in the form, add padding to the bottom of the form with css, and absolutely position the submit button at the bottom where you'd like it.
Where ever you use a <button> element by default it considers that button type="submit" so if you define the button type="button" then it won't consider that <button> as submit button.
I don't think you need javascript or CSS to fix this.
According to the html 5 spec for buttons a button with no type attribute is treated the same as a button with its type set to "submit", i.e. as a button for submitting its containing form. Setting the button's type to "button" should prevent the behaviour you're seeing.
I'm not sure about browser support for this, but the same behaviour was specified in the html 4.01 spec for buttons so I expect it's pretty good.
By pressing 'Enter' on focused <input type="text"> you trigger 'click' event on the first positioned element: <button> or <input type="submit">. If you press 'Enter' in <textarea>, you just make a new text line.
See the example here.
Your code prevents to make a new text line in <textarea>, so you have to catch key press only for <input type="text">.
But why do you need to press Enter in text field? If you want to submit form by pressing 'Enter', but the <button> must stay the first in the layout, just play with the markup: put the <input type="submit"> code before the <button> and use CSS to save the layout you need.
Catching 'Enter' and saving markup:
$('input[type="text"]').keypress(function (e) {
var code = e.keyCode || e.which;
if (code === 13) {
e.preventDefault();
// also submit by pressing Enter:
$("form").submit();
}
});
Pressing enter in a form's text field will, by default, submit the form. If you don't want it to work that way you have to capture the enter key press and consume it like you've done. There is no way around this. It will work this way even if there is no button present in the form.
You can use javascript to block form submission until the appropriate time. A very crude example:
<form onsubmit='return false;' id='frmNoEnterSubmit' action="index.html">
<input type='text' name='txtTest' />
<input type='button' value='Submit'
onclick='document.forms["frmNoEnterSubmit"].onsubmit=""; document.forms["frmNoEnterSubmit"].submit();' />
</form>
Pressing enter will still trigger the form to submit, but the javascript will keep it from actually submitting, until you actually press the button.
Dom example
<button onclick="anotherFoo()"> Add new row</button>
<input type="text" name="xxx" onclick="foo(event)">
javascript
function foo(event){
if(event.which == 13 || event.keyCode == 13) // for crossbrowser
{
event.preventDefault(); // this code prevents other buttons triggers use this
// do stuff
}
}
function anotherFoo(){
// stuffs.
}
if you don't use preventDefault(), other buttons will triggered.
I would do it like the following: In the handler for the onclick event of the button (not submit) check the event object's keycode. If it is "enter" I would return false.
My situation has two Submit buttons within the form element: Update and Delete. The Delete button deletes an image and the Update button updates the database with the text fields in the form.
Because the Delete button was first in the form, it was the default button on Enter key. Not what I wanted. The user would expect to be able to hit Enter after changing some text fields.
I found my answer to setting the default button here:
<form action="/action_page.php" method="get" id="form1">
First name: <input type="text" name="fname"><br>
Last name: <input type="text" name="lname"><br>
</form>
<button type="submit" form="form1" value="Submit">Submit</button>
Without using any script, I defined the form that each button belongs to using the <button> form="bla" attribute. I set the Delete button to a form that doesn't exist and set the Update button I wanted to trigger on the Enter key to the form that the user would be in when entering text.
This is the only thing that has worked for me so far.
You can do something like this.
bind your event into a common function and call the event either with keypress or button click.
for example.
function callME(event){
alert('Hi');
}
$('button').on("click",callME);
$('input ').keypress(function(event){
if (event.which == 13) {
callME(event);
}
});
I added a button of type "submit" as first element of the form and made it invisible (width:0;height:0;padding:0;margin:0;border-style:none;font-size:0;). Works like a refresh of the site, i.e. I don't do anything when the button is pressed except that the site is loaded again. For me works fine...
I am trying to intercept "Hide keyboard button" specific for Ipad in Javascript. I searched everywhere but could not find correct keycode for that.
I pressed any keys and I get a keycode map (for characters, but also for enter, space and delete..).
This is an example of what I want to accomplish
$( "#mydiv" ).on( "keydown", function( event ) {
if (event.which == xx){
//do something
}
}
where xx is my keycode on 'hide keyboard button'. No method is called to the delegate when the button is pressed nor a KeyCode.
I took a look at detect iPad keyboard Hiding button, but I get a solution on a different level (with Xcode), but I need a solution with Javascript.
Hope someone could help.
I found a workaroud for iPad IOS7. I will test on IOS8 to make sure it works. So basically I create a listener on every FOCUSOUT event (for all my texts) and I call my function.
It fires when you have your keyboard open and when you close your "keyboard". It doesn't fire when you select another text field or button, because it targets on null. If you use in combination with keydown, you can save multiple value and call your submit function only when you release your keyboard.
It works for my specific project.
document.addEventListener('focusout', function(e) {
if (e.relatedTarget === null) {
alert("close keyboard without click on something else");
callYourFunction();
}
});
p.s
I'm pretty new here in SO, so I don't know if I can reply myself or I should edit my question or make a comment.
Is there a way to link a button to an input, so mobiles know what to do when you press Next or Go on the keyboard within a .NET context (i.e. Pressing 'Go' on an input fakes the click on the next button instead of submitting the form)?
Let's talk code for a second. I have the following markup, where injected-via-js is injected via javascript into a large form (progressive enhancement).
<form class="dotNET-form-wrapper">
<div class="injected-via-js">
<div>
<span>£</span>
<input type="number" />
</div>
<div>
<button>accept</button>
</div>
</div>
<!-- More form elements -->
</form>
On most mobile browsers, when you change the value in the number input and press Go or Enter it fakes the button press (which in my case has an important event bound to it). However on some old Android devices pressing Go will submit the form instead, which is not what I want. To clarify: I want the Go button to fake the button press, not submit the form.
Note:
.NET is only relevant to this question due to the fact that everything is wrapped in a form, meaning I cannot create a separate form around the input and button and highjack the new form's submit.
I've made a JSBin where I was able to replicate this bug with an Android 2.2 phone although I imagine it exists on other bad browsers as well. It works as expected on iOS 6+ and Android 2.3+.
Here's the demo page: http://jsbin.com/tebizoda/2
And here's the edit version: http://jsbin.com/tebizoda/2/edit
Both "Go" and "Enter" has keycodes like the enter on the keyboard (13) so you should just make a JavaScript or jQuery function that overrides the default behaviour and just triggers the button press. Something like (example in jQuery):
$(your_form_or_input).keypress(function (e) {
if (e.keyCode == 13) {
return false;
} else {
// your code here...
}
});
Mind that some browsers use e.keyCode, others e.which to determine the pressed key code.
I need to detect how a user submitted a form to generate some statistics. They can either press enter when typing on the input or they could click the submit button.
I tried binding a click event to the button and a keyup event to the input but what happens is when I press enter the click event is triggered. I read in some other thread that this is part of the new HTML5 spec or something like that.
I then thought of binding a submit event to the form and detecting there what originated that event, but I've had no luck so far. Is that even possible?
EDIT
I guess I managed to fix it. I changed my keyup event to keypress, like suggested by fortegente, and prevented the defaultEvents from firing while at the same time triggering a submit event on the form. That seemed to do the trick.
You can try add custom attribute. Something like this:
$('form').submit(function(){
alert($(this).attr('event'));
});
$("button").on('click', function() {
$("form").prop("event", "click").submit();
});
$("input").on('keypress', function() {
if (e.which == 13) {
$("form").prop("event", "keypress").submit();
}
});
This is a weird bug, indeed. In Chrome (6.0.472.62, latest) and IE8 (at least), this behaves correctly, but in FF (3.6.9, latest) both the click event and enter event register, making it hard to discern between the behavior.
Check out this code: http://jsfiddle.net/QmkwY/1/, click on the search box in the "results" and just hit enter. The results underneath should register click event: 1 enter event: 13, which is clearly incorrect.
I have different things happening for click events and enter events on my page, so when an enter event registers as a click event, you can imagine the frustration!
Anyone have a clever solution?
In clickEvent, you can check e.pageX and e.pageY to be sure they have values to see if it was actually clicked.
if (e.pageX == 0 && e.pageY == 0) {
return;
}
But that will also affect "clicking" the button via spacebar. If that's not ok, you'll need to bind spacebar to the button separately.
$('#button').keyup(function (e) {
if (e.which == 32) {
// do something
}
}
You are binding to event to '#button' it should be '#search'
Well, when your button is hidden I'm only getting the enter event, and not the click event in Chrome. However, when I show the button I get both. I also inserted a button between your button and the input, and that causes it to not fire the click event.
I believe this is intended as a shortcut to submit forms, you could do workarounds as others have posted, but I don't think this is a real 'problem.'