0

I need to prevent accidental clicks in the Save button when a node is being saved.

I found this module which does exactly this. But the problem is that it uses javascript (jquery). Then if the user disable javascript this module is useless.

My problem is that in my website the user get points when creating nodes, so I have to prevent this in a more secure way.

How can I do this?

What do you think of these ideas?:

1) Maybe I would forbid the node being saved more than one time programmatically instead of disabling the Save button.

2) Or better: I would allow the user to just save a new node every 5 minutes.

3
  • 1
    Yes, I'd go for your option 2, either by using the Rules module or writing a custom validation handler which performs the appropriate checks. I suggest you carry out some experiments to determine the best logic so if someone accidentally presses save twice they don't see a worrying error message. – Alfred Armstrong Apr 3 '13 at 9:48
  • I also thought of rule being fired just before saving the node. – chefnelone Apr 3 '13 at 10:03
  • There is an autosave module, although my experience with it is mixed. However, there is a form_id generated with every form load. This should be used to prevent duplicates. – Interlated Apr 3 '13 at 11:39
1

Finaly I got this using these 2 modules:

http://drupal.org/project/hide_submit (to prevent clicking the bottom using jquery)

and

http://drupal.org/project/node_limit (just for browsers with javascript disabled) This allowed me to set a time interval limit to post new nodes.

0

You can use confirm_form() to confirm the users submit instead of hiding save button so that user will get chance to think whether he really wants to submit and not accidental click on save button. You need to alter the form on which you need to confirm.

0

Use the 'form_build_id' to prevent duplicate submissions. This is located at

$form_state['input']['form_build_id'] 

(drupal-7) and is generated with each form load.

See created module: http://drupal.org/sandbox/interlated/1963144.

A database table or widget field would be required to store it with each submission. Ideally the table holding the field would be locked. In a validation callback or node_save hook. A specific field per content type to prevent too much locking. The validation messages drupal_set_message() saying that multiple submissions were detected would still display. In practice the locking may become too cumbersome, so a cron job is required to clean it up.

There is a fair bit of code required. Create a module, then register field, widget, formatter. Create a widget form with a validator, write the validator. Finally write a cron job to delete duplicate nodes, or at least delete duplicate tallied points. Add the created field to your node.

Firstly, set up a constant.

ognotify.info

files[] = includes/OgNotifyManage.inc

In the declared file:

class OgNotifyManage {
  const field_id = 'duplicate_token';
}

In the .module file:

/**
 * Define the field definition for the node editing form.
 */
function ognotify_field_info() {
  return array(
    OgNotifyManage::field_id => array(
      'label' => t('Token'),
      'description' => t('Record tokens to reduce duplicates.'),
      'default_widget' => OgNotifyManage::field_id,
      'default_formatter' => OgNotifyManage::field_id,
    ),
  );
}

/**
 * Define the field for sending invitations.
 */
function ognotify_field_widget_info() {
  return array(
    OgNotifyManage::field_id => array(
      'label' => t('Detect Duplicates'),
      'field types' => array(OgNotifyManage::field_id),
    ),
  );
}

/**
 * Implements hook_field_formatter_info().
 */
function ognotify_field_formatter_info() {
  return array(
    OgNotifyManage::field_id => array(
      'label' => t('Default'),
      'field types' => array('duplicate_token'),
    ),
  );
}

/**
 * Define whether the field is empty. This is required by field API and 
 * determines whether the field is to be saved.
 */
function ognotify_field_is_empty($item, $field) {
   // items. No applicable concept of empty.
   if (empty($item[OgNotifyManage::field_id])) {
      return TRUE;
   }
  return FALSE;
}

function ognotify_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {

  $element[OgNotifyManage::field_id] = array(
    '#tree' => TRUE,
    '#type' => 'fieldset',
    '#theme' => 'ognotify_form',
    '#weight' => 10,
    '#element_validate' => array('ognotify_duplicates_validate'),
  );

  return $element;
}

function ognotify_duplicates_validate($element, &$form_state) {
  // Finally do some entity queries for our form token
  // We can do a rough first check for duplicates here, but cannot guarantee 
  // that another node has been saved while we are checking without locking the 
  // field table.


  // Save the form token in the form.
  form_set_value($element, $form_state['input']['form_token'] , $form_state);
}

function ognotify_cron() {
  // Do queries for nodes with duplicate form tokens.
}

It looks like a standard module. Let me know if you agree and I could help create it.

I was surprised that drupal doesn't just do this. The token answer is a good one.

4
  • Seems a good option. I'll try it as soon as I can. – chefnelone Apr 3 '13 at 13:39
  • I guess you meant: class OgNotifyManage { const field_id = 'duplicate_token'; } instead of class OgNotifyManage { const field_name = 'duplicate_token'; } – chefnelone Apr 3 '13 at 13:56
  • I´m afraid I do not have the knowledge to get this... – chefnelone Apr 4 '13 at 8:52
  • I created a module drupal.org/sandbox/interlated/1963144. Doesn't check post-install yet but the validate hook works in my testing – Interlated Apr 6 '13 at 13:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.