/hide_submit define('HIDE_SUBMIT_DEFAULT_IMAGE_BASENAME', 'loader.gif'); define('HIDE_SUBMIT_EXCLUDE_CLASS', 'hide-submit-exclude'); define('HIDE_SUBMIT_EXCLUDE_LISTED_FORMS', 0); define('HIDE_SUBMIT_EXCLUDE_UNLISTED_FORMS', 1); /** * Implementation of hook_help(). */ function hide_submit_help($section) { $output = ''; switch ($section) { case 'admin/help#hide_submit': case 'admin/settings/hide-submit': $output = '

'. t('The hide_submit module provides a way to hide the submit button in a form after it has been clicked. This will indicate to the user that his or her request is being processed and helps to prevent duplicate postings from impatient "double clickers".') .'

' .'

'. t('For more information please visit the !project page or the !documentation page', array('!documentation' => l('documentation', 'http://drupal.org/node/338935'), '!project' => l('hide submit project', 'http://drupal.org/project/hide_submit') ) ) .'

'; if ( module_exists('advanced_help') ) { $output .= '

'. theme('advanced_help_topic', 'hide_submit', 'using-hide-submit') .' ' . t('Click the icon to read the extended help.'); } break; } return $output; } /** * Implementation of hook_menu */ function hide_submit_menu($may_cache) { $items = array(); if ($may_cache) { $items[] = array( 'path' => 'admin/settings/hide-submit', 'title' => 'Hide Submit', 'description' => 'Configure hide submit', 'callback' => 'drupal_get_form', 'callback arguments' => array('hide_submit_admin_settings'), 'access' => user_access('administer site configuration'), 'file' => 'hide_submit_admin.inc', ); $items[] = array( 'path' => 'admin/settings/hide-submit/settings', 'title' => 'Hide Submit', 'file' => 'hide_submit_admin.inc', 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => 10, ); } else { $delete_path = 'admin/settings/hide-submit/delete'; $path_action = substr($_GET['q'],0,strlen($delete_path)); if ($path_action === $delete_path) { $items[] = array( 'path' => 'admin/settings/hide-submit/delete/'.arg(4), 'title' => 'Confirm delete', 'description' => 'Delete an image file', 'callback' => 'drupal_get_form', 'callback arguments' => array('hide_submit_admin_delete_image',arg(4)), 'access' => user_access('administer site configuration'), 'type' => MENU_CALLBACK, ); } } return $items; } /** * Implementation of hook_form_alter * * Used to add "hide-submit-exclude" class to some forms * Avoid conflicts and refine hiding */ function hide_submit_form_alter($form_id, &$form) { $exclude_forms = explode("\r\n", variable_get('hide_submit_form_exclusion', 'shoutbox_add_form')); $found = FALSE; $mode = variable_get('hide_submit_form_exclusion_mode', HIDE_SUBMIT_EXCLUDE_LISTED_FORMS); foreach ($exclude_forms as $exclude_form_id) { if ($form_id == $exclude_form_id) { $found = TRUE; if ($mode == HIDE_SUBMIT_EXCLUDE_LISTED_FORMS) { _hide_submit_add_exclude_class($form); if (_hide_submit_debug_on()) { drupal_set_message("hide_submit: Excluding form ". $exclude_form_id); } } } } if (!$found && $mode == HIDE_SUBMIT_EXCLUDE_UNLISTED_FORMS) { _hide_submit_add_exclude_class($form); if (_hide_submit_debug_on()) { drupal_set_message("hide_submit: Excluding form ". $form_id); } } _hide_submit_inject(); } //------------------------------------------------------------------------ // Private functions //------------------------------------------------------------------------ /** * Insert JS into page. */ function _hide_submit_inject() { static $hide_submit_js_loaded = FALSE; if (!$hide_submit_js_loaded && _hide_submit_load_js_check_condition()) { $js = _hide_submit_get_javascript(); drupal_add_js($js, 'inline', 'footer'); $hide_submit_js_loaded = TRUE; } } /** * A recursive function to add class to all excluded submit buttons */ function _hide_submit_add_exclude_class(&$elements) { // Recurse through all children. foreach (element_children($elements) as $key) { if (isset($elements[$key]) && $elements[$key]) { _hide_submit_add_exclude_class($elements[$key]); } } // Add class to submit buttons if (isset($elements['#type']) && $elements['#type'] == 'submit') { $elements['#attributes']['class'] = empty($elements['#attributes']['class']) ? HIDE_SUBMIT_EXCLUDE_CLASS : $elements['#attributes']['class'] .' '. HIDE_SUBMIT_EXCLUDE_CLASS; } } /** * Check if JS should be loaded for current page */ function _hide_submit_load_js_check_condition() { $js_load_option = variable_get('hide_submit_js_load_option', HIDE_SUBMIT_DEFAULT_JS_LOAD); switch ($js_load_option) { case HIDE_SUBMIT_IN_ALL_PAGES: return TRUE; case HIDE_SUBMIT_IN_LISTED_PAGES: case HIDE_SUBMIT_EXCLUDE_LISTED_PAGES: $pages = variable_get('hide_submit_js_load_pages', ''); break; case HIDE_SUBMIT_IN_CONTENT_ADD_EDIT: default: $pages = "node/add/*\r\nnode/*/edit"; break; } if ($js_load_option != HIDE_SUBMIT_EXCLUDE_LISTED_PAGES) { $pages .= "\r\nadmin/settings/hide-submit"; } $path = drupal_get_path_alias($_GET['q']); $regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\($|\|)/'), array('|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'), '/') .'\2'), preg_quote($pages, '/')) .')$/'; // Compare with the internal and path alias (if any). $page_match = preg_match($regexp, $path); if ($path != $_GET['q']) { $page_match = $page_match || preg_match($regexp, $_GET['q']); } // Do we have a match on our page list? if ($js_load_option == HIDE_SUBMIT_EXCLUDE_LISTED_PAGES) { return !($page_match == 1); } return ($page_match == 1); } /** * scrub the format strings for things that make bad javascript. * * @param $format_string * @return * cleaned $format_string */ function _hide_submit_clean_for_javascript($format_string='') { $patterns = array('/\n/', '/\r/', '/\'/'); $replacements = array('
', '', '`' ); return preg_replace($patterns, $replacements, $format_string); } /** * get the image according to user selection, default, random etc... */ function _hide_submit_get_image() { // Use static to assure the same image is returned for the current page static $image = FALSE; if ($image !== FALSE) return $image; $image = variable_get('hide_submit_image', HIDE_SUBMIT_DEFAULT_IMAGE); if (is_array($image)) { list($usec, $sec) = explode(' ', microtime()); srand((float) $sec + ((float) $usec * 100000)); $image = $image[rand()%count($image)]; } return $image; } /** * Get javascript code for injection */ function _hide_submit_get_message( ) { global $language; $message = variable_get('hide_submit_message_'. $language->language, "" ); if ( $message == "" ) { $message = variable_get('hide_submit_message', t("Please wait...")); } $image = _hide_submit_get_image( ); if ($image != "") { $image = theme('image', $image, $alt = '', $title = '', $attributes = NULL, $getsize = FALSE) .' '; } return '

'. $image .' '. $message .'

'; } /** * Get javascript code for injection */ function _hide_submit_get_javascript() { $message = filter_xss_admin( _hide_submit_clean_for_javascript( _hide_submit_get_message() ) ); // Set base path for local image, none for external $image = _hide_submit_get_image(); $image = (url($image) == $image) ? $image : (base_path() . $image); $image = check_url($image); // Assemble jQuery selector $selector = 'input:submit:not(.'. HIDE_SUBMIT_EXCLUDE_CLASS .')'; $selector .= implode("",explode("\r\n",filter_xss_admin(variable_get('hide_submit_attribute_filter', '')))); // For debugging, this addtion to the script will paint included and excluded buttons $debug_code = _hide_submit_debug_on() ? "$('input:submit').css({border:'6px red solid'}); $('$selector').css({border:'6px green solid'});" : ""; //background:'yellow', // Operation, hide or disable $operation = (variable_get('hide_submit_script_mode', HIDE_SUBMIT_MODE_HIDE) == HIDE_SUBMIT_MODE_HIDE) ? "$(this).siblings('input:submit').hide(); $(this).hide(); $('$message').insertAfter(this); " : "$(this).siblings('input:submit').attr('disabled', true); $(this).attr('disabled', true);"; $javascript = <<").attr("src",'$image'); $(document).ready(function() { $debug_code $('$selector').click(function() { $operation }) }) JAVASCRIPT_CODE; return $javascript; } /** * Debug mode check */ function _hide_submit_debug_on() { return variable_get('hide_submit_debug', FALSE) && user_access('administer site configuration'); }