I'm working on an HTML form that may take a few seconds to submit. I'd like to disable some of the fields in the form after it's submitted.
I can do this in a handler on the form's submit event, but this fires before the form submits. If I disable the controls then, their values aren't included in the post data sent to the server.
I've tried cancelling the submit event in my handler, removing my submit event handler from the form, submitting the form myself via JavaScript, and then disabling the controls, but the problem there is that I need to know which button the user clicked on to submit the form. This information is in the original form submit, but obviously isn't in the one I trigger manually (as no button was clicked).
I could try to copy this information into my manual form submit, but is there a way to run my disabling code after the form submits?
Don't allow further submits by disabling the submit buttons, you don't need to do anything else. Alternatively, hide the form and replace it with something that spins so users are mesmerized into thinking that Something Important is happening.
This is pretty much the same as sp00m's answer, except it uses Javascripts native submit to prevent the recursive call.
$('#myForm').submit(function() {
this.submit();
disableFields(); // your own function
return false;
});
After submiting the form you can trigger this function:
function name() {
$("#target :input").attr("disabled", true);
return true;
}
This code will disable all the from fields descended from the element with "target" as its id.
This version just matches all input elements:
function name() {
$("#target input").attr("disabled", true);
return true;
}
You have to include the jQuery library for this code to work.
You could use jQuery's .post() to submit, and .button().click() to detect what button was clicked
.post() takes a function to execute after the submission is complete
You could delay the execution of your operations so that they are called only after the submit has been made:
$('#myForm').submit(function() {
setTimeout(function() {
// Run disabling code here
}, 1);
return true;
}
setTimeout(fn, 1) will place the function inside at the end of the execution queue, so that the form submission has been started before the functions run.
setTimeout can be used for queuing operations a bit like thread indexing or z-index:
StackOverflow: Why is setTimeout(fn, 0) sometimes useful?
Related
Here's the part of my form:
<form name='form-main' onsubmit='return validate()' action='' method='post'>
<center><input type='submit' onClick='this.disabled=true; this.form.submit();' value='I accept - Download the GM!'/></center>
</form>
and here's the validate function:
function validate()
{
// this is just to test if it actually shows
alert('You must not leave any of the fields blank!');
return false;
}
Whenever I hit the submit button, nothing happens, the page just reloads.. I would like it so it shows the alert dialog.
When you call the form's submit function, the submit event is not fired. This is by design, the assumption is that if you're triggering the submission from code, you've already done any necessary validation. (Note that this is true of the HTMLFormElement#submit function; it is not necessarily true of the wrappers libraries put around it.)
In your example, I would remove the click handler on the button. It's a submit button, so just put any relevant logic in the submit event on the form. Alternately, if you prefer, call validate() as part of the button's click.
You can override the original prototype "submit" method like this:
HTMLFormElement.prototype._submit = HTMLFormElement.prototype.submit;
HTMLFormElement.prototype.submit = function (){
this._submit();
alert('Deddy Is Great :)'); // or fire the onsubmit event manually
};
The onclick event of your submit button is firing immediately before the onsubmit event of your form, and this is disabling subsequent events from propagating and firing, which causes the validate function to never get triggered. You can see this is you remove the this.disabled=true; from your code example.
Per the docs at W3:
A form control that is disabled must prevent any click events that are
queued on the user interaction task source from being dispatched on
the element.
You should remove the click event code from the submit button, and simply allow the function to do what you need it to do, including disabling the button. For example:
function validate() {
// this is just to test if it actually shows
document.getElementById('sub').disabled=true;
alert('You must not leave any of the fields blank!');
return false;
}
jsFiddle example
I want to know if submit gets called if my form data are not valid in html5 validation. For example I have a form id personal_info.
I use the following block to get on submit event :
$("#personal_info").submit(function(event) {
event.preventDefault();
saveData("personal_info");
});
function saveData(formName){
console.log("test");
}
Is is the default behavior that the function saveData gets called on submit because even if my form is not valid the function gets called.
How to prevent submit function from being called if my form is invalid?
The new HTML5 validation APIs will not submit an invalid form unless you use the novalidation attribute on the form. See https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Forms/Data_form_validation for more information.
It works but should on submit be called if the form is not valid.
Anytime your form #personal_info is submitted, the submit function will run.
The reason it may appear that the submit function isn't running, is because of this line
event.preventDefault();
This prevents the default action from taking place, which is submitting the form. So the form won't submit normally, thus your web page won't reload/refresh.
Calling submit even if the form is not valid, is just fine. Nothing wrong with that. The way your code is in your question, the saveData function is set to run each time, even if it's not valid. So we can change that from happening.
Like A. Wolff said in the comments, you could just wrap an if statement around your call to saveData function.
So you could have your code look something like this
$("#personal_info").submit(function(event) {
event.preventDefault();
if ($(this).valid()) { // if form is valid
saveData("personal_info"); // then do this
}
});
function saveData(formName){
console.log("test");
}
Bare bones Example:
<form id="tForm">
<input type="submit" id="tSubmit" value="Submit">
</form>
<script>
$(document).on( 'click','#tSubmit', function(e) { someFunction(<fire-and-forget-action)});
</script>
Usage scenario:
1.) User clicks form Submit button
2.) someFunction( ) is called
3.) tForm is submitted as the default behavior of the HTML input element of type=submit.
Am I guaranteed that the someFunction( ) call will happen before the submission of tForm? There has been an issue raised that the possibility exists that the someFunction( ) call would not complete before tForm is submitted and a new page is rendered.
If the function fire-and-forget-action is an asycronous request then all bets are off.
You need to prevent the form submission (return false or call preventDefault() on the event argument) and execute it once the inner function has completed. You might, for example, have to refactor the 'fire and forget action' to do this, but without a big more information about what it contains, it's hard to help further.
Note that even then you have an issue where the form can be submitted in other ways. You're shadowing the submit click action, but there are other ways to submit the form. Ideally you'd observe the form submit event instead.
Here is a slight abstract example of how you should do it:
$('#theForm').submit(function(e) {
var f = this;
setTimeout(function() {
f.submit();
}, 1000);
return false;
});
The setTimeout is basically equivalent to some asynchronous request happening outside of the original handler. The point is, the inner function knows about the original form and submits it when complete.
I am submitting a form using JQuery and an event listener bound to a div (not an input field) and I am trying to prevent multiple submits, so the customer does not get overcharged. I am trying to accomplish this by removing the submit-button class of the clicked div, so the next time the user clicks it, JQuery won't listen to the event that is associated with the submit-button preventing multiple submits.
Using the implementation below however, for some reason, does not prevent multiple submits, as intended.
HTML
<div class="submit-button button-style">Submit</div>
JQuery
$(".submit-button").click(function(){
$(this).removeClass("submit-button");
//**submit form**
});
NOTE: I must stick to a solution that uses the html above, so solutions using an input element of type submit, will not be useful.
I appreciate any suggestions on how to make this work. Many thanks in advance!
You can make use of .one() to prevent it from firing multiple times -
$(".submit-button").one('click',function(){
//**submit form**
});
http://api.jquery.com/one/
Edit :
In case of error :
function submitForm(){
//**submit form**
$.post('submit.php').error(function(){
// rebind event on error
$(".submit-button").one('click',submitForm);
});
}
$(".submit-button").one('click',submitForm);
You could use something like:
$('something').one('click', function(){
// submit code
});
Which will only fire once.
A significant portion of users don't bother clicking the submit button to submit a form - there's other more convenient ways, like hitting the enter key when the cursor focus is on a form field.
A more robust approach is to block the form via the forms submit event, and maintain a variable to keep track of the form submission state.
var submitted = false;
$("form#myForm").submit(function(evt){
if (submitted) {
evt.preventDefault();//stops form submission
return;
}
submitted = true;
});
I omitted form validation for this example.
I have a web form that uses a lot of JavaScript and ajax to determine if each field is valid. It gives warning messages on the fly to help the user know when there's a problem. I even use the "disable" feature on my submit button until everything is up to snuff. But here's the problem: All the event handling happens using the onblur feature. but when the last field is filled out, the validation doesn't happen till the user clicks away from that field. but why would they? there's nothing left to do on the page but click submit, which they can't do until they click somewhere else, anywhere else, first (to set off the validation event). I'm trying to find a way around this. There has to be a way where they don't have to make that extra click. it just doesn't seem professional. Is there a standard way around this? Can the validation event be triggered each time the user types an individual letter?
The form node has an onsubmit event that will fire when the user tries to submit the form. You can use this to validate all of the form fields and decide whether to let the user submit the form. The general implementation is this:
<form onsubmit="return validateForm()">
...
</form>
And in your JavaScript function, you have to return true if the user can continue submitting the form, or false to cancel the user's request before the form is submitted.
(In Psuedo-code):
function validateForm(){
if(formIsOkay){
return true;
}else{
return false;
}
}
You can validate each field using onkeyup, and withhold your user notification to the onblur method so it doesn't get annoying. If all fields are valid at the onkeyup, enable the submit button.
Given the limitations of {onChange, onKeyup, blur, etc} when it comes to handling copy/pasted or other edge cases I would probably add a timer to poll every 500ms or so and enable/disable the submit button:
window.setInterval(checkEnableSubmit, 500);
function checkEnableSubmit(){
if(validateForm()){
// enable submit button
}
}
function validateForm(){
if(formIsOkay){
return true;
}
return false;
}
I'd still call validateForm() on the button click to avoid users invalidating data and submitting before the timer is called. Server side validation is a given but I'd like to avoid the bad submit if possible.