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();
Related
I have an edit form using the jQuery Validation plugin. It's part of an ASP.NET Core project, also using ASP.NET's Unobtrusive Validation plugin. The form has two submit buttons, posting to different handlers server-side:
Submit changes
Delete entry
"Submit changes" is working fine, however I'd like the "Delete" button to skip any client-side validation. Currently it won't post the form if any required fields are missing (or any other validation condition doesn't pass).
I've tried the HTML5 formnovalidate attribute on the "Delete" button without success. Is there an equivalent feature in the jQuery Validation plugin? If not, how would you bypass validation only for a specific submit button?
EDIT:
The "Delete" button is actually outside the <form> tag, but referencing the form by ID through the form attribute:
<form id="my-form">
<!-- form fields and submit button here -->
</form>
<button type="submit" form="my-form" noformvalidate asp-page-handler="Delete">
Delete entry
</button>
I've found that when moving the "Delete" button inside the <form>, the noformvalidate attribute works as expected. I would really like to keep this button outside the <form> tag (due to the page's layout), though I might be able to work around it if there's no other way.
Any ideas on how to make it skip validation while placed outside the form?
The problem you have seems to be summarized in this issue:
Typical save vs submit button where save does not validate and submit
does. Save button is declared with the formnovalidate attrribute. Only
thing is that these buttons are outside of the form itself.
See, the plugin expects the submit buttons to be inside your form. It actually still handles both 'preventing' flags - cancel class and formnovalidate attribute - within click handler propagated from buttons to the top of the form (source):
// "this" is jQuery-wrapped HTMLFormElement with validator attaching
this.on( "click.validate", ":submit", function( event ) {
// Track the used submit button to properly handle scripted
// submits later.
validator.submitButton = event.currentTarget;
// Allow suppressing validation by adding a cancel class to the submit button
if ( $( this ).hasClass( "cancel" ) ) {
validator.cancelSubmit = true;
}
// Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
if ( $( this ).attr( "formnovalidate" ) !== undefined ) {
validator.cancelSubmit = true;
}
} );
... which clearly doesn't work if buttons are outside of form DOM hierarchy, like in your case. Only submit.validate handler is fired, but it expects to check validator.cancelSubmit flag (and set it to false if it's truthy).
One idea that comes to mind is to place your own click handler on Delete button that will override that flag. Validator instance is accessible through form $.data, as usually with jQuery plugins:
const validator = $.data(form, 'validator');
Perhaps you are looking for something like this:
var $frm = $('#my-form')
, frm = $frm[0]
, $btnsubmit = $('button[type="submit"]');
frm.addEventListener('submit', (evt) => {
var skipValidation = evt.submitter.hasAttribute('formnovalidate')
, validator = $frm.data('validator');
skipValidation && validator !== undefined
? (validator.cancelSubmit = true)
: ($frm.valid() && $btnsubmit.prop('disabled', true));
})
here I'm using a mix of vanilla JS and JQuery because not all submit-event properties are available in JQuery and is not so recommended to access JQuery data using vanilla JS.
In this case, there is no matter where are declared your submit-buttons but... you should be sure to execute the above script before $.validator.unobtrusive.parse(document) that mean before validator.unobtrusive become obtrusive.
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:
When my user presses 'Enter' after clicking a checkbox, my form should act as though the 'Next' button was pressed. But, I am using PPR (partial page rendering) so that when it is clicked, my checkbox triggers a 'Next' button to get repainted. This is done by setting autoSubmit="true" on the checkbox and a partialTrigger on the button.
The problem is that with autoSubmit=”true” on my component, the javascript/jquery does not ‘hear’ the keyup event. I assume that this is because when the button that has the partialTrigger on it is repainted, my checkbox has lost focus. I have tried resetting the focus on the checkbox in an onclick method but it seems to fire too early. I set a timeout on it too, but that didn't work either. I have also tried programatically making a javascript call during the checkbox's valueChangeListener method, but this must be firing too early as well. Does anyone know why this is happening and what I can do?
Here is the code
$(document).ready(function(){
$("input[id='subview:agree']").keyup(function (event) {
if (event.keyCode == 13) {
processEnterKey();
}
});
});
function processEnterKey() {
$("button[id='subview:btnSubmit']").click();
}
Checkbox:
<tr:selectBooleanCheckbox binding="#{bean.termsOfUseChkBox}"
id="agree"
autoSubmit="true"
simple="true"
valueChangeListener="#{bean.agreementChangeListener}"/> /
Button:
<tr:commandButton id="btnSubmit"
disabled="#{!bean.agreementAccepted}"
partialTriggers="agree" text="Next"
action="#{bean.termsOfUse_action}"
partialSubmit="false"
onclick="handleLoadingPleaseWait()"
blocking="true"/>
Here is the onclick method I used to try to set focus back to the checkbox so it could 'hear' the keyup:
$("input[id='subview:agree']").click(function (event) {
if(document.getElementById('subview:agree').checked) {
setTimeout(function(){document.getElementById('subview:agree').focus();},1000)
}
});
Here is the server-side code I put in the changeListener:
FacesContext fctx = FacesContext.getCurrentInstance();
ExtendedRenderKitService erks = null;
//compose JavaScript to be executed on the client
StringBuilder script = new StringBuilder();
script.append("document.getElementById(\"subview:agree\").focus();");
erks = Service.getRenderKitService(
fctx, ExtendedRenderKitService.class);
erks.addScript(fctx, script.toString());
If you want to submit the form from each imput by pressing enter you can simply use the defaultCommand attribute on your tr:form.
Documentation on <tr:form defaultCommand="..."/>
The id attribute of the command button whose action would be invoked by default for form submit on hitting enter on any of the input fields of the form.
So, setting it to btnSubmit should do the trick.
As this did not help for your scenario, you could try adding a onkeypress attribute to your checkbox:
<tr:selectBooleanCheckbox binding="#{bean.termsOfUseChkBox}"
id="agree"
autoSubmit="true"
simple="true"
valueChangeListener="#{bean.agreementChangeListener}"
onkeypress="if (event.keyCode === 13){ this.click(); }"/>
For me this triggered submitting my form.
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.
I have a HTML form on my page. When i am putting some value in one of the text fields in form and press 'Enter key' the form gets submitted instantly. I think this is happening due to default focus is on submit button. But i try to remove that focus using blur() function, it is not working. I am using Chrome.
Is there any way to avoid this scenario?
All suggestions are welcome. thanks in advance.
The Submit button is not actually focused; Enter in a text field is supposed to submit the form.
You could register a handler for the submit event, and then only allow it if the Submit button was actually focused at the time submit was requested.
However, you'll be deliberately breaking the way that HTML forms work. Not everyone wants to submit the form using the One True Way of actually clicking the Submit button (also, you'll be breaking accessibility and may introduce browser-specific bugs).
No. The focus is still on the text field. Pressing enter there is supposed to submit the form (and bypasses the submit button entirely).
You can suppress the behavior using JavaScript, but since it is normal behavior for the browser, I wouldn't recommend doing so.
try this solution: replace the 'input' with 'button' and add attribute
type equals 'button' and handle the onclick event with submit javascript function
<form name='testForm'>
<input type='text' value="myName" />
<button type='button' onclick='testForm.submit()'/>
</form>
i think it works also with tag input adding the same attribute
Enjoy
Mirco
blur() is the way to go. It works like this:
<button onclick="this.blur();">some button</button>
Note that you should not use JavaScript and DOM-events using Attributes. This is just for demonstration purposes. Try to be unobstrusive.
Maybe it will help you out, the form is "supposed" to be sent with enter in the text box (HTML by design), it is no a matter of focus.
If you want to avoid it, check this out.
This is the proposed script:
function disableEnterKey(e)
{
var key;
if(window.event)
key = window.event.keyCode; //IE
else
key = e.which; //firefox
return (key != 13);
}
Good luck, tell me if you need any clarification!
EDIT: I do agree with Piskvor answer, it may bring some bugs
this has nothing to do with the focus, its just the default behavior of you browser. to avoid this, you could try to cath the enter-keypress like this (Source - but there are a lot of other solutions (most working the same way, just using other events like the firms onsubmit instead of the documents onkeypress)):
function catchEnter(e){
// Catch IE’s window.event if the
// ‘e’ variable is null.
// FireFox and others populate the
// e variable automagically.
if (!e) e = window.event;
// Catch the keyCode into a variable.
// IE = keyCode, DOM = which.
var code = (e.keyCode) ? e.keyCode : e.which;
// If code = 13 (enter) or 3 (return),
// cancel it out; else keep going and
// process the key.
if (code == 13 || code == 3)
return false;
else
return true;
}
// Anonymous method to push the onkeypress
// onto the document.
// You could finegrain this by
// document.formName.onkeypress or even on a control.
window.onload = function() { document.onkeypress = catchEnter; };
Change:
<input type="text" ... >
To:
<textarea ... ></textarea>
You may need to mess around with the attributes a bit, I've left them signified as ....
try to add on the keypress event of your button this javascript function :
function ButtonKeyPress()
{
var code = (window.event.which) ? window.event.which : window.event.keyCode;
if ( code == 13 )
{
event.returnValue = false;
return false;
}
return true;
}
So, you have a form. In this form, you have a text input, and a submit button.
You get in the text input, you type some text, than you press "Enter". This submits the form.
You would like to break this normal behavior.
I think this is not a good idea : The convention says that when your in a text input and press "Enter", it submits the form. If you change this behavior, users could be (I don't find the right word, let's say ~) surprised.
Anyway, if you still want to do this, you should listen for the keypress event on the text input, and than prevent default behaviour shoud do the work.
let's say you use jQuery :
$(input[type=text]).bind('keypress', function(evt) {
if(evt.keyCode == 13) {
evt.preventDefault();
}
});
This should do it. I didn't test it, maybe I made mistakes, but you got the idea, no ?
And maybe keyup is better than keypress... I don't know very well this, not enough practice on key bindings
The easiest way is to set css style like this:
&:focus {
outline: 0 none;
}