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 5b417d0..8e1a1a6 100644 --- a/js/modal.js +++ b/js/modal.js @@ -9,6 +9,7 @@ */ (function ($) { + // Make sure our objects are defined. Drupal.CTools = Drupal.CTools || {}; Drupal.CTools.Modal = Drupal.CTools.Modal || {}; @@ -32,7 +33,7 @@ var defaults = { modalTheme: 'CToolsModalDialog', throbberTheme: 'CToolsModalThrobber', - animation: 'show', + animation: 'fadeIn', animationSpeed: 'fast', modalSize: { type: 'scale', @@ -61,44 +62,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'); }; /** @@ -282,6 +255,8 @@ // content. This is helpful for allowing users to see error messages at the // top of a form, etc. $('#modal-content').html(response.output).scrollTop(0); + // Trigger a resize event to make sure modal is in the right place. + $(window).trigger('resize'); Drupal.attachBehaviors(); } @@ -367,15 +342,6 @@ if ( $('#modalBackdrop')) $('#modalBackdrop').remove(); if ( $('#modalContent')) $('#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 @@ -388,6 +354,48 @@ // 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' + }); + $('#modalContent').css({'width': 'auto'}); + } + 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; @@ -417,10 +425,11 @@ // 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;}; @@ -460,7 +469,14 @@ }; // 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); + // Get our heights var docHeight = $(document).height(); var docWidth = $(document).width(); @@ -470,14 +486,38 @@ // Get where we should move content to var modalContent = $('#modalContent'); - var mdcTop = ( 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(); }; @@ -500,6 +540,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);