From 96453a8f1d132d64a5128bbfb1ff2ae22e32b921 Mon Sep 17 00:00:00 2001
From: "konstantin.viktorov" <konstantin.viktorov@massmo.ru>
Date: Wed, 24 Feb 2016 22:05:06 +0300
Subject: [PATCH] scale modal

---
 .../ctools_ajax_sample/ctools_ajax_sample.module   |  38 ++++
 sites/all/modules/ctools/js/modal.js               | 216 ++++++++++++++++-----
 2 files changed, 204 insertions(+), 50 deletions(-)

diff --git a/sites/all/modules/ctools/ctools_ajax_sample/ctools_ajax_sample.module b/sites/all/modules/ctools/ctools_ajax_sample/ctools_ajax_sample.module
index 4638ac3..f715ad7 100644
--- a/sites/all/modules/ctools/ctools_ajax_sample/ctools_ajax_sample.module
+++ b/sites/all/modules/ctools/ctools_ajax_sample/ctools_ajax_sample.module
@@ -137,9 +137,44 @@ function ctools_ajax_sample_page() {
       'modalTheme' => 'CToolsSampleModal',
       'throbber' => theme('image', array('path' => ctools_image_path('ajax-loader.gif', 'ctools_ajax_sample'), 'alt' => t('Loading...'), 'title' => t('Loading'))),
     ),
+    'ctools-ui-dialog' => array(
+      'library' => 'ui.dialog',
+      //'modalTheme' => 'CToolsSampleModal',
+      'throbber' => theme('image', array('path' => ctools_image_path('ajax-loader.gif', 'ctools_ajax_sample'), 'alt' => t('Loading...'), 'title' => t('Loading'))),
+      // This is jQuery's dialog default values not required, just for reference
+      'options' => array(
+        'disabled' => TRUE,
+        'autoOpen' => TRUE, // Not the default!
+        //'buttons' => new stdClass(),
+        'closeOnEscape' => TRUE,
+        'closeText' => t('Close'),
+        'dialogClass' => '',
+        'draggable' => TRUE,
+        'height' => 'auto',
+        'hide' => NULL,
+        'maxHeight' => FALSE,
+        'maxWidth' => FALSE,
+        'minHeight' => 300,
+        'minWidth' => 600,
+        'modal' => FALSE,
+        'position' => FALSE,
+        'resizable' => TRUE,
+        'show' => 'fade',
+        'stack' => TRUE,
+        //'title' => '',
+        'width' => 300,
+        'zIndex' => 1000,
+      ),
+    	'modalSize' => array(
+    		'type' => 'scale',
+    		'width' => 0.8,
+    		'height' => 0.8,
+    	),
+    ),
   );
 
   drupal_add_js($sample_style, 'setting');
+  drupal_add_library('system', 'ui.dialog');
 
   // Since we have our js, css and images in well-known named directories,
   // CTools makes it easy for us to just use them without worrying about
@@ -157,6 +192,8 @@ function ctools_ajax_sample_page() {
     // The extra class points to the info in ctools-sample-style which we added
     // to the settings, prefixed with 'ctools-modal'.
     $links[] = ctools_modal_text_button(t('Modal Login (custom style)'), 'ctools_ajax_sample/nojs/login', t('Login via modal'),  'ctools-modal-ctools-sample-style');
+    // jQuery UI Dialog style
+    $links[] = ctools_modal_text_button(t('Modal Login (jQuery dialog'), 'ctools_ajax_sample/nojs/login', t('Login via modal'),  'ctools-modal-ctools-ui-dialog');
   }
 
   // Four ways to do our animal picking wizard.
