I've looked around for a solution and found the spam module. However, I'm looking for something that will prevent it from the start.

The problem:
I can go into the comment section of an article, write a comment, and click the "Submit Comment" button 20 times and it'll post 20 times.

Is there a way to disable the submit button after the first click? or nullify the submission if it were clicked more than once? I'm thinking there should be an easy solution to this since no one else seems to have this problem.

Any help would be appreciated.

Comments

bacon333’s picture

Let's see...

on this comment, i clicked the submit button 20 times but only one post came up. how was this done?

amnon’s picture

FWIW,

In the past, when I worked with HTML directly, I used to attach to my submit buttons 'onclick' events which disabled them.

Somthing like this:

<input type="submit" ... onclick="this.disable = true" />

Now, let's think. Perhas you can also do:

<input type="submit" ... onclick="this.value='Wait...'; this.disable = true" />
bacon333’s picture

thanks for your reply.

I've seen fixes like that, along with some cgi ones but that would involve me editing the module.

If you try to post a comment on this page, after you preview, and keep clicking the "submit comment" button, it only posts once without having to disable the button. I want to know how to do that =) It's gotta be right under my nose...

dman’s picture

A quick peek shows me something I expected:

<input type="hidden" name="edit[form_token]" id="edit-form_token" value="c16338a617a8ae7b33354832f6733ca7"  />

I don't know where it does it or exactly how, but I can make a damn good guess at what that's doing.

I don't recall seeing it on my site code however, maybe it's from a contrib.

.dan.

http://www.coders.co.nz/

bacon333’s picture

Hm. Interesting...anyone know more about this?

amnon’s picture

No, It's part of core. This long hex number is the session ID, and it's used to make sure no one it trying to hack the website.

amnon’s picture

I was just trying to verify that this claim is correct, that you can't hit the send button here on drupal.org twenty times.

Well, it isn't true ;-)

Sorry...

I hope the moderators won't revoke my membership...

amnon’s picture

No, It's part of core. This long hex number is the session ID, and it's used to make sure no one it trying to hack the website.

Heine’s picture

That's enough for illustration purposes, me thinks :D
--
The Manual | Troubleshooting FAQ | Tips for posting | Make Backups! | Consider creating a Test site.

amnon’s picture

In the past, when I worked with HTML directly, I used to attach to my submit buttons 'onclick' events which disabled them.

Here's a tiny module I wrote to do exactly that. It disables the submit button after you click it. I wrote it just for fun. It isn't very sexy.

Installation

  1. Save this code in a file named 'submit_once.module'
  2. Copy it to your modules folder
  3. Enable it (administer » modules)

define('DEFAULT_WAIT_MSG', ' (Wait...)');

function submit_once_help($section = '')
{
  switch ($section) {
    case 'admin/modules#description':
      return t('Disable submit buttons after one click.');
  }
}

function submit_once_form_alter($form_id, &$form)
{
  foreach (element_children($form) as $name) {
    if ($form[$name]['#type'] == 'submit') {
      if (!isset($form[$name]['#attributes']))
        $form[$name]['#attributes'] = array();
      $form[$name]['#attributes']['onclick'] =
        "this_btn=this;this.value+='".DEFAULT_WAIT_MSG."';setTimeout('this_btn.disabled=true',0)";
    }
  }
}

amnon’s picture

Arghhh... bad news: this javascript trick doesn't work in Mozilla. So this module is useless, as-is. But I know how to fix it: instead of disabling the button, the Javascript code should use a flag variable. If anyone is intereseted in a fix, let me know.

bacon333’s picture

I am VERY interested in a fix =P.

wow you were able to get more than one post in, i tried a few times and couldn't do it.

amnon’s picture

Here's the fixed module.


function submit_once_help($section = '')
{
  switch ($section) {
    case 'admin/modules#description':
      return t('Disable submit buttons after one click.');
  }
}

function submit_once_form_alter($form_id, &$form)
{
    _submit_once_alter_submit_buttons($form);
}

function _submit_once_alter_submit_buttons(&$form)
{
  static $counter = 1;
  $disabling_method = variable_get('submit_once_disabling_method', 'flag_variable');
 
  foreach (element_children($form) as $name) {
    if ($form[$name]['#type'] == 'submit')
    {
      if (!isset($form[$name]['#attributes']))
        $form[$name]['#attributes'] = array();
      if (!isset($form[$name]['#prefix']))
        $form[$name]['#prefix'] = '';

      switch ($disabling_method) {
        case 'none':
          break;
        case 'disabled_attr':
          $form[$name]['#attributes']['onclick'] .=
            ";this_btn=this; setTimeout('this_btn.disabled=true',0); return true";
          break;
        case 'flag_variable':
          $form[$name]['#prefix'] .= "<script type='text/javascript'>btn_{$counter}_clicked=0;</script>";
          $form[$name]['#attributes']['onclick'] .=
            ";if (btn_{$counter}_clicked) return false; btn_{$counter}_clicked=1; return true";
          break;
      }
      $counter++;
    }
  }
}

function submit_once_settings()
{
  $form['submit_once_disabling_method'] = array(
    '#type' => 'radios',
    '#title' => t('Disabling method'),
    '#description' => t('The JavaScript method used to disable the submit buttons'),
    '#default_value' => variable_get('submit_once_disabling_method', 'flag_variable'),
    '#options' => array(
        'disabled_attr' => t('Use the HTML "disabled" attribute (the buttons\' text will dim; DOESNT WORK IN MICROSOFT INTERNET EXPLORER)'),
        'flag_variable' => t('Use a variable to flag whether the button was pressed (the buttons won\'t change appearance)'),
    ),
  );
  return $form;
}

