MDL-61138 javascript: add preshow callback to modal factory
authorRyan Wyllie <ryan@moodle.com>
Wed, 21 Mar 2018 07:06:32 +0000 (15:06 +0800)
committerRyan Wyllie <ryan@moodle.com>
Wed, 18 Apr 2018 03:19:37 +0000 (11:19 +0800)
lib/amd/build/modal_factory.min.js
lib/amd/src/modal_factory.js

index d041bf7..5494e45 100644 (file)
Binary files a/lib/amd/build/modal_factory.min.js and b/lib/amd/build/modal_factory.min.js differ
index 29acb94..b946390 100644 (file)
@@ -60,49 +60,55 @@ define(['jquery', 'core/modal_events', 'core/modal_registry', 'core/modal',
      * @method setUpTrigger
      * @param {Promise} modalPromise The modal instance
      * @param {object} triggerElement The jQuery element to open the modal
+     * @param {object} modalConfig The modal configuration given to the factory
      */
-    var setUpTrigger = function(modalPromise, triggerElement) {
-        if (typeof triggerElement != 'undefined') {
-            // The element that actually shows the modal.
-            var actualTriggerElement = null;
-            if (Array.isArray(triggerElement)) {
-                var selector = triggerElement[1];
-                triggerElement = triggerElement[0];
-
-                CustomEvents.define(triggerElement, [CustomEvents.events.activate]);
-                triggerElement.on(CustomEvents.events.activate, selector, function(e, data) {
-                    actualTriggerElement = e.currentTarget;
-                    modalPromise.then(function(modal) {
-                        modal.show();
-
-                        return modal;
-                    });
-                    data.originalEvent.preventDefault();
-                });
-            } else {
-                CustomEvents.define(triggerElement, [CustomEvents.events.activate]);
-                triggerElement.on(CustomEvents.events.activate, function(e, data) {
-                    actualTriggerElement = e.currentTarget;
-                    modalPromise.then(function(modal) {
-                        modal.show();
-
-                        return modal;
-                    });
-                    data.originalEvent.preventDefault();
-                });
-            }
-
+    var setUpTrigger = function(modalPromise, triggerElement, modalConfig) {
+        // The element that actually shows the modal.
+        var actualTriggerElement = null;
+        // Check if the client has provided a callback function to be called
+        // before the modal is displayed.
+        var hasPreShowCallback = (typeof modalConfig.preShowCallback == 'function');
+        // Function to handle the trigger element being activated.
+        var triggeredCallback = function(e, data) {
+            actualTriggerElement = $(e.currentTarget);
             modalPromise.then(function(modal) {
-                modal.getRoot().on(ModalEvents.hidden, function() {
-                    // Focus on the trigger element that actually launched the modal.
-                    if (actualTriggerElement !== null) {
-                        actualTriggerElement.focus();
-                    }
-                });
+                if (hasPreShowCallback) {
+                    // If the client provided a pre-show callback then execute
+                    // it now before showing the modal.
+                    modalConfig.preShowCallback(actualTriggerElement, modal);
+                }
+
+                modal.show();
 
                 return modal;
             });
+            data.originalEvent.preventDefault();
+        };
+
+        // The trigger element can either be a single element or it can be an
+        // element + selector pair to create a delegated event handler to trigger
+        // the modal.
+        if (Array.isArray(triggerElement)) {
+            var selector = triggerElement[1];
+            triggerElement = triggerElement[0];
+
+            CustomEvents.define(triggerElement, [CustomEvents.events.activate]);
+            triggerElement.on(CustomEvents.events.activate, selector, triggeredCallback);
+        } else {
+            CustomEvents.define(triggerElement, [CustomEvents.events.activate]);
+            triggerElement.on(CustomEvents.events.activate, triggeredCallback);
         }
+
+        modalPromise.then(function(modal) {
+            modal.getRoot().on(ModalEvents.hidden, function() {
+                // Focus on the trigger element that actually launched the modal.
+                if (actualTriggerElement !== null) {
+                    actualTriggerElement.focus();
+                }
+            });
+
+            return modal;
+        });
     };
 
     /**
@@ -112,7 +118,6 @@ define(['jquery', 'core/modal_events', 'core/modal_registry', 'core/modal',
      * @method createFromElement
      * @param {object} registryConf A config from the ModalRegistry
      * @param {object} modalElement The modal HTML jQuery object
-     * @param {object} triggerElement The trigger HTML jQuery object
      * @return {object} Modal instance
      */
     var createFromElement = function(registryConf, modalElement) {
@@ -125,15 +130,14 @@ define(['jquery', 'core/modal_events', 'core/modal_registry', 'core/modal',
 
     /**
      * Create the correct modal instance for the given type, including loading
-     * the correct template and setting up the trigger relationship with the
-     * trigger element.
+     * the correct template.
      *
      * @method createFromType
      * @param {object} registryConf A config from the ModalRegistry
-     * @param {object} triggerElement The trigger HTML jQuery object
+     * @param {object} templateContext The context to render the template with
      * @return {promise} Resolved with a Modal instance
      */
-    var createFromType = function(registryConf, templateContext, triggerElement) {
+    var createFromType = function(registryConf, templateContext) {
         var templateName = registryConf.template;
 
         var modalPromise = Templates.render(templateName, templateContext)
@@ -143,8 +147,6 @@ define(['jquery', 'core/modal_events', 'core/modal_registry', 'core/modal',
             })
             .fail(Notification.exception);
 
-        setUpTrigger(modalPromise, triggerElement);
-
         return modalPromise;
     };
 
@@ -172,7 +174,7 @@ define(['jquery', 'core/modal_events', 'core/modal_registry', 'core/modal',
             templateContext = modalConfig.templateContext;
         }
 
-        return createFromType(registryConf, templateContext, triggerElement)
+        var modalPromise = createFromType(registryConf, templateContext)
             .then(function(modal) {
                 if (typeof modalConfig.title != 'undefined') {
                     modal.setTitle(modalConfig.title);
@@ -192,6 +194,12 @@ define(['jquery', 'core/modal_events', 'core/modal_registry', 'core/modal',
 
                 return modal;
             });
+
+        if (typeof triggerElement != 'undefined') {
+            setUpTrigger(modalPromise, triggerElement, modalConfig);
+        }
+
+        return modalPromise;
     };
 
     return {