/* * Custom jQuery plugin: fs.luxmodal() * Mod by Josh Rencher for FolioSnap (10/22/2008) * Copied from fs.modal() and slightly modded for Lux templates (09/2009) * ===================================================== * Based On: * jQuery blockUI plugin * Version 2.09 (09/16/2008) * @requires jQuery v1.2.3 or later */ (function($) { // Global methods for opening/closing modal window $.modalOpen = function(opts) { install(opts); }; $.modalClose = function(opts) { remove(opts); }; // Default behavior and style (to disable CSS and use external stylesheet, call "$.modalOpen.defaults.css = {};") $.modalOpen.defaults = { // bordered content wrapper wrapper: "" + "" + "" + "" + "" + "
", title: null, // default to null message: null, // default to null padding: 0, // inside display layer, default to 0 css: { padding: 0, // outside display layer, should always be 0 margin: 0, // outside display layer, should always be 0 fontFamily: "Trebuchet MS,Arial,Helvetica,sans-serif", fontSize: "14px", color: "#000000", cursor: "default" }, cssOverlay: { backgroundColor: "#000000", opacity: "0.6", cursor: "default" }, // fadeOut time in milliseconds (set to 0 to disable fadeout on modalClose) fadeOut: 400, // callback method invoked when unblocking has completed; the callback is // passed the element that has been unblocked (which is the window object // for page blocks) and the options that were passed to the unblock call: // onModalClose(element, options) onModalClose: null }; // Set defaults var pageBlock = null; var pageBlockEls = []; // ########## BEG: modalOpen ################################################### function install(opts) { // Merge default options with passed options opts = $.extend({}, $.modalOpen.defaults, opts || {}); opts.css = $.extend({}, $.modalOpen.defaults.css, opts.css || {}); opts.cssOverlay = $.extend({}, $.modalOpen.defaults.cssOverlay, opts.cssOverlay || {}); var msg = opts.message[0]; // expects jQuery object (array), so grab zero-index // Remove any existing blocks if(pageBlock) remove({fadeOut:0}); // If an existing element is being used as the modal content, capture // its current place and display style in the DOM so we can restore it. if(msg.parentNode || msg.jquery) { var node = msg; var data = {}; $(window).data("modalOpen.history", data); data.element = node; data.parent = node.parentNode; data.display = node.style.display; data.position = node.style.position; data.parent.removeChild(node); } var z = 20; // base Z-index for modal layers // Three layers are used for modal (regardless of platform for simplicity's sake) // LAYER ONE: iframe layer used to supress bleed through of underlaying content in IE // LAYER TWO: overlay layer to dim page and prevent interaction outside of modal // LAYER THREE: display layer to show modal contents var lyr1 = ($.browser.msie) ? $('') : $(''); var lyr2 = $('
'); var lyr3 = $('
'); // Apply style to display layer if(msg) lyr3.css(opts.css); // Apply style to overlay layer (except Firefox on Linux, due to opacity issues) if(!($.browser.mozilla && /Linux/.test(navigator.platform))) lyr2.css(opts.cssOverlay); lyr2.css("position","fixed"); // Apply transparency to iframe layer (IE only) if($.browser.msie) lyr1.css("opacity","0"); // Add all layers to page () //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo("body"); var layers = [lyr1,lyr2,lyr3]; $.each(layers, function() { this.appendTo( $("body") ); }); // UPDATED 10/18/10 for compatibility with jQuery 1.4.x // ********** BEG: IE FIXES ************************************************** // IE7 must use absolute positioning in quirks mode. Must also account for activex issues when scrolling. var ie6 = $.browser.msie && /MSIE 6.0/.test(navigator.userAgent); var expr = $.browser.msie && (!$.support.boxModel || $("object,embed").length > 0); if(ie6 || expr) { // 1) Give body 100% height if($.support.boxModel) $("html,body").css("height","100%"); // why only in non-quirks mode (when $.support.boxModel true)? // 2) Simulate fixed position $.each([lyr1,lyr2,lyr3], function(i,o) { var thisstyle = o[0].style; thisstyle.position = "absolute"; if(i < 2) { //thisstyle.setExpression("height","Math.max(document.body.scrollHeight, document.body.offsetHeight) - ($.support.boxModel ? 0 : 4) + \"px\""); //thisstyle.setExpression("width","$.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + \"px\""); // changed on 1/19/11 due to 'not implemented' error in IE8 thisstyle.height = Math.max(document.body.scrollHeight, document.body.offsetHeight) - ($.support.boxModel ? 0 : 4) + "px"; thisstyle.width = ($.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"); } }); } // ********** END: IE FIXES ************************************************** // Add wrapper to display layer, add modal contents to wrapper var modalwrapper = $(opts.wrapper); lyr3.append(modalwrapper); if(!opts.title) $(".fsmodal-titlerow").hide(); else $(".fsmodal-title").append(opts.title); if(!opts.padding) $(".fsmodal-inner").append(msg.innerHTML); else $(".fsmodal-inner").css("padding",opts.padding).append(msg.innerHTML); // Center horizontally var winWidth = $(window).width(); var mWidth = $(".fsmodalview").width() + 20; // twice left/right padding and border (adjust as needed) var mLeft = Math.ceil((winWidth - mWidth) / 2); $(".fsmodalview").css("left",mLeft+"px"); // Center vertically var winHeight = $(window).height(); var mHeight = $(".fsmodalview").height() + 30; // twice top/bottom padding and border (adjust as needed) var mTop = Math.ceil((winHeight - mHeight) / 2); // ADD RULE TO RE-SET mTOP BASED ON HEIGHTS! $(".fsmodalview").css("top",mTop+"px"); // Show display layer lyr3.show(); // Bind key and mouse events bind(1,opts); pageBlock = lyr3[0]; pageBlockEls = $(":input:enabled:visible",pageBlock); setTimeout(focus, 20); }; // ########## END: ENABLE BLOCK ################################################ // ########## BEG: REMOVE BLOCK ################################################ function remove(opts) { var data = $(window).data("modalOpen.history"); opts = $.extend({}, $.modalOpen.defaults, opts || {}); bind(0,opts); // unbind events var els = $("body").children().filter(".fsmodal"); //pageBlock = pageBlockEls = null; pageBlock = null; pageBlockEls = null; if(opts.fadeOut) { els.fadeOut(opts.fadeOut); setTimeout(function() { reset(els,data,opts); }, opts.fadeOut); } else reset(els,data,opts); }; // ########## END: REMOVE BLOCK ################################################ // RESET: Move blocking element back into the DOM where it started function reset(els,data,opts) { els.each(function(i,o) { // remove via DOM calls so we don't lose event handlers if(this.parentNode) this.parentNode.removeChild(this); }); if(data && data.element) { data.element.style.display = data.display; data.element.style.position = data.position; data.parent.appendChild(data.element); $(data.element).removeData("modalOpen.history"); } if(typeof opts.onModalClose == "function") opts.onModalClose(opts); }; // BIND: Bind (b=1) or unbind (b=0) the event handler function bind(b,opts) { // don't bother unbinding if there is nothing to unbind if(!b && !pageBlock) return; // bind anchors and inputs for mouse and key events var events = "mousedown mouseup keydown keypress click"; b ? $(document).bind(events,opts,handler) : $(document).unbind(events,handler); }; // HANDLER: Suppress keyboard/mouse events when blocking function handler(e) { // allow tab navigation (conditionally) if(e.keyCode && e.keyCode == 9) { if(pageBlock) { var els = pageBlockEls; var fwd = !e.shiftKey && e.target == els[els.length-1]; var back = e.shiftKey && e.target == els[0]; if(fwd || back) { setTimeout(function() { focus(back) }, 10); return false; } } } // allow events within the message content if($(e.target).parents("div.fsmodalview").length > 0) return true; // allow events for content that is not being blocked return $(e.target).parents().children().filter("div.fsmodal").length == 0; }; // FOCUS: Auto-set focus to first input element (if any) function focus(back) { if(!pageBlockEls) return; var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0]; if(e) e.focus(); }; })(jQuery);