diff --git a/ctools_ajax_sample/ctools_ajax_sample.module b/ctools_ajax_sample/ctools_ajax_sample.module
index 2a30c2a..27f88cc 100644
--- a/ctools_ajax_sample/ctools_ajax_sample.module
+++ b/ctools_ajax_sample/ctools_ajax_sample.module
@@ -137,6 +137,21 @@ 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-sample-style-dynamic' => array(
+ 'modalSize' => array(
+ 'type' => 'dynamic',
+ 'width' => 100,
+ 'height' => 100,
+ ),
+ 'modalOptions' => array(
+ 'opacity' => .5,
+ 'background-color' => '#000',
+ ),
+ 'animation' => 'slideDown',
+ 'speed' => 'fast',
+ 'modalTheme' => 'CToolsSampleModal',
+ 'throbber' => theme('image', array('path' => ctools_image_path('ajax-loader.gif', 'ctools_ajax_sample'), 'alt' => t('Loading...'), 'title' => t('Loading'))),
+ ),
);
drupal_add_js($sample_style, 'setting');
@@ -164,6 +179,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 (dynamic modal)'), 'ctools_ajax_sample/nojs/animal', t('Pick an animal'), 'ctools-modal-ctools-sample-style-dynamic');
$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/js/modal.js b/js/modal.js
index 37908cf..d00dc9b 100644
--- a/js/modal.js
+++ b/js/modal.js
@@ -61,45 +61,16 @@
Drupal.CTools.Modal.currentSettings = settings;
- 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;
-
- 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;
- }
- else {
- var width = Drupal.CTools.Modal.currentSettings.modalSize.width;
- var height = Drupal.CTools.Modal.currentSettings.modalSize.height;
- }
-
- // Use the additionol 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'
- });
- $('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'
- });
- }
-
if (!Drupal.CTools.Modal.modal) {
Drupal.CTools.Modal.modal = $(Drupal.theme(settings.modalTheme));
- if (settings.modalSize.type == 'scale') {
- $(window).bind('resize', resize);
- }
}
- 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);
$('#modalContent .modal-content').html(Drupal.theme(settings.throbberTheme));
+ $(window).trigger('resize');
+
// Position autocomplete results based on the scroll position of the modal.
$('#modalContent .modal-content').delegate('input.form-autocomplete', 'keyup', function() {
$('#autocomplete').css('top', $(this).position().top + $(this).outerHeight() + $(this).offsetParent().filter('#modal-content').scrollTop());
@@ -299,6 +270,8 @@
// Attach behaviors within a modal dialog.
var settings = response.settings || ajax.settings || Drupal.settings;
Drupal.attachBehaviors('#modalContent', settings);
+ // Trigger a resize event to make sure modal is in the right place.
+ $(window).trigger('resize');
}
/**
@@ -383,15 +356,6 @@
if ($('#modalBackdrop').length) $('#modalBackdrop').remove();
if ($('#modalContent').length) $('#modalContent').remove();
- // position code lifted from http://www.quirksmode.org/viewport/compatibility.html
- if (self.pageYOffset) { // all except Explorer
- var wt = self.pageYOffset;
- } else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
- var wt = document.documentElement.scrollTop;
- } else if (document.body) { // all other Explorers
- var wt = document.body.scrollTop;
- }
-
// Get our dimensions
// Get the docHeight and (ugly hack) add 50 pixels to make sure we dont have a *visible* border below our div
@@ -404,6 +368,52 @@
// Create our divs
$('body').append('
' + $(content).html() + '
');
+ setSize = function(context) {
+ var width = 0;
+ var height = 0;
+
+ if (Drupal.CTools.Modal.currentSettings.modalSize.type == 'scale') {
+ width = $(window).width() * Drupal.CTools.Modal.currentSettings.modalSize.width;
+ height = $(window).height() * Drupal.CTools.Modal.currentSettings.modalSize.height;
+ }
+ else {
+ width = Drupal.CTools.Modal.currentSettings.modalSize.width;
+ height = Drupal.CTools.Modal.currentSettings.modalSize.height;
+ }
+
+ if (Drupal.CTools.Modal.currentSettings.modalSize.type == 'dynamic') {
+ // Use the additionol pixels for creating the width and height.
+ $('div.ctools-modal-content', context).css({
+ 'min-width': Drupal.CTools.Modal.currentSettings.modalSize.width,
+ 'min-height': Drupal.CTools.Modal.currentSettings.modalSize.height,
+ 'width': 'auto',
+ 'height': 'auto',
+ 'max-height': (winHeight / 2) * 1.8 + 'px',
+ 'max-width': (winWidth / 2) * 1.8 + 'px',
+ 'overflow': 'auto'
+ });
+ $('#modalContent').css({'width': 'auto'});
+ $('div.ctools-modal-content .modal-content', context).css("overflow", "visible");
+ }
+ else {
+ // 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'
+ });
+ $('#modalContent', context).css({
+ 'width': width + Drupal.CTools.Modal.currentSettings.modalSize.addWidth + 'px',
+ 'height': height + Drupal.CTools.Modal.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'
+ });
+ }
+ }
+
+ setSize(document);
+
// Keyboard and focus event handler ensures focus stays on modal elements only
modalEventHandler = function( event ) {
target = null;
@@ -438,10 +448,10 @@
// Create our content div, get the dimensions, and hide it
var modalContent = $('#modalContent').css('top','-1000px');
- var mdcTop = wt + ( winHeight / 2 ) - ( modalContent.outerHeight() / 2);
- var mdcLeft = ( winWidth / 2 ) - ( modalContent.outerWidth() / 2);
+ var mdcTop = Math.max($(document).scrollTop() + ( winHeight / 2 ) - ( modalContent.outerHeight() / 2), 10);
+ var mdcLeft = Math.max(( winWidth / 2 ) - ( modalContent.outerWidth() / 2), 10);
$('#modalBackdrop').css(css).css('top', 0).css('height', docHeight + 'px').css('width', docWidth + 'px').show();
- modalContent.css({top: mdcTop + 'px', left: mdcLeft + 'px'}).hide()[animation](speed);
+ modalContent.css({top: mdcTop + 'px', left: mdcLeft + 'px'}).hide()[animation](speed, function () { /* $(window).trigger('resize'); */ });
// Bind a click for closing the modalContent
modalContentClose = function(){close(); return false;};
@@ -481,7 +491,13 @@
};
// Move and resize the modalBackdrop and modalContent on resize of the window
- modalContentResize = function(){
+ modalContentResize = 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;
+
+ setSize(context);
// position code lifted from http://www.quirksmode.org/viewport/compatibility.html
if (self.pageYOffset) { // all except Explorer
@@ -501,14 +517,37 @@
// Get where we should move content to
var modalContent = $('#modalContent');
- var mdcTop = wt + ( winHeight / 2 ) - ( modalContent.outerHeight() / 2);
- var mdcLeft = ( winWidth / 2 ) - ( modalContent.outerWidth() / 2);
+
+ var height = Math.max(modalContent.outerHeight(), $('div.ctools-modal-content', context).outerHeight());
+ var width = Math.max(modalContent.outerWidth(), $('div.ctools-modal-content', context).outerWidth());
+
+ var mdcTop = Math.max($(document).scrollTop() + ( winHeight / 2 ) - ( height / 2), 10);
+ var mdcLeft = Math.max(( winWidth / 2 ) - ( width / 2), 10);
+
+ // Apply attributes to fix the position of the modal relative to current
+ // position of page. This is required when the modal is larger than the
+ // browser window. This enables the modal to scroll with the rest of the
+ // page, rather than remaining centered in the page whilst scrolling.
+ if (height > $(window).height()) {
+ if (e.type === 'resize') {
+ // Is a resize event so get the position of top relative to current
+ // position of document in browser window.
+ mdcTop = 10 + $(document).scrollTop();
+ }
+ else if (e.type === 'scroll') {
+ // Is a scroll event so mantain to current position of the modal
+ // relative to page.
+ var modalOffSet = modalContent.offset();
+ mdcTop = modalOffSet.y;
+ }
+ }
// Apply the changes
- $('#modalBackdrop').css('height', docHeight + 'px').css('width', docWidth + 'px').show();
+ $('#modalBackdrop').css({'height': winHeight + 'px', 'width': winWidth + 'px', 'top': $(document).scrollTop()}).show();
modalContent.css('top', mdcTop + 'px').css('left', mdcLeft + 'px').show();
};
$(window).bind('resize', modalContentResize);
+ $(window).bind('scroll', modalContentResize);
$('#modalContent').focus();
};
@@ -531,6 +570,7 @@
// Unbind the events we bound
$(window).unbind('resize', modalContentResize);
+ $(window).unbind('scroll', modalContentResize);
$('body').unbind('focus', modalEventHandler);
$('body').unbind('keypress', modalEventHandler);
$('.close').unbind('click', modalContentClose);