I apologise in advance for not being able to provide any actual code, as the problem appears in a page which is currently private :-/ Please bear with me.
I have an HTML form. I attached a (proprietary) calendar widget to one of the text input fields. When the user tabs into the field the calendar appears. On the calendar there are a couple of buttons (to move to the previous/next month). When the user clicks on one of these buttons the calendar updates itself accordingly, but also - the form submits! There's NOTHING in the calendar code that touches anything other than the calendar itself and the text input field it is attached to, let alone submits a form! I would appreciate any clue regarding any of the following questions:
1) What could possibly have submitted the form in such a setting?
2) What things generally submit a form, other than clicking on the submit button or hitting the enter key? (In particular, do ordinary buttons submit forms? Under which circumstances?)
3) As a workaround in case I don't manage to figure this out, is there a way to simply totally disable submitting the form (and then reenable it in an event handler attached to the submit key)?
Note(s): The calendar behaves normally other than that - responds normally to key events and to click events on the dates themselves (which are not buttons). I tried this on both Firefox and Chrome and got the same behaviour. I tried to follow the click event handler step-by-step with FireBug, and everything seemed perfectly normal - but the moment it finished the form was submitted (and the page reloaded). The widget uses jQuery 1.7.2. Any help in understanding and/or solving this will be most appreciated!
Sorry to answer my own question, but none of the given answers was complete, even though I've learnt from them and from the comments! Thanks for everyone who participated!
So:
1+2) Buttons defined by the <button> element cause submits (as if they had type="submit" set. At least in some browsers). If one wants a button not to cause a submit one should use <button type="button">, or the good old <input type="button" />.
3) (Unnecessary for me now, but it was part of the question.) There are many ways to prevent a form from submitting. Three of them are:
to handle the onsubmit event, preventing the submit (by return false; or - preferably! - by e.preventDefault();) in case a flag is not set; set the flag when handling the event(s) that should actually submit the form
to handle the onsubmit event and prevent the submit as above if the element that triggered the event is not (one of) the element(s) we want to cause a submit
to set the form action to non-action, i.e. action="#", and to have the handler for the event that should actually submit the form set the action to the proper address
The calendar can submit your form in its JavaScript source code by calling form's submit() method using jQuery or plain JavaScript.
Here is an example how to disable the form submit and allow it only in case of pressing the button.
<form id="form">
<input type="text" />
<input type="button" name="submit-button" value="Submit"/>
</form>
<script type="text/javascript">
var form = document.getElementById('form'),
button = form['submit-button'];
form.onsubmit = function(e) {
return !!form.getAttribute('data-allow-submit');
};
button.onclick = function() {
form.setAttribute('data-allow-submit', 1);
form.submit();
};
</script>
Demo
The calendar code isn't calling submit() somewhere?
3) As a workaround in case I don't manage to figure this out, is there a way to simply totally disable submitting the form (and then reenable it in an event handler attached to the submit key)?
Unfortunately, I'm not totally sure if it's reliable that the click handler will be called before the form submit event.
( function () {
var prevent_submit = true;
$( "form" ).on( 'submit', function ( event ) {
if ( prevent_submit ) {
event.preventDefault();
}
} );
$( "input[type='submit']" ).on( 'click', function ( event ) {
prevent_submit = false;
} );
} )();
or
$( "form" ).attr( { action : "#", method : "post" } );
$( "input[type='submit']" ).on( 'click', function ( event ) {
event.target.form.action = "...";
} );
Hitting enter on text fields can sometimes trigger a form submit. See here. Especially if that is the only element in the form. One way to control the post back is to set the action to empty and fire off the event yourself with Javascript.
Check the placement of the closing form tags. I had this problem once and I finally figured out that there was some 'permissions' code within the form itself that prevented the user from reaching the closing tag because he didn't have the proper permission level to submit it. In effect this left an open form tag that then responded to other buttons elsewhere on the same page.
Related
My question is about react, onSubmit and preventDefault.
I've got a form, which handles between 2 - 4 steps of user input depending on certain cases.
<Form>
{StepRendersHere}
</Form>
The form has a onSubmit event that prevents default (and stopPropagation).
When using the button for "next step" the event fires, and the form is NOT submitted.
But when using the enter key, the event is fired, but the form is posted. This results in the site refreshing with the form data as url parameters.
The weird thing is that if none of the buttons in the form has type="submit". The onSubmit doesn't even fire on enter key.
isDefaultPrevented returns true in both cases.
Any hints/thoughts on how I can prevent the form from posting when pressing enter? My issue is with Enter key posting the form, despite preventDefault.
Have tried binding the enter key to a event that prevents default, doesn't work. Might have done it the wrong way though.
UPDATE (implementation)
<Form onSubmit={this.inc_step} id="applicationform">
{FormStepRenderedHere}
</Form>
inc_step = e => {
e.preventDefault();
e.stopPropagation();
alert( e.isDefaultPrevented() )
let new_step = this.state.current_step + 1;
alert('INSIDE INC STEP');
if (this.validateForm()) {
this.setState({
current_step: new_step
})
}
}
UPDATE (FIXED IT)
I found a solution, and want to share if anyone else has the same problem.
My solution however might be unique to semantic ui, which i'm using. I solved it by putting as={Form.Group} on the form, mening it wont render as a form, with its standard events, such as enter key submit. Now the enter key does nothing, as I wanted it.
Thank you for the comments!
A much easier way to accomplish this is to add a button element to your form and add the display none css attribute (if you don't want to see the button).
The button automatically adds the ability to use the enter key with onSubmit.
I found a solution, and want to share if anyone else has the same problem.
My solution however might be unique to semantic ui, which i'm using. I solved it by putting as={Form.Group} on the form, mening it wont render as a form, with its standard events, such as enter key submit. Now the enter key does nothing, as I wanted it.
So actually not rendering the form as a form to begin with was the solution.
I need to get a form to submit but when it submits I need it to disable the button because the query takes a few seconds to run and the people using this form don't understand loading pages and so they will click 5 or 6 times on the button submitting the form way to many times. I had a working method in Chrome but in IE it submits twice and I know why but I don't know how to get it to work for both. Here is the form line:
<form method="post" id="submitItem" action="secondPage.php">
I have tried various versions of this such as using onSubmit or other related ideas but none work. The "Working" solution in chrome that submits twice in IE is that form call and the following JS:
$( document ).on( "click", ".once-only", function(){
$(".once-only").prop('disabled', true);
$('form').submit();
});
The class "once-only" is attached to the submit button so upon clicking submit that button gets disabled in both browsers but because I have "action='....'" in the form instantiation line it submits using that and the ".submit()". Chrome does not submit using the action but only the ".submit()". Is there a way to get this working? I have tried a large combination of changing the JS to use a function or taking out the ".submit()" or even changing what is in the form line but I haven't figured one out. Any ideas? IE has been giving me problems with this site anytime I use JS, the AJAX only works in chrome for all my other pages so I REALLY hate using IE but more than half the people using the site don't even know what chrome is. Any tips? I can share any other code if needed!
Try this:
$( document ).on( "click", ".once-only", function(event) {
event.preventDefault(); //this should disable the default form submit action
$(".once-only").prop('disabled', true);
$('form').submit();
});
but in IE it submits twice
For that you can first off or unbind the click followed by on
// If the button is not dynamically generated , there is no need to delegate the event
$('.once-only).off('click').on( "click",function(event){
// Rest of the code
})
For second issue
you can either use button type = "button" then use ajax instead of form action
Alternately you can use button type="submit"
$('.once-only').off('click').on( "click",function(event) {
event.preventDefault(); //prevent default behavior
$(".once-only").prop('disabled', true);
$.ajax({
url:'some url'
//Rest of code
})
});
Note ajax also works in IE
edit
or like this: onclick="this.form.submit();this.enabled=false;"
so the real answer is this
onclick="setTimeout((function(){ this.disabled = true; }).bind(this),0);"
explanation: this instructs the browser to disable the button later; since JS works in event loop, you enqueue a time-out event that'll do it outside that onclick event.
i think it is just stupid of chrome to make me do this trick.
Using Javascript, no framework, what button event should I use to confirm form when I wish not redirect? I expect to use either left mouse button or keyboard to confirm the form.
I used this element:
<button type="button" value="1">Save</button>
Using type="submit" with "submit" event is no solution for me because this creates redirection (values the from are lost). So I use type "button".
When I use
document.getElementById("advanced_form").addEventListener("click", saveOptions);
This even "click" is used with mouse. But there is possibility that the user will use keyboard instead mouse to submit form. So I suspect the form would not react to keyboard confirm action. I did not find any event related to button being pressed. So how to solve this problem?
You could still use ´type="submit"´ in combination with ´e.preventDefault();´ to aviod the redirect.
I hope this helped, good luck.
From your clarifying comment:
What happened is when I clicked the button the values which were in the form disapeared and so I understood it that the form was reloaded without any values.
Submitting a form...submits the form. What you get back as a result depends entirely on what the server sends back.
But the values should not disappear, the behaviour which I need is like in a normal Browser Window (WINAPI)
That is normal.
...the page will not clear the values. If I'd want to close the form, I'd close the tab (html page).
That isn't normal. Normal is for the form to go away and be replaced by the result of submitting it.
But you can do that with the submit event, just use event.preventDefault() within the submit event to prevent the form submission:
document.getElementById("the-form").addEventListener("submit", function(event) {
event.preventDefault(); // Prevents the form from being submitted
});
That event will reliably fire whether the user used the mouse, keyboard, or assistive technology to submit the form. The click event on a submit button will not reliably fire when the form is submitted with the keyboard or assistive technology.
You can use submit button, but you need to handle submit action. Try this (with jquery):
<input class="submit_button" type="submit" value="Save" />
<script>
function submit_form(e)
{
if (check_form_submit()) {
// check your data here
$(this).submit();
return;
}
e.preventDefault();
}
$(function() {
$('.submit_button').parents('form').submit(submit_form);
});
</script>
You should still use the submit input type but you need to prevent the default action so that the page doesn't reload.
If you are using jQuery this snippet should help.
$('#my-form').submit(function(ev) {
ev.preventDefault(); // to stop the form from submitting
// Your code here
this.submit(); // If you want to submit at the end
});
URL is here: http://prorankstudios.com/sandbox/wtf/
Using IE9, with focus on the User or Pass field, hit the ENTER key...
Notice that this whole page reloads.
What's happening is that the click handler for the #live_site_link (assigned on line 30 of common.js) is running when no click has happened on #live_site_link at all...
Login Submit code:
Login.Submit = function(e)
{
Login.feedback.empty();
if (Login.user.val() == '')
{
Camo.ErrorAlert('Invalid username.',Login.feedback);
Login.user.focus().select();
return false;
}
if (Login.pass.val() == '')
{
Camo.ErrorAlert('Invalid password.',Login.feedback);
Login.pass.focus().select();
return false;
}
Camo.AJAXStart('Logging in...');
postData =
{
user:Login.user.val(),
pass:Login.pass.val()
}
Camo.AJAXPost('index/login/',Login.Success,Login.Failure,postData);
return false;
}
live_site_link click handler:
$('#live_site_link').click(function()
{
window.location.href = './';
});
In fact, the handlers for the login form (both a keyup and a click on Go button assigned in login.js lines 22 and 24 respectively) sometimes run AFTER the page has reloaded, strangely enough.
In IE7/compatibility mode, the keyup and click handlers for login_submit properly work and the page does not reload. This is also the case in all other browsers I tested.
What is IE9 doing?
Try calling e.preventDefault() or e.stopPropagation() before you return false in Login.SubmitOnEnter
It would be better though if you wrapped a form around your form elements, then attached an event for the form submit. That way it will still work without javascript and you wouldn't have to have a separate event for click and enter press.
The only "fix" for this I could figure out short of changing the live site link button to a regular anchor tag was actually to enclose the login fields and button inside form tags.
Apparently without those enclosing form tags, IE9 is using the live_site_link button instead of the GO button to submit the form on a natural enter key press before the keyup handlers on the inputs and the click handler on the Go button of the login form ever get a chance to trigger, which causes the page to reload (as that's what the click handler for live_site_link does).
Now I have to handle logins without AJAX...
You would probably manage the login submittal process easier by using a submit handler rather than needing to catch enter key and make it click on submit button. Seems like extra code to work around doing it a simpler way
$('form').submit(function(){
var valid=someValidionFunction();
return valid;
})
Edited due to no ajax
I've got an onsubmit handler added to a form like so:
$('#content_form').bind('submit',function(e) {
source = $(e.target).attr('name');
alert(source);
return false;
});
so e.target = the form element. I'm using several submit buttons, and need to determine which one was actually clicked (in modern browsers, that clicked button is the only one that submits, I'm doing this for IE6 compat - it submits the values of all the buttons).
My only thought it to kill any onsubmit events, and then tie click events to the buttons themselves. This would kill the form functionality entirely if javascript wasn't enabled, so I'd like to avoid this.
An easy (but possibly naive) implementation would be to have the onclick handler for each button set a field indicating which one was the last one clicked. In your submit handler, you could then check the value of this field.
$('#content_form input:submit').bind('click', function(e) {
$('#content_form').submit();
// you can now reference this or $(this),
// which should contain a reference to your button
});
Have you checked out the jQuery Form Plugin? It handles submitting forms via ajax very nicely and will handle this problem (along with many others) for you.
Something else you could do is use preventDefault(); instead of return false