From 423616fa1bc75a6da428499e1680cfb8ec7c1c32 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Thu, 13 Jun 2019 16:26:02 -0400 Subject: [PATCH] Rewrite submitOnce function, deprecate old one New function works on a per-form basis, not per button. It changes the button icon instead of the button text. --- CRM/Activity/Form/Activity.php | 3 +- CRM/Case/Form/Activity/OpenCase.php | 1 - CRM/Case/Form/Case.php | 2 + CRM/Contribute/Form/Contribution/Confirm.php | 3 +- CRM/Contribute/Form/Contribution/Main.php | 2 +- CRM/Core/Form.php | 15 ++++++-- .../Registration/AdditionalParticipant.php | 3 +- CRM/Event/Form/Registration/Confirm.php | 3 +- CRM/Event/Form/Registration/Register.php | 5 +-- CRM/SMS/Form/Schedule.php | 3 +- js/Common.js | 38 +++++++++++++++---- 11 files changed, 55 insertions(+), 23 deletions(-) diff --git a/CRM/Activity/Form/Activity.php b/CRM/Activity/Form/Activity.php index eec77a752c..d1ccc1bfb9 100644 --- a/CRM/Activity/Form/Activity.php +++ b/CRM/Activity/Form/Activity.php @@ -136,9 +136,10 @@ class CRM_Activity_Form_Activity extends CRM_Contact_Form_Task { * @var bool * */ - protected $supportsActivitySeparation = TRUE; + public $submitOnce = TRUE; + /** * Explicitly declare the entity api name. * diff --git a/CRM/Case/Form/Activity/OpenCase.php b/CRM/Case/Form/Activity/OpenCase.php index ed571d76f3..c233fd321a 100644 --- a/CRM/Case/Form/Activity/OpenCase.php +++ b/CRM/Case/Form/Activity/OpenCase.php @@ -198,7 +198,6 @@ class CRM_Case_Form_Activity_OpenCase { 'type' => 'upload', 'name' => ts('Save'), 'isDefault' => TRUE, - 'submitOnce' => TRUE, ], [ 'type' => 'upload', diff --git a/CRM/Case/Form/Case.php b/CRM/Case/Form/Case.php index 685ce79553..80b83d578c 100644 --- a/CRM/Case/Form/Case.php +++ b/CRM/Case/Form/Case.php @@ -91,6 +91,8 @@ class CRM_Case_Form_Case extends CRM_Core_Form { */ public $_caseTypeId = NULL; + public $submitOnce = TRUE; + /** * Explicitly declare the entity api name. */ diff --git a/CRM/Contribute/Form/Contribution/Confirm.php b/CRM/Contribute/Form/Contribution/Confirm.php index 9add6a4ec1..ffd9a524ce 100644 --- a/CRM/Contribute/Form/Contribution/Confirm.php +++ b/CRM/Contribute/Form/Contribution/Confirm.php @@ -52,6 +52,8 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr */ public $_contributionID; + public $submitOnce = TRUE; + /** * @param $form * @param $params @@ -615,7 +617,6 @@ class CRM_Contribute_Form_Contribution_Confirm extends CRM_Contribute_Form_Contr 'name' => $contribButton, 'spacing' => '         ', 'isDefault' => TRUE, - 'js' => ['onclick' => "return submitOnce(this,'" . $this->_name . "','" . ts('Processing') . "');"], ], [ 'type' => 'back', diff --git a/CRM/Contribute/Form/Contribution/Main.php b/CRM/Contribute/Form/Contribution/Main.php index 601c8e08fd..7738e66017 100644 --- a/CRM/Contribute/Form/Contribution/Main.php +++ b/CRM/Contribute/Form/Contribution/Main.php @@ -525,7 +525,7 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu ]; // Add submit-once behavior when confirm page disabled if (empty($this->_values['is_confirm_enabled'])) { - $submitButton['js'] = ['onclick' => "return submitOnce(this,'" . $this->_name . "','" . ts('Processing') . "');"]; + $this->submitOnce = TRUE; } //change button name for updating contribution if (!empty($this->_ccid)) { diff --git a/CRM/Core/Form.php b/CRM/Core/Form.php index d55dfd9751..6d5e6e5a14 100644 --- a/CRM/Core/Form.php +++ b/CRM/Core/Form.php @@ -189,6 +189,11 @@ class CRM_Core_Form extends HTML_QuickForm_Page { */ protected $context; + /** + * @var bool + */ + public $submitOnce = FALSE; + /** * @return string */ @@ -627,6 +632,10 @@ class CRM_Core_Form extends HTML_QuickForm_Page { ) { $this->setAttribute('data-warn-changes', 'true'); } + + if ($this->submitOnce) { + $this->setAttribute('data-submit-once', 'true'); + } } /** @@ -642,7 +651,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page { $prevnext = $spacing = []; foreach ($params as $button) { if (!empty($button['submitOnce'])) { - $button['js']['onclick'] = "return submitOnce(this,'{$this->_name}','" . ts('Processing') . "');"; + $this->submitOnce = TRUE; } $attrs = ['class' => 'crm-form-submit'] + (array) CRM_Utils_Array::value('js', $button); @@ -1255,7 +1264,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page { * @param string $nextType * Button type for the form after processing. * @param string $backType - * @param bool|string $submitOnce If true, add javascript to next button submit which prevents it from being clicked more than once + * @param bool|string $submitOnce */ public function addDefaultButtons($title, $nextType = 'next', $backType = 'back', $submitOnce = FALSE) { $buttons = []; @@ -1272,7 +1281,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page { 'isDefault' => TRUE, ]; if ($submitOnce) { - $nextButton['js'] = ['onclick' => "return submitOnce(this,'{$this->_name}','" . ts('Processing') . "');"]; + $this->submitOnce = TRUE; } $buttons[] = $nextButton; } diff --git a/CRM/Event/Form/Registration/AdditionalParticipant.php b/CRM/Event/Form/Registration/AdditionalParticipant.php index afaaf1a4d4..5e665f0175 100644 --- a/CRM/Event/Form/Registration/AdditionalParticipant.php +++ b/CRM/Event/Form/Registration/AdditionalParticipant.php @@ -210,7 +210,7 @@ class CRM_Event_Form_Registration_AdditionalParticipant extends CRM_Event_Form_R //add buttons $js = NULL; if ($this->isLastParticipant(TRUE) && empty($this->_values['event']['is_monetary'])) { - $js = ['onclick' => "return submitOnce(this,'" . $this->_name . "','" . ts('Processing') . "');"]; + $this->submitOnce = TRUE; } //handle case where user might sart with waiting by group @@ -361,7 +361,6 @@ class CRM_Event_Form_Registration_AdditionalParticipant extends CRM_Event_Form_R 'name' => ts('Continue'), 'spacing' => '                  ', 'isDefault' => TRUE, - 'js' => $js, ], ]); if ($includeSkipButton) { diff --git a/CRM/Event/Form/Registration/Confirm.php b/CRM/Event/Form/Registration/Confirm.php index 5acff51c3a..6d83f2148f 100644 --- a/CRM/Event/Form/Registration/Confirm.php +++ b/CRM/Event/Form/Registration/Confirm.php @@ -49,6 +49,8 @@ class CRM_Event_Form_Registration_Confirm extends CRM_Event_Form_Registration { */ public $_totalAmount; + public $submitOnce = TRUE; + /** * Monetary fields that may be submitted. * @@ -334,7 +336,6 @@ class CRM_Event_Form_Registration_Confirm extends CRM_Event_Form_Registration { 'type' => 'next', 'name' => $contribButton, 'isDefault' => TRUE, - 'js' => ['onclick' => "return submitOnce(this,'" . $this->_name . "','" . ts('Processing') . "');"], ], ]); diff --git a/CRM/Event/Form/Registration/Register.php b/CRM/Event/Form/Registration/Register.php index 080ecb98c4..2fcd458f84 100644 --- a/CRM/Event/Form/Registration/Register.php +++ b/CRM/Event/Form/Registration/Register.php @@ -463,10 +463,8 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration { ) { //freeze button to avoid multiple calls. - $js = NULL; - if (empty($this->_values['event']['is_monetary'])) { - $js = ['onclick' => "return submitOnce(this,'" . $this->_name . "','" . ts('Processing') . "');"]; + $this->submitOnce = TRUE; } // CRM-11182 - Optional confirmation screen @@ -488,7 +486,6 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration { 'name' => $buttonLabel, 'spacing' => '         ', 'isDefault' => TRUE, - 'js' => $js, ], ]); } diff --git a/CRM/SMS/Form/Schedule.php b/CRM/SMS/Form/Schedule.php index 4a1fdefb4f..1f6e8f1451 100644 --- a/CRM/SMS/Form/Schedule.php +++ b/CRM/SMS/Form/Schedule.php @@ -32,6 +32,8 @@ */ class CRM_SMS_Form_Schedule extends CRM_Core_Form { + public $submitOnce = TRUE; + /** * Set variables up before form is built. */ @@ -86,7 +88,6 @@ class CRM_SMS_Form_Schedule extends CRM_Core_Form { 'name' => ts('Submit Mass SMS'), 'spacing' => '                 ', 'isDefault' => TRUE, - 'js' => ['onclick' => "return submitOnce(this,'" . $this->_name . "','" . ts('Processing') . "');"], ], [ 'type' => 'cancel', diff --git a/js/Common.js b/js/Common.js index 9b5f835ed3..41be7f03ba 100644 --- a/js/Common.js +++ b/js/Common.js @@ -144,17 +144,11 @@ function showHideByValue(trigger_field_id, trigger_value, target_element_id, tar } } +var submitcount = 0; /** - * Function to change button text and disable one it is clicked + * Old submit-once function. Will be removed soon. * @deprecated - * @param obj object - the button clicked - * @param formID string - the id of the form being submitted - * @param string procText - button text after user clicks it - * @return bool */ -var submitcount = 0; -/* Changes button label on submit, and disables button after submit for newer browsers. - Puts up alert for older browsers. */ function submitOnce(obj, formId, procText) { // if named button clicked, change text if (obj.value != null) { @@ -860,6 +854,30 @@ if (!CRM.vars) CRM.vars = {}; }); }; + // Submit-once + var submitted = [], + submitButton; + function submitOnceForm(e) { + if (e.isDefaultPrevented()) { + return; + } + if (_.contains(submitted, e.target)) { + return false; + } + submitted.push(e.target); + // Spin submit button icon + if (submitButton && $(submitButton, e.target).length) { + // Dialog button + if ($(e.target).closest('.ui-dialog .crm-ajax-container')) { + var identifier = $(submitButton).attr('name') || $(submitButton).attr('href'); + if (identifier) { + submitButton = $(e.target).closest('.ui-dialog').find('button[data-identifier="' + identifier + '"]')[0] || submitButton; + } + } + $(submitButton).siblings('.crm-i').add('.crm-i, .ui-icon', submitButton).removeClass().addClass('crm-i fa-spinner fa-pulse'); + } + } + // Initialize widgets $(document) .on('crmLoad', function(e) { @@ -925,6 +943,10 @@ if (!CRM.vars) CRM.vars = {}; CRM.wysiwyg.create(this); } }); + $('form[data-submit-once]', e.target).submit(submitOnceForm); + $('form[data-submit-once] input[type=submit]', e.target).click(function(e) { + submitButton = e.target; + }); }) .on('dialogopen', function(e) { var $el = $(e.target); -- 2.25.1