How can I disable a Drupal form submit button when it is clicked to prevent double submission?
Asked Answered
G

4

6

Sounds like a simple question. I've added a bit of jQuery magic:

$("#edit-save").click(function(event) {
  $(this).attr("disabled", "true");
});

However, once this is in place, my form submit handler doesn't get called.

This is a custom form on my own path defined in hook_menu:

$items['my_form'] = array(
  'title' => 'My form',
  'page callback' => 'drupal_get_form',
  'page arguments' => array('mymod_myform'),
  'type' => MENU_CALLBACK,
);

In the form, I have a submit button and a cancel button:

$form['cancel'] = array(
  '#type' => 'submit',
  '#value' => t('Cancel'),
);

$form['save'] = array(
  '#type' => 'submit',
  '#value' => t('Save'),
);

and I define my own submit handler:

$form['#submit'][] = 'mymod_myform_submit';

I've put a bit of tracing code in the drupal_get_form() function to sniff the $_POST variable when the form is submitted. When the jQuery magic is disabled, the $_POST variable includes an "op" parameter:

Array
  (
    [op] = Save
    [form_build_id] => form-6e74c87390e3fc48d0bebd2f5193315b
    [form_token] => 33db6e34c0350e33c48861a63a38d45f
    [form_id] => dh_seo_workload_item_form
  )

but if I enable the jQuery magic to disable the submit button after it's been clicked, the "op" parameter is no longer included in the $_POST array, and so Drupal thinks the form has not been submitted.

I've seen the question at Prevent double submission of forms in jQuery, but am concerned that this seems like a really hacky fix, and there should be a better way.

Gorgon answered 17/12, 2010 at 17:29 Comment(2)
I also added an answer to the question you linked with (I think) a less hacky solution.Cleodal
Is possibly doesn't get called due to the button being disabled on click. My solution below uses setTimeout at 1ms to get around this.Auxochrome
A
5

Or you can do this, as a one-liner addition at the PHP form array level...

$form['submit'] = array(
  '#type' => 'submit',
  '#value' => t('Save'),
  '#attributes' => array(
    'onclick' => 'javascript:var s=this;setTimeout(function(){s.value="Saving...";s.disabled=true;},1);',
  ),
);
Auxochrome answered 22/4, 2013 at 10:52 Comment(0)
D
2

I fixed it this afternoon this way and was able to get the form information submitted with out issue:

$("#id_of_button").click(function() {
  var submit = $(this);
  setTimeout(function(){
    submit.attr('disabled','disabled')
  },1);
});
Dollhouse answered 17/12, 2010 at 21:47 Comment(0)
C
1

I think the fact that you're binding to the click event of the button means that the button gets disabled before the click event can bubble up to the form and cause a submit.

Our team found that disabling the submit button almost always creates problems for Internet Explorer. We made a tiny plugin to solve the issue; see code here: https://mcmap.net/q/135339/-prevent-double-submission-of-forms-in-jquery

Cleodal answered 17/12, 2010 at 18:41 Comment(2)
Thanks for your solution. I recommend using bind instead of live because live has been deprecated.Thrave
@Thrave - actually on() is the updated version. bind is also deprecated and, unlike live or on, worked only for elements on the page at the time of invocation. Corrected accordingly.Cleodal
H
0

Just hide your submit button(display:none), and show another button already disabled instead. I think its less hacky than the rest of solutions for this problem. I usually just have 2 buttons on my page, one visible and the other one not, and onClick, just switch them up.

The problem is caused because disabled buttons don't trigger postbacks.

Hylo answered 9/10, 2013 at 16:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.