Preventing form from submitting multiple times
From the comments, it sounds like you're making an asynchronous request (in axios.post()
) and immediately setting this.submitting
and this.value
without awaiting the result of the network request, similar to this example:
checkForm( e ) {
this.submitting = true;
this.value = 'Submitting';
axios.post('https://foo');
this.submitting = false;
this.value = 'Submit';
}
Since axios.post()
is asynchronous (i.e., returns a Promise
), the lines that follow are executed before the POST
request even occurs. You can either move those settings into the then
callback of axios.post()
:
checkForm( e ) {
this.submitting = true;
this.value = 'Submitting';
axios.post('https://foo').then(() => {
this.submitting = false;
this.value = 'Submit';
});
}
Or you can use async
/await
like this:
async checkForm( e ) {
this.submitting = true;
this.value = 'Submitting';
await axios.post('https://foo');
this.submitting = false;
this.value = 'Submit';
}
demo
Block multiple form submissions/ debounce a fetch request on form submit in Next.js app
A very simple and generally used method is to make the submit button be disabled until you get a response back from your API. So, for example:
Create a state:
const [isSubmitting, setIsSubmitting] = useState(false);
Use that state to set your submit button's disabled
attribute:
<button type="submit" disabled={isSubmitting}>Save</button>
Call setIsSubmitting
from your event handler:
const onSubmit = async (data) => {
setIsSubmitting(true);
const { email, password1, password2, first_name, last_name } = data;
const response = await postSignUp( email, password1, password2, first_name, last_name );
// error handling code
toast.success('You have successfully registered!', { autoClose: 2500 })
setTimeout( () => {
router.push({ pathname: '/auth/verify-email', query: { email: email } });
}, 2500 )
setIsSubmitting(false);
}
How to Prevent Users from Submitting a Form Twice
try out this code..
<input type="submit" name="btnADD" id="btnADD" value="ADD" onclick="this.disabled=true;this.value='Sending, please wait...';this.form.submit();" />
How to prevent submitting a form accidentally multiple times - on the client side without JS?
Not possible. You must use js to disable the button (or otherwise prevent submission) after submission.
Remember also: No matter what you modify with js, the client can undo it with devtools. So sanitize everything server side.
prevent multiple submissions when user clicks submit button multiple times before loading to the new page
If this is the buttton:
<input type="submit" name="submit" value="submit" id="preventDouble">
With jQuery:
$("#preventDouble").on("submit",function(){
$(this).unbind("submit");
$(this).on("submit",function(){return false;});
};
After the first submit, jQuery will attach an event that will cancel further submits.
Note that this event does not check if the form was actually successfully submited to the server.
This may answer your question, but it's a safer and better approach to track multiple submits on the server, e.g. adding a "last_submitted" attribute to the session, and prevent further submits if datetime.datetime.now is less than 1 minute from session.last_submitted:
import datetime
import pickle
def form_valid(self,form):
if not hasattr(self.request.session['last_submitted']):
last_submitted = pickle.dumps(datetime.datetime.now())
self.request.session['last_submitted'] = last_submitted
save_it = True
else:
last_submitted = pickle.loads(self.request.session['last_submitted'])
delta = datetime.datetime.now() - last_submitted
save_it = (delta.seconds > 60): # assume allow re-submit after 60 seconds
if save_it:
self.object = form.save(commit=False)
# any manual settings go here
#self.object.category = Category.objects.filter(category__in=categories).all()
self.object.moderator = self.request.user
self.object.image = extract(self.object.url)
self.object.thumbnail = extractt(self.object.content)
self.object.save()
return HttpResponseRedirect(reverse('post', args=[self.object.slug]))
else:
# consider redirect as usual, if the user just clicked twice by mistake
return self.form_invalid(form) # or Http error code
Edit
import datetime
import pickle
class PostCreateView(CreateView):
model = Post
form_class = PostForm
template_name = 'main/add_post.html'
def form_valid(self,form):
if not hasattr(self.request.session['last_submitted']):
last_submitted = pickle.dumps(datetime.datetime.now())
self.request.session['last_submitted'] = last_submitted
save_it = True
else:
last_submitted = pickle.loads(self.request.session['last_submitted'])
delta = datetime.datetime.now() - last_submitted
save_it = (delta.seconds > 60) # assume allow re-submit after 60 seconds
if save_it:
self.object = form.save(commit=False)
# any manual settings go here
#self.object.category = Category.objects.filter(category__in=categories).all()
self.object.moderator = self.request.user
self.object.image = extract(self.object.url)
self.object.thumbnail = extractt(self.object.content)
self.object.save()
return HttpResponseRedirect(reverse('post', args=[self.object.slug]))
else:
# consider redirect as usual, if the user just clicked twice by mistake
return self.form_invalid(form) # or Http error code
Prevent double submission of forms in jQuery
Update in 2018: I just got some points for this old answer, and just wanted to add that the best solution would be to make the operation idempotent so that duplicate submissions are harmless.
Eg, if the form creates an order, put a unique ID in the form. The first time the server sees an order creation request with that id, it should create it and respond "success". Subsequent submissions should also respond "success" (in case the client didn't get the first response) but shouldn't change anything.
Duplicates should be detected via a uniqueness check in the database to prevent race conditions.
I think that your problem is this line:
$('input').attr('disabled','disabled');
You're disabling ALL the inputs, including, I'd guess, the ones whose data the form is supposed to submit.
To disable just the submit button(s), you could do this:
$('button[type=submit], input[type=submit]').prop('disabled',true);
However, I don't think IE will submit the form if even those buttons are disabled. I'd suggest a different approach.
A jQuery plugin to solve it
We just solved this problem with the following code. The trick here is using jQuery's data()
to mark the form as already submitted or not. That way, we don't have to mess with the submit buttons, which freaks IE out.
// jQuery plugin to prevent double submission of forms
jQuery.fn.preventDoubleSubmission = function() {
$(this).on('submit',function(e){
var $form = $(this);
if ($form.data('submitted') === true) {
// Previously submitted - don't submit again
e.preventDefault();
} else {
// Mark it so that the next submit can be ignored
$form.data('submitted', true);
}
});
// Keep chainability
return this;
};
Use it like this:
$('form').preventDoubleSubmission();
If there are AJAX forms that should be allowed to submit multiple times per page load, you can give them a class indicating that, then exclude them from your selector like this:
$('form:not(.js-allow-double-submission)').preventDoubleSubmission();
Related Topics
Canvas.Todataurl() Securityerror
Format Date to Mm/Dd/Yyyy in JavaScript
Remove Items from Array with Splice in for Loop
Convert String in Dot Notation to Get the Object Reference
Using Http Rest APIs with Angular 2
When Does Js Interpret {} as an Empty Block Instead of an Empty Object
How to Map More Than One Property from an Array of Objects
Is the Promise Constructor Callback Executed Asynchronously
How to Guarantee That My Enums Definition Doesn't Change in JavaScript
What Is "Export Default" in JavaScript
Jquery Checkbox Checked State Changed Event
Jquery to Loop Through Elements with the Same Class
How to Copy Static Files to Build Directory with Webpack