Rewrite submitOnce function, deprecate old one
authorColeman Watts <coleman@civicrm.org>
Thu, 13 Jun 2019 20:26:02 +0000 (16:26 -0400)
committerColeman Watts <coleman@civicrm.org>
Sun, 16 Jun 2019 15:04:30 +0000 (11:04 -0400)
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
CRM/Case/Form/Activity/OpenCase.php
CRM/Case/Form/Case.php
CRM/Contribute/Form/Contribution/Confirm.php
CRM/Contribute/Form/Contribution/Main.php
CRM/Core/Form.php
CRM/Event/Form/Registration/AdditionalParticipant.php
CRM/Event/Form/Registration/Confirm.php
CRM/Event/Form/Registration/Register.php
CRM/SMS/Form/Schedule.php
js/Common.js

index eec77a752c232b4b4221d707fb8005516224d5b2..d1ccc1bfb980d03b6db4438b5b6cf813b7039e5e 100644 (file)
@@ -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.
    *
index ed571d76f3ad37edddc1965634af4174d056967b..c233fd321a612b878386627e252d6cbb1c3a4306 100644 (file)
@@ -198,7 +198,6 @@ class CRM_Case_Form_Activity_OpenCase {
         'type' => 'upload',
         'name' => ts('Save'),
         'isDefault' => TRUE,
-        'submitOnce' => TRUE,
       ],
       [
         'type' => 'upload',
index 685ce79553d009aafacc0f47d4d65dbba375572b..80b83d578cde94b797b18c44e522199136672790 100644 (file)
@@ -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.
    */
index 9add6a4ec12fc172b89cf6f7ee609fabdc9aa145..ffd9a524cee08a4aed0d9cc2b18d4657ee507b34 100644 (file)
@@ -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' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
         'isDefault' => TRUE,
-        'js' => ['onclick' => "return submitOnce(this,'" . $this->_name . "','" . ts('Processing') . "');"],
       ],
       [
         'type' => 'back',
index 601c8e08fd2ebbbca2caba0e5171d0bf5feee9a4..7738e66017ad81901524758fa6fc81e9ea4df205 100644 (file)
@@ -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)) {
index d55dfd97519f0f328d49cfcfeb2f685bd5e6cc5f..6d5e6e5a14ca02265b4cda218e1c2256f464542c 100644 (file)
@@ -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;
     }
index afaaf1a4d4ff8e5af2c408043fb9bf9da1c4e1d2..5e665f0175ea218e08f5eb6a1f0e1565910adb62 100644 (file)
@@ -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' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
           'isDefault' => TRUE,
-          'js' => $js,
         ],
       ]);
       if ($includeSkipButton) {
index 5acff51c3acd97638ecf256bfafd14b07222f079..6d83f2148ff006152f9c26e248093e3d1d983641 100644 (file)
@@ -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') . "');"],
       ],
     ]);
 
index 080ecb98c4d561fde3adbe2e77b36937f5a4963b..2fcd458f8408cbeb7d4daad12a4febc8c946fd66 100644 (file)
@@ -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' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
           'isDefault' => TRUE,
-          'js' => $js,
         ],
       ]);
     }
index 4a1fdefb4fe56b7b30b1d575ccbb333cbdc3de1a..1f6e8f14516ff05a9c86741bb605eda1a393f672 100644 (file)
@@ -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' => '&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;',
         'isDefault' => TRUE,
-        'js' => ['onclick' => "return submitOnce(this,'" . $this->_name . "','" . ts('Processing') . "');"],
       ],
       [
         'type' => 'cancel',
index 9b5f835ed37921d563d4b7e401cd07fe3bc55600..41be7f03ba4aa2ab3de45fa95d96452e22f3f362 100644 (file)
@@ -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);