@@ -164,6 +201,7 @@ function ctools_ajax_sample_page() {
   $links[] = l(t('Wizard (no modal)'), 'ctools_ajax_sample/nojs/animal');
   $links[] = ctools_modal_text_button(t('Wizard (default modal)'), 'ctools_ajax_sample/nojs/animal', t('Pick an animal'));
   $links[] = ctools_modal_text_button(t('Wizard (custom modal)'), 'ctools_ajax_sample/nojs/animal', t('Pick an animal'),  'ctools-modal-ctools-sample-style');
+  $links[] = ctools_modal_text_button(t('Wizard (jQuery dialog)'), 'ctools_ajax_sample/nojs/animal', t('Pick an animal'),  'ctools-modal-ctools-ui-dialog');
   $links[] = drupal_render($button_form);
 
   $links[] = ctools_ajax_text_button(t('Hello world!'), "ctools_ajax_sample/nojs/hello", t('Replace text with "hello world"'));
diff --git a/sites/all/modules/ctools/js/modal.js b/sites/all/modules/ctools/js/modal.js
index c757ef2..be5eb3b 100644
--- a/sites/all/modules/ctools/js/modal.js
+++ b/sites/all/modules/ctools/js/modal.js
@@ -13,12 +13,16 @@
   Drupal.CTools = Drupal.CTools || {};
   Drupal.CTools.Modal = Drupal.CTools.Modal || {};
 
+
+  var ctoolsModal = Drupal.CTools.Modal;
+  var modalJQuery = null;
+
   /**
    * Display the modal
    *
    * @todo -- document the settings.
    */
-  Drupal.CTools.Modal.show = function(choice) {
+  ctoolsModal.show = function(choice) {
     var opts = {};
 
     if (choice && typeof choice == 'string' && Drupal.settings[choice]) {
@@ -30,6 +34,7 @@
     }
 
     var defaults = {
+      library: null,
       modalTheme: 'CToolsModalDialog',
       throbberTheme: 'CToolsModalThrobber',
       animation: 'show',
@@ -49,47 +54,61 @@
         opacity: .55,
         background: '#fff'
       },
+      options: {},
       modalClass: 'default'
     };
 
     var settings = {};
     $.extend(true, settings, defaults, Drupal.settings.CToolsModal, opts);
 
-    if (Drupal.CTools.Modal.currentSettings && Drupal.CTools.Modal.currentSettings != settings) {
-      Drupal.CTools.Modal.modal.remove();
-      Drupal.CTools.Modal.modal = null;
+    if (ctoolsModal.currentSettings && ctoolsModal.currentSettings != settings) {
+      ctoolsModal.modal.remove();
+      ctoolsModal.modal = null;
     }
 
-    Drupal.CTools.Modal.currentSettings = settings;
+    ctoolsModal.currentSettings = settings;
+
+    // Set the library for jQuery UI
+    modalJQuery = ctoolsModal.currentSettings['library'] == 'ui.dialog';
+
+    if (modalJQuery) {
+
+      if (ctoolsModal.modal && ('dialog' in ctoolsModal.modal)) {
+        ctoolsModal.modal.dialog('close');
+        ctoolsModal.modal = null;
+      }
+      ctoolsModal.modalContent(Drupal.theme(settings.throbberTheme), settings);
+      return;
+    }
 
     var resize = function(e) {
       // When creating the modal, it actually exists only in a theoretical
       // place that is not in the DOM. But once the modal exists, it is in the
       // DOM so the context must be set appropriately.
-      var context = e ? document : Drupal.CTools.Modal.modal;
+      var context = e ? document : ctoolsModal.modal;
 
-      if (Drupal.CTools.Modal.currentSettings.modalSize.type == 'scale') {
-        var width = $(window).width() * Drupal.CTools.Modal.currentSettings.modalSize.width;
-        var height = $(window).height() * Drupal.CTools.Modal.currentSettings.modalSize.height;
+      if (ctoolsModal.currentSettings.modalSize.type == 'scale') {
+        var width = $(window).width() * ctoolsModal.currentSettings.modalSize.width;
+        var height = $(window).height() * ctoolsModal.currentSettings.modalSize.height;
       }
       else {
-        var width = Drupal.CTools.Modal.currentSettings.modalSize.width;
-        var height = Drupal.CTools.Modal.currentSettings.modalSize.height;
+        var width = ctoolsModal.currentSettings.modalSize.width;
+        var height = ctoolsModal.currentSettings.modalSize.height;
       }
 
-      // Use the additionol pixels for creating the width and height.
+      // Use the additional pixels for creating the width and height.
       $('div.ctools-modal-content', context).css({
-        'width': width + Drupal.CTools.Modal.currentSettings.modalSize.addWidth + 'px',
-        'height': height + Drupal.CTools.Modal.currentSettings.modalSize.addHeight + 'px'
+        'width': width + ctoolsModal.currentSettings.modalSize.addWidth + 'px',
+        'height': height + ctoolsModal.currentSettings.modalSize.addHeight + 'px'
       });
       $('div.ctools-modal-content .modal-content', context).css({
-        'width': (width - Drupal.CTools.Modal.currentSettings.modalSize.contentRight) + 'px',
-        'height': (height - Drupal.CTools.Modal.currentSettings.modalSize.contentBottom) + 'px'
+        'width': (width - ctoolsModal.currentSettings.modalSize.contentRight) + 'px',
+        'height': (height - ctoolsModal.currentSettings.modalSize.contentBottom) + 'px'
       });
     }
 
-    if (!Drupal.CTools.Modal.modal) {
-      Drupal.CTools.Modal.modal = $(Drupal.theme(settings.modalTheme));
+    if (!ctoolsModal.modal) {
+      ctoolsModal.modal = $(Drupal.theme(settings.modalTheme));
       if (settings.modalSize.type == 'scale') {
         $(window).bind('resize', resize);
       }
@@ -97,8 +116,8 @@
 
     resize();
 
-    $('span.modal-title', Drupal.CTools.Modal.modal).html(Drupal.CTools.Modal.currentSettings.loadingText);
-    Drupal.CTools.Modal.modalContent(Drupal.CTools.Modal.modal, settings.modalOptions, settings.animation, settings.animationSpeed, settings.modalClass);
+    $('span.modal-title', ctoolsModal.modal).html(ctoolsModal.currentSettings.loadingText);
+    ctoolsModal.modalContent(Drupal.CTools.Modal.modal, settings.modalOptions, settings.animation, settings.animationSpeed, settings.modalClass);
     $('#modalContent .modal-content').html(Drupal.theme(settings.throbberTheme)).addClass('ctools-modal-loading');
 
     // Position autocomplete results based on the scroll position of the modal.
@@ -110,9 +129,9 @@
   /**
    * Hide the modal
    */
-  Drupal.CTools.Modal.dismiss = function() {
-    if (Drupal.CTools.Modal.modal) {
-      Drupal.CTools.Modal.unmodalContent(Drupal.CTools.Modal.modal);
+  ctoolsModal.dismiss = function() {
+    if (ctoolsModal.modal) {
+      ctoolsModal.unmodalContent(ctoolsModal.modal);
     }
   };
 
@@ -125,7 +144,7 @@
     html += '    <div class="ctools-modal-content">' // panels-modal-content
     html += '      <div class="modal-header">';
     html += '        <a class="close" href="#">';
-    html +=            Drupal.CTools.Modal.currentSettings.closeText + Drupal.CTools.Modal.currentSettings.closeImage;
+    html +=            ctoolsModal.currentSettings.closeText + ctoolsModal.currentSettings.closeImage;
     html += '        </a>';
     html += '        <span id="modal-title" class="modal-title">&nbsp;</span>';
     html += '      </div>';
@@ -144,7 +163,7 @@
     var html = '';
     html += '  <div id="modal-throbber">';
     html += '    <div class="modal-throbber-wrapper">';
-    html +=        Drupal.CTools.Modal.currentSettings.throbber;
+    html +=        ctoolsModal.currentSettings.throbber;
     html += '    </div>';
     html += '  </div>';
 
@@ -154,7 +173,7 @@
   /**
    * Figure out what settings string to use to display a modal.
    */
-  Drupal.CTools.Modal.getSettings = function (object) {
+  ctoolsModal.getSettings = function (object) {
     var match = $(object).attr('class').match(/ctools-modal-(\S+)/);
     if (match) {
       return match[1];
@@ -164,23 +183,23 @@
   /**
    * Click function for modals that can be cached.
    */
-  Drupal.CTools.Modal.clickAjaxCacheLink = function () {
-    Drupal.CTools.Modal.show(Drupal.CTools.Modal.getSettings(this));
+  ctoolsModal.clickAjaxCacheLink = function () {
+    ctoolsModal.show(ctoolsModal.getSettings(this));
     return Drupal.CTools.AJAX.clickAJAXCacheLink.apply(this);
   };
 
   /**
    * Handler to prepare the modal for the response
    */
-  Drupal.CTools.Modal.clickAjaxLink = function () {
-    Drupal.CTools.Modal.show(Drupal.CTools.Modal.getSettings(this));
+  ctoolsModal.clickAjaxLink = function () {
+    ctoolsModal.show(ctoolsModal.getSettings(this));
     return false;
   };
 
   /**
    * Submit responder to do an AJAX submit on all modal forms.
    */
-  Drupal.CTools.Modal.submitAjaxForm = function(e) {
+  ctoolsModal.submitAjaxForm = function(e) {
     var $form = $(this);
     var url = $form.attr('action');
 
@@ -206,7 +225,7 @@
 
       $('area.ctools-use-modal, a.ctools-use-modal', context).once('ctools-use-modal', function() {
         var $this = $(this);
-        $this.click(Drupal.CTools.Modal.clickAjaxLink);
+        $this.click(ctoolsModal.clickAjaxLink);
         // Create a drupal ajax object
         var element_settings = {};
         if ($this.attr('href')) {
@@ -221,13 +240,13 @@
       // Bind buttons
       $('input.ctools-use-modal, button.ctools-use-modal', context).once('ctools-use-modal', function() {
         var $this = $(this);
-        $this.click(Drupal.CTools.Modal.clickAjaxLink);
+        $this.click(ctoolsModal.clickAjaxLink);
         var button = this;
         var element_settings = {};
 
         // AJAX submits specified in this manner automatically submit to the
         // normal form action.
-        element_settings.url = Drupal.CTools.Modal.findURL(this);
+        element_settings.url = ctoolsModal.findURL(this);
         if (element_settings.url == '') {
           element_settings.url = $(this).closest('form').attr('action');
         }
@@ -239,7 +258,7 @@
 
         // Make sure changes to settings are reflected in the URL.
         $('.' + $(button).attr('id') + '-url').change(function() {
-          Drupal.ajax[base].options.url = Drupal.CTools.Modal.findURL(button);
+          Drupal.ajax[base].options.url = ctoolsModal.findURL(button);
         });
       });
 
@@ -276,20 +295,75 @@
       // class to close the modal.
       $('.ctools-close-modal', context).once('ctools-close-modal')
         .click(function() {
-          Drupal.CTools.Modal.dismiss();
+          ctoolsModal.dismiss();
           return false;
         });
     }
   };
 
+  // Register events here, example of how a custom script could work with it. Loose coupling win.
+  $(window).bind('modalAfterCreate', function (e, $modal, settings) {
+    // We don't want to use behaviors because it's very useless to run it that much.
+    $modal.bind('loadStop', function (e) {
+      // Bind our custom event to the form submit
+      $(this).find('form').once('ctools-use-modal', function() {
+        var element_settings = {};
+
+        element_settings.url = $(this).attr('action');
+        element_settings.event = 'submit';
+        element_settings.progress = { 'type': 'throbber' }
+        var base = $(this).attr('id');
+
+        Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
+        Drupal.ajax[base].form = $(this);
+
+        var buttons = {};
+        // Transform submit in dialog buttons.
+        $(this).find('input[type=submit], button')
+          .each(function () {
+            var $that = $(this).hide();
+            var text = $(this).html() || $(this).attr('value');
+
+            buttons[text] = function (e) {
+              var that = $that[0];
+              var base = $(that.form).attr('id');
+              Drupal.ajax[base].element = that;
+              that.form.clk = that;
+              $(that.form).trigger('submit');
+            };
+          });
+
+        ctoolsModal.modal.dialog('option', 'buttons', buttons);
+      });
+    });
+  });
+
   // The following are implementations of AJAX responder commands.
 
   /**
    * AJAX responder command to place HTML within the modal.
    */
-  Drupal.CTools.Modal.modal_display = function(ajax, response, status) {
+  ctoolsModal.modal_display = function(ajax, response, status) {
+    if (modalJQuery) {
+      var $modalContent = ctoolsModal.modal;
+      if ($modalContent.length === 0) {
+        ctoolsModal.show(ctoolsModal.getSettings(ajax.element));
+      }
+
+      Drupal.detachBehaviors($modalContent.get(0), null, 'unload');
+      $modalContent.html('');
+      $modalContent.trigger('load');
+
+      $modalContent.dialog('option', 'title', response.title);
+      $modalContent.html(response.output);
+      // Triggers a event to allow other scripts to react.
+      $modalContent.trigger('loadStop');
+      return;
+    }
+    
+
     if ($('#modalContent').length == 0) {
-      Drupal.CTools.Modal.show(Drupal.CTools.Modal.getSettings(ajax.element));
+      ctoolsModal.show(ctoolsModal.getSettings(ajax.element));
     }
     $('#modal-title').html(response.title);
     // Simulate an actual page load by scrolling to the top after adding the
@@ -316,8 +390,8 @@
   /**
    * AJAX responder command to dismiss the modal.
    */
-  Drupal.CTools.Modal.modal_dismiss = function(command) {
-    Drupal.CTools.Modal.dismiss();
+  ctoolsModal.modal_dismiss = function(command) {
+    ctoolsModal.dismiss();
     $('link.ctools-temporary-css').remove();
   }
 
@@ -325,10 +399,10 @@
    * Display loading
    */
   //Drupal.CTools.AJAX.commands.modal_loading = function(command) {
-  Drupal.CTools.Modal.modal_loading = function(command) {
-    Drupal.CTools.Modal.modal_display({
-      output: Drupal.theme(Drupal.CTools.Modal.currentSettings.throbberTheme),
-      title: Drupal.CTools.Modal.currentSettings.loadingText
+  ctoolsModal.modal_loading = function(command) {
+    ctoolsModal.modal_display({
+      output: Drupal.theme(ctoolsModal.currentSettings.throbberTheme),
+      title: ctoolsModal.currentSettings.loadingText
     });
   }
 
@@ -340,7 +414,7 @@
    * class. They need to be in the form in order since we will
    * concat them all together using '/'.
    */
-  Drupal.CTools.Modal.findURL = function(item) {
+  ctoolsModal.findURL = function(item) {
     var url = '';
     var url_class = '.' + $(item).attr('id') + '-url';
     $(url_class).each(
@@ -363,7 +437,45 @@
    * @param speed (valid animation speeds slow, medium, fast or # in ms)
    * @param modalClass class added to div#modalContent
    */
-  Drupal.CTools.Modal.modalContent = function(content, css, animation, speed, modalClass) {
+  ctoolsModal.modalContent = function(content, css, animation, speed, modalClass) {
+    if (modalJQuery) {
+      // Here content is $content.
+      var $content = content;
+      // And css is settings.
+      var settings = css;
+      var $modalContent = $('<div id="modalContent"/>').html($content);
+      var options = $.extend(true, {}, settings.options, {
+        title: settings.loadingText,
+        close: function (e) {
+          Drupal.detachBehaviors(e.target, null, 'unload');
+          // Remove everything from the DOM like the previous modal dialog.
+          $(e.target).dialog('destroy').remove();
+        }
+      });
+
+      if (ctoolsModal.currentSettings.modalSize.type == 'scale') {
+    	options.width = $(window).width() * ctoolsModal.currentSettings.modalSize.width;
+    	options.height = $(window).height() * ctoolsModal.currentSettings.modalSize.height;
+      }
+      
+      // Remove leftover buttons.
+      $modalContent.bind('load', function () {
+        $(this).dialog('option', 'buttons', null);
+      });
+      // Attach behaviors to the new AJAX content.
+      $modalContent.bind('loadStop', function () {
+        Drupal.attachBehaviors($(this).parent());
+      });
+      // Trigger a global event to allow scripts to bind events to the dialog.
+      $(window).trigger('modalBeforeCreate', [$modalContent, options]);
+            
+      $modalContent.dialog(options);
+      $(window).trigger('modalAfterCreate', [$modalContent, options]);
+      ctoolsModal.modal = $modalContent;
+      return;
+    }
+
+
     // If our animation isn't set, make it just show/pop
     if (!animation) {
       animation = 'show';
@@ -644,8 +756,12 @@
    * @param animation (fadeOut, slideUp, show)
    * @param speed (valid animation speeds slow, medium, fast or # in ms)
    */
-  Drupal.CTools.Modal.unmodalContent = function(content, animation, speed)
-  {
+  ctoolsModal.unmodalContent = function(content, animation, speed) {
+    if (modalJQuery) {
+      ctoolsModal.modal.dialog('close');
+      return;
+    }
+
     // If our animation isn't set, make it just show/pop
     if (!animation) { var animation = 'show'; } else {
       // If our animation isn't "fade" then it always is show
@@ -689,8 +805,8 @@
   };
 
 $(function() {
-  Drupal.ajax.prototype.commands.modal_display = Drupal.CTools.Modal.modal_display;
-  Drupal.ajax.prototype.commands.modal_dismiss = Drupal.CTools.Modal.modal_dismiss;
+  Drupal.ajax.prototype.commands.modal_display = ctoolsModal.modal_display;
+  Drupal.ajax.prototype.commands.modal_dismiss = ctoolsModal.modal_dismiss;
 });
 
 })(jQuery);
-- 
1.9.5.msysgit.0

