[BUGFIX] Fix doubleclick-doublesubmit touchup 57/50857/2
authorMarkus Timtner <markus@timtner.de>
Mon, 21 Nov 2016 10:07:58 +0000 (11:07 +0100)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Sat, 3 Dec 2016 10:19:09 +0000 (11:19 +0100)
If a user double-clicks fast enough on any save-button of any new record
in Chrome, the record gets submitted twice.
This fix introduces a semaphore variable in the corresponding JS
to ensure the record gets submitted only once.

Resolves: #77942
Related: #77729, #77944
Releases: master, 7.6
Change-Id: I73516b6a07b23b947e0756dea7051863546a246d
Reviewed-on: https://review.typo3.org/50857
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
typo3/sysext/backend/Resources/Public/JavaScript/SplitButtons.js

index 9279cf3..7c11585 100644 (file)
@@ -31,6 +31,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Icons'], function($, Icons) {
         * Initializes the save handling
         */
        SplitButtons.initializeSaveHandling = function() {
+               var preventExec = false;
                var elements = [
                        'button[form]',
                        'button[name^="_save"]',
@@ -39,45 +40,49 @@ define(['jquery', 'TYPO3/CMS/Backend/Icons'], function($, Icons) {
                        'a[data-name="CMD"][data-value^="save"]'
                ].join(',');
                $('.t3js-module-docheader').on('click', elements, function(e) {
-                       var $me = $(this),
-                               linkedForm = $me.attr('form') || $me.attr('data-form') || null,
-                               $form = linkedForm ? $('#' + linkedForm) : $me.closest('form'),
-                               name = $me.data('name') || this.name,
-                               value = $me.data('value') || this.value,
-                               $elem = $('<input />').attr('type', 'hidden').attr('name', name).attr('value', value);
+                       // prevent doubleclick double submission bug in chrome,
+                       // see https://forge.typo3.org/issues/77942
+                       if (!preventExec) {
+                               preventExec = true;
+                               var $me = $(this),
+                                       linkedForm = $me.attr('form') || $me.attr('data-form') || null,
+                                       $form = linkedForm ? $('#' + linkedForm) : $me.closest('form'),
+                                       name = $me.data('name') || this.name,
+                                       value = $me.data('value') || this.value,
+                                       $elem = $('<input />').attr('type', 'hidden').attr('name', name).attr('value', value);
 
-                       // Run any preSubmit callbacks
-                       for (var i = 0; i < SplitButtons.preSubmitCallbacks.length; ++i) {
-                               SplitButtons.preSubmitCallbacks[i](e);
-                       }
-
-                       $form.append($elem);
-
-                       // Disable submit buttons
-                       $form.on('submit', function() {
-                               if ($form.find('.has-error').length > 0) {
-                                       return false;
+                               // Run any preSubmit callbacks
+                               for (var i = 0; i < SplitButtons.preSubmitCallbacks.length; ++i) {
+                                       SplitButtons.preSubmitCallbacks[i](e);
                                }
+                               $form.append($elem);
+                               // Disable submit buttons
+                               $form.on('submit', function() {
+                                       if ($form.find('.has-error').length > 0) {
+                                               preventExec = false;
+                                               return false;
+                                       }
 
-                               var $affectedButton,
-                                       $splitButton = $me.closest('.t3js-splitbutton');
+                                       var $affectedButton,
+                                               $splitButton = $me.closest('.t3js-splitbutton');
 
-                               if ($splitButton.length > 0) {
-                                       $splitButton.find('button').prop('disabled', true);
-                                       $affectedButton = $splitButton.children().first();
-                               } else {
-                                       $me.prop('disabled', true);
-                                       $affectedButton = $me;
-                               }
+                                       if ($splitButton.length > 0) {
+                                               $splitButton.find('button').prop('disabled', true);
+                                               $affectedButton = $splitButton.children().first();
+                                       } else {
+                                               $me.prop('disabled', true);
+                                               $affectedButton = $me;
+                                       }
 
-                               Icons.getIcon('spinner-circle-dark', Icons.sizes.small).done(function(markup) {
-                                       $affectedButton.find('.t3js-icon').replaceWith(markup);
+                                       Icons.getIcon('spinner-circle-dark', Icons.sizes.small).done(function(markup) {
+                                               $affectedButton.find('.t3js-icon').replaceWith(markup);
+                                       });
                                });
-                       });
 
-                       if ((e.currentTarget.tagName === 'A' || $me.attr('form')) && !e.isDefaultPrevented()) {
-                               $form.submit();
-                               e.preventDefault();
+                               if ((e.currentTarget.tagName === 'A' || $me.attr('form')) && !e.isDefaultPrevented()) {
+                                       $form.submit();
+                                       e.preventDefault();
+                               }
                        }
                });
        };