/*
* jQuery Frame Dialog 1.1.2
*
* Copyright (c) 2009 SolutionStream.com & Michael J. Ryan (http://www.solutionstream.com/)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* Requires:
* jquery ui dialog
*
* jQuery.FrameDialog namespaced
* .create() function will create an iframe, pass on the options
* and return from a jQueryUI Dialog.
* additional url option
*
* TODO: - Add logic to allow for relative URLs.
*
* CUSTOMIZATION:
* see FrameDialog._defaultOptions below for additional changes from ui dialog defaults
* Returns a jQuery.dialog extension, with the same options passed in.
*
* refer to jQueryUI Dialog for more customization options
*
*
* LOCALIZATION: create a window.localization object
* localization.OK override text for the OK button
* localization.Cancel override text for the Cancel button
*
*
* FROM PARENT WINDOW: use the full url, including protocol://host/ portions
* jQuery.FrameDialog
* .create({
* url: baseURL + 'framed-modal-test.aspx',
* title: 'test title',
* ... Other jQueryUI Dialog Options ...
* })
* .bind('dialogclose', function(event, ui) {
* alert("result: " + event.result);
* });
*
* INSIDE MODAL:
* jQuery.FrameDialog.setResult(value); //sets the result value
* jQuery.FrameDialog.clearResult(); //clears the result value
* jQuery.FrameDialog.closeDialog(); //close the dialog (same as OK)
* jQuery.FrameDialog.cancelDialog(); //cancel the dialot (same as Cancel
*
*
*
* !!!!!!!!!! WARNING WARNING WARNING WARNING !!!!!!!!!!
* Modal must set the result from the same host address in order to access
* the parent for setting the result.
*/
(function($) {
//create FrameDialog namespace
$.FrameDialog = $.FrameDialog || {};
//array for return values, placeholder
$.FrameDialog._results = $.FrameDialog._results || {};
$.FrameDialog._arguments = $.FrameDialog._arguments || {};
$.FrameDialog._frames = $.FrameDialog._frames || [];
//set localized variables
var OK = (window.localization && window.localization.OK) || "OK";
var Cancel = (window.localization && window.localization.CANCEL) || "Cancel";
var buttons = {};
//remove default button
// buttons[OK] = function() {
// $(this).dialog("close");
// }
// buttons[Cancel] = function() {
// var frame = $(this);
// $.FrameDialog.clearResult(frame.attr("id"));
// frame.dialog("close");
// }
//default options
$.FrameDialog._defaultOptions = {
modal: true,
closeOnEscape: false,
position: 'center',
buttons: buttons
};
var retry = false;
$.FrameDialog.create = function(options) {
try {
//generate unique id
var uid = Math.random().toString(16).replace(".", "") + (new Date()).valueOf().toString(16);
//extend frame dialog options with passed in options.
var opts = $.extend(
$.FrameDialog._defaultOptions,
options || {}
);
var url = (opts && opts.url) || null;
if (url === null)
throw new Error("MODAL ERROR: Option 'url' not specified!"); //diagnostic error
//clean up redundant forward slashes in the url.
url = url.replace(/(^|[^:])\/+/g, "$1/");
//remove url argument from options to be passed to dialog.
try {
delete opts.url;
} catch (err) { }
// set arguments
$.FrameDialog._arguments[uid] = opts.args;
$.FrameDialog._frames.push(uid);
//create iframe object
// object type="text/html doesn't seem to work in IE :(
// using iframe, which seems to work cross browser, tested in IE7, and Firefox 3.0.7
var iframe = $("")
.attr("id", uid + "-VIEW")
.attr("name", uid + "-VIEW")
.attr("src", url)
.css("margin", "0")
.css("border", "0")
.css("padding", "0")
.css("top", "0")
.css("left", "0")
.css("right", "0")
.css("bottom", "0")
.css("width", "100px")
.css("height", "100px")
;
var overlay = $("
")
.css("position", "absolute")
.css("margin", "0")
.css("border", "0")
.css("padding", "0")
.css("top", "0")
.css("left", "0")
.css("right", "0")
.css("bottom", "0")
.css("width", "100%")
.css("height", "100%")
.css("display", "none")
;
var ret = $("")
.attr("id", uid)
.css("margin", "0")
.css("border", "0")
.css("padding", "0")
.css("top", "0")
.css("left", "0")
.css("right", "0")
.css("bottom", "0")
.css("overflow", "hidden")
.hide()
.append(iframe)
.append(overlay)
// .appendTo(opts.container ? opts.container : document.body)
.bind("dialogbeforeclose", function(event, ui) {
var frame = $(this);
var uid = frame.attr("id");
//default close (firefox) - clear response
if (event && event.originalTarget && event.originalTarget.nodeName && event.originalTarget.nodeName == "SPAN")
$.FrameDialog.clearResult(uid);
//default close (IE7) - clear response
if (event && event.originalEvent && event.originalEvent.currentTarget && event.originalEvent.currentTarget.tagName && event.originalEvent.currentTarget.tagName == "A")
$.FrameDialog.clearResult(uid);
//get the response value, attach to the object.
var result = $.FrameDialog._results[uid] || null; //result or an explicit null
return result;
})
.bind('dialogclose', function(event, ui) {
var frame = $(this);
var uid = frame.attr("id");
iframe.attr("src", ""); // 1.IE memory leak
var result = $.FrameDialog._results[uid]; //result or an explicit null
frame.attr("result", result);
//cleanup the dialog
frame.dialog('destroy');
//destroy the iframe, remove from the DOM
iframe.remove(); // 2.IE memory leak
frame.remove();
overlay.remove();
ret.remove();
frame = null; // 3.IE memory leak
//remove the placeholder for the result
try {
delete $.FrameDialog._results[uid];
delete $.FrameDialog._arguments[uid];
// 移除frames数组
var array = $.FrameDialog._frames;
var index = jQuery.inArray(uid, array);
if (index > -1) {
$.FrameDialog._frames.splice(index, 1);
}
iframe = null;
} catch (err) { /*nothing to delete*/ }
//Cleanup remnants in 15 seconds
// Should be enough time for the results of the close to finish up.
// window.setTimeout(
// // 清空对象
// function() {
// //cleanup the dialog
// frame.dialog('destroy');
//
// //destroy the iframe, remove from the DOM
// iframe.remove(); // 2.IE memory leak
// frame.remove();
// overlay.remove();
// ret.remove();
//
// frame = null; // 3.IE memory leak
// //remove the placeholder for the result
// try {
// delete $.FrameDialog._results[uid];
// delete $.FrameDialog._arguments[uid];
// // 移除frames数组
// var array = $.FrameDialog._frames;
// var index = jQuery.inArray(uid, array);
// if (index > -1) {
// $.FrameDialog._frames.splice(index, 1);
// }
//
// iframe = null;
// } catch (err) { /*nothing to delete*/ }
// },
// 100
// );
return result;
})
.dialog(opts);
/*** BEGIN FIX FOR jQueryUI 1.7 Dialog's sizing bug *************************************************/
//store the window width at the start
var winw = $(document).width();
var winh = $(document).height();
var wrap = ret.parent(".ui-resizable");
//set the window to the appropriate size - fix bug with jQueryUI's Dialog
// uses an overlay over the iframe, to prevent focus change.
wrap.css('width', (opts.minWidth || opts.width || 200) + 'px')
.css('height', (opts.minHeight || opts.height || 120) + 'px')
.bind('dragstart', function() {
overlay.show();
})
.bind('dragstop', function() {
overlay.hide();
})
.bind('resizestart', function() {
overlay.show();
})
.bind('resize', function() {
var height = $(this).height()-50;
var width = $(this).width();
// 根据div调整高度、宽度
//ret.css('height', height + 'px').css('width', width + 'px');
//iframe.css('height', height + 'px').css('width', width + 'px');
ret.css('height','90%').css('width','100%');
iframe.css('height','100%').css('width','100%');
})
.bind('resizestop', function() {
overlay.hide();
var height = $(this).height()-50;
var width = $(this).width();
// 根据div调整高度、宽度
//ret.css('height', height + 'px').css('width', width + 'px');
//iframe.css('height', height + 'px').css('width', width + 'px');
ret.css('height','90%').css('width','100%');
iframe.css('height','100%').css('width','100%');
});
//force resize event.
window.setTimeout(function(){
wrap.trigger('resizestop');
}, 100);
//get window's new width
var ww = wrap.width();
var wh = wrap.height();
//reset the center position, if needed
if (opts.position == 'center' || (opts.position && (opts.position[0] == 'center' || opts.position[1] == 'center'))) {
// 默认居中显示
var pos = parseInt(parseFloat(winw - ww) / 2);
var top = parseInt(parseFloat(winh - wh) / 2)+$(document).scrollTop();
if (pos < 0) pos = 0;
if (top < 0) top = 0;
wrap.css('left', pos + 'px');
wrap.css('top', top + 'px');
}
//reset right position, as needed
if (opts.position == 'right' || (opts.position && (opts.position[0] == 'right' || opts.position[1] == 'right'))) {
var pos = winw - ww - 5; //set to rightmost, - 5 px
if (pos < 0) pos = 0;
wrap.css('left', pos + 'px');
}
/*** END FIX FOR jQueryUI 1.7 Dialog's sizing bug *************************************************/
retry = false; //reset the retry state.
return ret;
} catch (err) {
//cleanup any left over ui elements...
try { ret.dialog('destroy'); } catch(err) {}
try { ret.remove(); } catch(err) {}
try { overlay.remove(); } catch(err) {}
try { iframe.remove(); } catch(err) {}
//it was a TypeError (seems to be happening with the modal's overlay mask, retry once.
if (err instanceof TypeError && !retry) {
retry = true;
return $.FrameDialog.create(options); //retry once only
}
throw err; //rethrow error if something else
}
};
//retrieves the uid for the current frame within the parent.
$.FrameDialog._getUidOld = function() {
//find the current frame within the parent window
if (window.parent && window.parent.frames && window.parent.document && window.parent.document.getElementsByTagName) {
var iframes = window.parent.document.getElementsByTagName("IFRAME");
for (var i = 0; i < iframes.length; i++) {
var id = iframes[i].id || iframes[i].name || i;
if (window.parent.frames[id] == window) {
return id.replace("-VIEW", "");
}
}
}
return null; //no match
};
var templocation = "";
/**
* 向上递归获取Dialog打开者uid
*/
$.FrameDialog._getUid = function(){
var opener = $.FrameDialog._getOpener();
if (opener && opener.jQuery && opener.jQuery.FrameDialog) {
var array = opener.jQuery.FrameDialog._frames;
if (array.length > 0) {
var id = array[array.length - 1];
return id;
}
}
return "";
};
/**
* 向上递归获取打开者
*/
$.FrameDialog._getOpener = function(){
var opener = window;
while (opener) {
// 向上递归第一个_frames长度大于0的为打开窗口
if (opener.jQuery && opener.jQuery.FrameDialog && opener.jQuery.FrameDialog._frames.length > 0){
return opener;
} else if(opener == window.top){
break;
}
opener = opener.parent;
}
return null; //no match
};
//Returns the current dialog handle in the parent window as a jquery object.
$.FrameDialog.current = function() {
if (window.parent && window.parent.jQuery)
return window.parent.jQuery("#" + $.FrameDialog._getUid());
return null;
};
//clear the result value
// uid - id for child window, or empty for current in parent.
$.FrameDialog.clearResult = function(uid) {
if (uid) {
//clear child's value
try {
delete $.FrameDialog._results[uid];
} catch (err) { /*nothing to delete*/ }
} else {
//clear for current dialog
var uid = $.FrameDialog._getUid();
var opener = $.FrameDialog._getOpener();
if (uid != null && opener && opener.jQuery && opener.jQuery.FrameDialog && opener.jQuery.FrameDialog._results) {
try {
delete opener.jQuery.FrameDialog._results[uid];
} catch (err) { /*nothing to delete*/ }
}
}
};
$.FrameDialog.getArguments = function(uid) {
if (uid) {
//set child value
return jQuery.FrameDialog._arguments[uid];
} else {
//set value from inside
var uid = $.FrameDialog._getUid();
var opener = $.FrameDialog._getOpener();
if (uid != null && opener && opener.jQuery && opener.jQuery.FrameDialog && opener.jQuery.FrameDialog._arguments) {
return opener.jQuery.FrameDialog._arguments[uid];
}
}
};
//helper function to set response value to the parent
// value - result value for the given FrameDialog
// uid - child id, or empty for current FrameDialog
$.FrameDialog.setResult = function(value, uid) {
if (uid) {
//set child value
jQuery.FrameDialog._results[uid] = value;
} else {
//set value from inside
var uid = $.FrameDialog._getUid();
var opener = $.FrameDialog._getOpener();
if (uid != null && opener && opener.jQuery && opener.jQuery.FrameDialog && opener.jQuery.FrameDialog._results) {
opener.jQuery.FrameDialog._results[uid] = value;
}
}
};
//same as clicking OK button
// uuid - for a child node, or empty for current
$.FrameDialog.closeDialog = function(uid) {
if (uid) {
//close child
jQuery("#" + uid).dialog('close');
} else {
//close self
var uid = $.FrameDialog._getUid();
var opener = $.FrameDialog._getOpener();
if (uid != null && opener && opener.jQuery) {
opener.jQuery("#" + uid).dialog('close');
}
}
return false;
};
$.FrameDialog.resize = function(width, height, left , top, uid) {
if (uid) {
var wrap = jQuery("#" + uid).parent(".ui-resizable");
//resize child
if (width > -1) {
wrap.css('width', width + 'px');
}
if (height > -1) {
wrap.css('height', height + 'px');
}
if(left>=0 && typeof left!="string"){
//var dleft=parseInt(parseFloat(cWidth - width) / 2);
wrap.css('left', left + 'px');
}
if(top>=0 && typeof top!="string"){
//var dheight=parseInt(parseFloat(cHeight - height) / 2);
wrap.css('top', top + 'px');
}
} else {
var uid = $.FrameDialog._getUid();
var opener = $.FrameDialog._getOpener();
if (uid != null && opener && opener.jQuery && opener.jQuery.FrameDialog) {
var wrap = opener.jQuery("#" + uid).parent(".ui-resizable");
//resize self
if (width > -1) {
wrap.css('width', width + 'px');
}
if (height > -1) {
wrap.css('height', height + 'px');
}
if(left>=0 && typeof left!="string"){
//var dleft=parseInt(parseFloat(cWidth - width) / 2);
wrap.css('left', left + 'px');
}
if(top>=0 && typeof top!="string"){
//var dheight=parseInt(parseFloat(cHeight - height) / 2);
wrap.css('top', top + 'px');
}
}
}
};
//same as clicking Cancel button
// uid - for a child node, or empty for current frame
$.FrameDialog.cancelDialog = function(uid) {
$.FrameDialog.clearResult(uid);
$.FrameDialog.closeDialog(uid);
return false;
};
//extension methods for shortcuts in dealing with a framedialog handle
$.fn.setResult = function(result) {
return this.each(function() {
$.FrameDialog.setResult(result, $(this).attr("id"));
});
};
$.fn.clearResult = function() {
return this.each(function() {
$.FrameDialog.clearResult($(this).attr("id"));
});
};
$.fn.closeDialog = function() {
return this.dialog('close');
};
$.fn.cancelDialog = function() {
return this.clearResult().closeDialog();
};
//get the window context for the object/iframe in question
$.fn.window = function() {
//this item is a frame or iframe
if (this.attr('tagName') == "IFRAME" || this.attr('tagName') == "FRAME")
return window.frames[this.attr('name') || this.attr('id')];
//get the first frame/iframe child
var frame = this.find('iframe, frame')[0];
return (frame && window.frames[frame.name || frame.id]) || null;
};
})(jQuery);