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.
Related
I know a way to stop a form from submitting, but i have a on click event to the submit button and its firing even though the form doesnt pass the HTML validation.
<form id="signupform" class="signupform" onsubmit="(e)=>{e.preventDefault()};return false">
</form>
My goal is to stop the page refresh either way (if it validates or not) but still allow the built in validation to run first.
Any suggestions?
A submit button's job is to trigger the submit event of a form. Therefore, with form elements, you don't set up click events on the submit button, you set up submit event handlers on the form.
Then, to introduce validation into the mix, you can stop the native submit to take place in the handler, only if validation fails. This is done by accessing the event argument that is automatically sent to every DOM event handler* (see next paragraph for caveat). You can use the event.preventDefault() method to stop the native event from taking place.
*One final note, the use of inline HTML event handling attributes such as onsubmit and onclick is to be avoided. This is a 25+ year old technique that we used before we had standards and unfortunately, because they seem easy to use, they get copied by new developers who don't know any better. There are real reasons not to use them and you've stumbled into one. Your e argument to your event handling function is not being populated with a reference to the event like you think it is. That only happens when you use the modern standard way of setting up event callbacks, which is .addEventListener().
// Set up a submit event handler for the form
// not a click event handler for the button because
// clicking a submit button triggers the form's submit event
document.querySelector("form").addEventListener("submit", function(event){
if(document.querySelector("input").value === ""){
// Invalid data! Stop the submit!
event.preventDefault();
alert("Please fill in all fields!");
return;
}
// If the code reaches this point, validation succeeded
console.log("Form submitted");
});
<form action="https://example.com" method="post">
<input>
<button>Submit</button>
</form>
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?
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.
I have a form which uses GET as the method. I want to do some js validation on the form. I bind the event using
document.forms[0].onsubmit = function(){return myObj.myFrm.isFormValid();}.
In Firefox it works the first time I click on submit but after a while if I click it again the form submits even though I've not changed and data.
Any ideas?
Simply adding an event handler doesn't stop it from submitting.
You need to add in preventDefault();
(Documentation)
I've got a page with a normal form with a submit button and some jQuery which binds to the form submit event and overrides it with e.preventDefault() and runs an AJAX command. This works fine when the submit button is clicked but when a link with onclick='document.formName.submit();' is clicked, the event is not caught by the AJAX form submit event handler. Any ideas why not or how to get this working without binding to all the a elements?
A couple of suggestions:
Overwrite the submit function to do your evil bidding
var oldSubmit = form.submit;
form.submit = function() {
$(form).trigger("submit");
oldSubmit.call(form, arguments);
}
Why not bind to all the <a> tags? Then you don't have to do any monkey patching, and it could be as simple as (assuming all the links are inside the form tag):
$("form a").click(function() {
$(this).parents().filter("form").trigger("submit");
});
If you are using jQuery, you should be attaching events via it's own event mechanism and not by using "on" properties (onclick etc.). It also has its own event triggering method, aptly named 'trigger', which you should use to activate the form submission event.
Thanks Eran
I am using this event binding code
this._form.bind('submit', Delegate.create(this, function(e) {
e.preventDefault();
this._searchFadeOut();
this.__onFormSubmit.invoke(this, new ZD.Core.GenericEventArgs(this._dateField.attr('value')));
});
but there is legacy onclick code on the HTML and I would prefer not to change it as there are just so many links.
This worked for me:
Make a dummy button, hide the real submit with the name submit,
and then:
$("#mySubmit").click(function(){
$("#submit").trigger("click"); });
set an event handler on your dummy to trigger click on the form submit button. let the browser figure out how to submit the form... This way you don't need to preventDefault on the form submit which is where the trouble starts.
This seemed to work around the problem.