The settings page allows one to choose between two "disabling methods".

The default method, "Use a flag variable...", works in all browsers.

The other method, using HTML's "disabled" attribute, for some mysterious reason don't work in my Internet Explorer. I can't debug it, because I'm running IE under Wine (I'm using Linux) and it's cumbersome, so just don't choose this disabling method. I leave it there for some developer who runs Windows and wants to fix it.

kpatrickdj’s picture

Submit_once is a useful piece of code. However, gives an issue when used in a form with autocomplete field. To elaborate, when a form has an autocomplete field and the user selects an item from the autocomplete match list and hits enter key, submit_once java script also executes (may be because Drupal makes Submit button as default action). This sets btn_clicked variable and hence clicking Submit button does not submit the form!

robdinardo’s picture

I know editing modules is a no no, but this is what you could do to add this functionality to an existing form in a module:

Add this line:

'#attributes' => array("onclick" => "javascript: this.value='Please Wait...'; this.disabled = true;"),

to this array

$form['submitbutton'] = array(
          '#type' => 'submit',
          '#value' => t('Submit'),
          '#weight' => 1000,
          	'#attributes' => array("onclick" => "javascript: this.value='Please Wait...'; this.disabled = true;"),
        );

That should change the text in the submit button and render it disabled - when clicked.

tloudon’s picture

just a thought, updating the value of the button could impact things downstream in the form submit function...i can't remember if it's just d5, but forms with multiple submit buttons differentiate between them based on the value...ie the text on the button.

totally random and 2 years later i know, but may save some folks a few hours of trouble--it took me a little while to figure out what was going on with one of my forms :)

cheers

alpapan’s picture

On D6, in a multi-button form this will not work (but will work fine in a single button one where the name is not used to determine which operation to perform).
Funny enough, it does not work even if the javascript only sets the disabled and not touch the value argument. By looking at the source HTML before and after, nothing obvious seems to be affected that would cause the operation to fail:
<input name="op" id="edit-union" value="ANY selected annotation" title="Get features which match any one of the above selected terms." onclick="javascript: this.disabled = true;" class="form-submit" type="submit">
Becomes (and does not work...)
<input disabled="disabled" name="op" id="edit-union" value="ANY selected annotation" title="Get features which match any one of the above selected terms." onclick="javascript: this.disabled = true;" class="form-submit" type="submit">

hmm...

Also a small problem: (in single-button forms where it works): if someone clicked their browser's back button (even though it's not a good idea generally) it would still be disabled...

Uersu’s picture

I have just experienced the hard way from a user that this script breaks the form on the safari browser. The form never gets submitted at all and only the button is disabled, showing the changed text.

The form still works ok for IE and Firefox

Urs

tomarnold2’s picture

Still searching for a solution. Adding to your code you can see it's till active after submission:
'#attributes' => array(
'onclick' => "javascript: this.value=this.value+'...please wait...'; this.disable = true;",

If you click multiple times it keeps adding "...please wait..." to the button's caption again and again.

malc0mn’s picture

Wasted nearly a day for a specific D6 site where I wanted to use jQuery to disable the submit button by adding a click handler. Done that before on Drupal6 sites but on this site it just wouldn't work they way I wanted it to.

I was adding a click handler on the submit (not preview) button of the drupal 6 core comment_form. When clicking the submit button, the comment was not saved! DPM-ing around in the comment module, I noticed that the form did not pass validation. It did not throw an error either!

I ended up in concluding that the Drupal 6 core 'form tampering protection' kicked in for a still unknown reason. Usually you would get the obscure 'Illegal choice detected ...' error in such a case, but nothing... Vaildation simply fails. The solution I ended up in using was this:

(function($) {

  Drupal.behaviors.disableReviewButton = function() {
    $('#comment-form #edit-submit').click(function(e){
      $('#comment-form #edit-submit').hide();
      $('#edit-submit-wrapper').append(
        $('<input />').attr('type', 'button').attr('disabled', true).addClass('form-submit').val(Drupal.t('Processing...'))
      );
    });
  }

})(jQuery);

Note that I replaced the input button with another button to avoid restyling!

Helped me, might save someone a day of pulling hair :-p

Jax’s picture

I made a little module that uses the jQuery blockUI plugin to achieve this. Every time a submit button is clicked it blocks the whole UI and displays "Please wait" (which is the plugin default).
Download it: http://jax.be/blockui-1.0.tgz
BlockUI page: http://malsup.com/jquery/block/

robserious’s picture

Hi Guys,

I have noticed this problem before, in other places too. For example when you are creating terms in a category. If you bash enter a few times it will create as many as you like.

I suggest adding these js files across the board, ie for all forms on the site.

I have tried this out on a site thats in development now and it is working. Can you think of any reason not to do this?

function _blockui_js() {
	$path =  drupal_get_path('module', 'blockui');
	drupal_add_js("{$path}/jquery.blockUI.js");
	drupal_add_js("{$path}/blockui.js");	
}


/*function blockui_nodeapi(&$node, $op, $a3 = null, $a4 = null) {
	if($op == 'prepare') {
		_blockui_js();
	}
}

function blockui_comment(&$a1, $op) {
	if($op != 'form') {
		_blockui_js();
	}
}*/

function blockui_menu() {
	_blockui_js();
}

Cheers

Rob

kzuser’s picture

Hi, can you update it to drupal 6 compatible module. blockui

fall_0ut’s picture

It's good idea!

Jax’s picture

And here a version that should work with drupal 6 for those that are interested:
http://jax.be/blockui-6.x-1.0.tgz

v8powerage’s picture

gratissim’s picture

I have the same problem. thank you for the advice.