;
(function ($) {
var otherButton = [];
var d = $("<div style='position:absolute;top:-1000px;width:100px;height:100px;padding:5px'></div>").appendTo("body");
$._boxModel = parseInt(d.width()) === 100;
d.remove();
$.fn._outerWidth = function (el) {
if (el == undefined) {
if (this[0] == window) {
return this.width() || document.body.clientWidth;
}
return this.outerWidth() || 0;
}
return this.each(function () {
if ($._boxModel) {
$(this).width(el - ($(this).outerWidth() - $(this).width()));
} else {
$(this).width(el);
}
});
};
$.fn._outerHeight = function (el) {
if (el == undefined) {
if (this[0] == window) {
return this.height() || document.body.clientHeight;
}
return this.outerHeight() || 0;
}
return this.each(function () {
if ($._boxModel) {
$(this).height(el - ($(this).outerHeight() - $(this).height()));
} else {
$(this).height(el);
}
});
};
/**
* 面板容器
*
* @example
* var $root = $("<div>").css({position:'absolute',top:5,left:10}).appendTo('body');
* var p = new FR.Panel({
* renderEl : $root,
* contentHtml : "Hello",
* width : 300,
* height : 100,
* title : "Test",
* border : true,
* doSize : true,
* closable : true
* });
*
* @class FR.Panel
* @extends FR.Widget
* @since 6.5.3
*
* @cfg {JSON} options 配置属性
* @cfg {Number} [options.titleHeight=25] 标题高度(如果有标题)
* @cfg {String} [options.headerBackground=null] 标题背景色
* @cfg {Number/String} [options.borderRadius=false] 边框的圆角
* @cfg {Boolean} [options.fit=false] 是否根据父容器自适应大小
* @cfg {Boolean} [options.doSize=true] 是否需要在初始化的时候计算大小
* @cfg {Boolean} [options.border=false] 是否需要边框
* @cfg {Number} [options.borderWidth=1] 边框宽度,仅在border=true时生效。
* @cfg {Boolean} [options.closable=false] 是否需要关闭按钮
* @cfg {Boolean} [options.maximizable=false] 是否可以最大化
* @cfg {Boolean} [options.minimizable=false] 是否可以最小化
* @cfg {Boolean} [options.collapsible=false] 是否可以收缩和下拉
* @cfg {Boolean} [options.autoScroll=true] 是否根据内容的多少自动显示滚动条
* @cfg {Boolean} [options.closed=false] 初始化完成以后是否直接显示组件
* @cfg {Boolean/Number} [options.animate=true] 显示和隐藏的时候是否需要动画效果,参数可以为一个整数表示动画持续的时间
* @cfg {Number} [options.width=300] 控件的初始宽度
* @cfg {Number} [options.height=200] 控件的初始高度
* @cfg {String} [options.contentUrl=null] 容器内容(从给定的服务器地址获取。注意:该url不能跨域)
* @cfg {String} [options.contentHtml=null] 容器内容(html文本)
* @cfg {String} [options.contentText=null] 容器内容(普通文本)
* @cfg {FR.Widget} [options.contentWidget=null] 容器内容(控件)
* @cfg {"blue"/"green"/"gray"} [options.style="blue"] 控件的样式
* @cfg {Array} [options.tools] 控件的工具栏按钮组,可以设置按钮的样式,宽度以及事件
* @cfg {Number} [options.tools.width=24] 按钮的宽度
* @cfg {String} options.tools.iconCls 按钮的css样式表
* @cfg {Boolean} [options.tools.invisible=false] 按钮的不可见性
* @cfg {String} options.tools.text 按钮上的文字
* @cfg {Function} options.tools.handler 按钮点击时触发的事件
*/
FR.Panel = FR.extend(FR.Widget, {
_defaultConfig: function () {
return $.extend(FR.Panel.superclass._defaultConfig.apply(this, arguments), {
baseCls: "fr-core-panel", // 基本样式
titleHeight: 25, // 标题栏的高度
headerBackground: null,
borderRadius: false, // 边框的圆角
fit: false, // 是否根据父容器自适应大小
doSize: true, // 是否需要再初始化的时候计算大小
border: false, // 是否需要边框
borderWidth: 1, // 边框宽度
closable: false, // 是否需要关闭按钮
maximizable: false, // 是否可以最大化
minimizable: false, // 是否可以最小化
collapsible: false, // 是否可以收缩和下拉
autoScroll: true, // 是否根据内容的多少自动显示滚动条
closed: false, // 初始化完成以后是否直接显示组件
animate: true, // 显示和隐藏的时候是否需要动画效果,参数可以为一个整数表示动画持续的时间
width: 300, // 控件的初始宽度
height: 200, // 控件的初始高度
tools: null, // 控件的工具栏按钮,可以设置按钮的样式,宽度以及事件
style: null // 控件的样式,默认为blue,具有blue,green以及gray共3种样式
});
},
_init: function () {
var o = this.options;
this.headerHeight = (!FR.isEmpty(o.title)) ? o.titleHeight : (o.miniExpand ? 8 : 0);
// wei : 如果panel有可收缩的工具栏,那么先调整下它的高度。
// 这里得考虑下传过来的o.height是不是"auto"或者百分比
if (typeof o.height == 'number') {
o.height += (!FR.isEmpty(o.title)) ? o.titleHeight : 0;
}
FR.Panel.superclass._init.apply(this, arguments);
var self = this;
var defaultStyle = "blue";
$.each(["gray", "green", "blue"], function (i, item) {
if (o.style && item == o.style.toLowerCase()) {
defaultStyle = o.style.toLowerCase();
}
});
o.style = defaultStyle;
this.element.addClass(o.baseCls);
// 注意,这里需要先调用_addContent(),再调用_addHeader()方法
this._addContent();
if ((typeof o.height == 'number' && o.height > this.headerHeight) || typeof o.height != 'number') {
this._addHeader();
}
this._addBorder();
// 注意:必须要先doResize才能关闭,否则无法正确计算宽度和高度
if (o.doSize === true) {
this.doResize({
width: o.width,
height: o.height
});
}
if (o.closed === true) {
this.element.hide();
}
if (o.css) {
this.element.css(o.css);
}
this.on("_resize", function () {
if (self.options._resize) {
self.options._resize();
}
})
},
/**
* autoScroll:是否显示panel内容的滚动条 url:数据加载有地址 html:包含html标签的内容 text:普通文本内容
* url,html和text三种数据获取方式只能选一种
* @private
*/
_addContent: function () {
var opts = this.options;
// 先给panel的content套一层标识
var top = FR.isEmpty(opts.title) ? 0 : opts.titleHeight;
/**
* @property {jQuery} panelBody 容器内容所在的dom
*/
this.panelBody = $('<div class="fr-core-panel-body"></div>').css({
position: 'absolute',
top: top,
left: 0
}).appendTo(this.element);
/**
* @property {jQuery} $contentPane 容器内容所在的dom
*/
this.$contentPane = this._createContentPane();
this._loadContent(false);
},
/**
* @private
*/
_createContentPane: function () {
if (this.options.autoScroll === false) {
this.panelBody.css({
overflow: 'hidden'
});
}
return this.panelBody;
},
/**
* @private
*/
_addBorder: function () {
var o = this.options;
if (o.border === true) {
// 如果没有标题,那么样式也就没有意义了,所以这里不用加载css,只在有标题的时候加载css
if (this.$header) {
* @property {jQuery} $header 标题所在的dom元素
*/
this.$header.removeClass('fr-core-panel-header-noborder');
}
this.borderFix4width = o.borderWidth * 2;
this.borderFix4height = o.borderWidth * 2;
this.panelBody
.addClass("fr-core-panel-body-border")
.removeClass('fr-core-panel-body-noborder')
.css({borderWidth: o.borderWidth});
if (!FR.isEmpty(o.title)) {
this.borderFix4height = o.borderWidth;
this.panelBody.css({
borderTop: 'none'
});
}
} else {
if (this.$header) {
this.$header
.addClass('fr-core-panel-header-noborder');
}
this.panelBody
.removeClass('fr-core-panel-body-border')
.addClass('fr-core-panel-body-noborder');
}
},
_loadContent: function (forced) {
var opts = this.options;
var ct = this.$contentPane;
// url不为空,需要强制加载或者还没有加载过时使用ajax异步加载内容
if (opts.contentUrl && (!opts.isLoaded || forced === true)) {
opts.isLoaded = false;
ct.html($('<div class="fr-core-panel-loading"></div>')
.html("loading..."));
FR.ajax({
url: opts.contentUrl,
type: "POST",
complete: function (res, status) {
var ht = res.responseText;
if ($.isFunction(opts.callback)) {
opts.callback(ct, ht);
} else {
ct.html(ht);
}
opts.isLoaded = true;
}
});
} else if (opts.contentWidget) {
if (opts.contentWidget.type) {
opts.contentWidget.style = opts.style;
opts.contentWidget = FR.createWidget(opts.contentWidget);
}
$.extend(opts.resultWidgets, opts.contentWidget.options.resultWidgets);
ct.append(opts.contentWidget.element);
} else if (opts.contentHtml) {
ct.html(opts.contentHtml);
if (typeof opts.contentHtml === 'object') {
var newEl = $(opts.contentHtml)[0];
//wikky:$(newEl)如果hide后然后show,由于$loading的原因,会导致IE9的标准模式下$(newEl)大小为100*100。
if (newEl.tagName == 'IFRAME') {
// $(newEl).hide();
var topHeight = FR.isEmpty(opts.title) ? 0 : opts.titleHeight;
var loadTop = topHeight - opts.height;
var $loading = $('<div class="fr-core-panel-loading" style="position: relative"></div>')
.css({
width: opts.width,
height: 30,
top: loadTop
}).html(FR.i18nText("FR-Basic_Loading") + "...");
if (!opts.noLoading) {
ct.append($loading);
}
if (newEl.attachEvent) {
newEl.attachEvent("onload", function () {
// $(newEl).show();
$loading.remove();
});
} else {
newEl.onload = function () {
// $(newEl).show();
$loading.remove();
};
}
}
}
} else if (opts.contentText) {
ct.text(opts.contentText);
}
},
* title : 标题 tools : 自定义的工具栏 closable : 是否可关闭 maximizable : 是否可最大化
* minimizable :是否可最小化 collapsible : 是否可收缩与伸展 miniExpand : 只带箭头的收缩按钮
* @private
*/
_addHeader: function () {
var self = this;
var opts = this.options;
if (!FR.isEmpty(opts.title)) {
this.$header = $('<div class="fr-core-panel-header"></div>')
.addClass("fr-core-panel-style-" + opts.style)
.css({
position: 'absolute',
top: 0,
left: 0
}).appendTo(this.element);
if (!opts.borderRadius) {
this.$header.css({borderRadius: 0});
}
if (opts.headerBackground) {
this.$header.css({background: opts.headerBackground});
}
var fix = $.support.boxModel ? 2 : 0;
this.$innerHeader = $('<div class="fr-core-panel-header-inner"></div>').css({
position: 'absolute',
top: 0,
left: 0
}).appendTo(this.$header);
this.$titleText = $('<div></div>')
.text(opts.title)
.addClass('fr-core-panel-title')
.appendTo(this.$innerHeader);
this.rightDistance = 7;
if (opts.closable) {
$('<div class="fr-core-panel-tool-close"></div>')
.css({
position: 'absolute',
top: 0,
right: this.rightDistance,
width: 25,
height: opts.titleHeight - fix
})
.mouseout(function () {
$(this).removeClass("fr-core-panel-tool-close-hover")
.removeClass("fr-core-panel-tool-close-down")
.removeClass("fr-core-panel-tool-over")
.addClass("fr-core-panel-tool-close");
}).mousedown(function (e) {
//Sean:这里要取消冒泡,否则点击关闭按钮时会触发拖动。
//wei:没什么影响,就不取消冒泡了,不然定义在document上的下拉菜单收起事件就不执行了。
$(this).removeClass("fr-core-panel-tool-close-hover")
.addClass("fr-core-panel-tool-close-down");
// e.stopEvent();
}).mouseover(function () {
$(this).removeClass("fr-core-panel-tool-close")
.addClass("fr-core-panel-tool-over")
.addClass("fr-core-panel-tool-close-hover");
}).bind("click", function () {
self.doClose();
}).appendTo(this.$innerHeader);
this.rightDistance += 24;
}
if (opts.tools) {
for (var i = opts.tools.length - 1; i >= 0; i--) {
var item = opts.tools[i];
var itemWidth = item.width || 24,
itemHeight = item.height || opts.titleHeight - fix;
var t = $('<div></div>').css({
position: 'absolute',
top: 0,
width: itemWidth,
height: itemHeight,
lineHeight: itemHeight + 'px'
}).addClass(item.iconCls).hover(function () {
$(this).addClass("fr-core-panel-tool-over");
$(this).addClass(item.iconCls + "-over");
}, function () {
$(this).removeClass("fr-core-panel-tool-over");
$(this).removeClass(item.iconCls + "-over");
}).mousedown(function () {
$(this).addClass(item.iconCls + '-click');
}).mouseleave(function () {
$(this).removeClass(item.iconCls + '-over');
$(this).removeClass(item.iconCls + '-click');
}).mouseup(function () {
$(this).removeClass(item.iconCls + '-click');
})
.appendTo(this.$innerHeader);
item.el = t;
item.width = itemWidth;
if (item.invisible) {
t.hide();
}
if (item.handler) {
if ($.isFunction(item.handler)) {
t.bind('click', item.handler.createDelegate(t));
} else if (typeof(item.handler) === 'object') {
//扩展成可以将click动作拆分成3个动作,这样可以满足实现tool的点击效果。
if ($.isFunction(item.handler.mousedown)) {
t.mousedown(item.handler.mousedown.createDelegate(t));
}
if ($.isFunction(item.handler.mouseleave)) {
t.mouseleave(item.handler.mouseleave.createDelegate(t));
}
if ($.isFunction(item.handler.mouseup)) {
t.mouseup(item.handler.mouseup.createDelegate(t));
}
} else {
t.bind('click', eval(item.handler));
}
}
if ($.isArray(item.hover) && item.hover.length > 1) {
t.hover(item.hover[0].createDelegate(t), item.hover[1].createDelegate(t));
}
if (item.text) {
t.text(item.text);
}
if (item.styleText) {
FR.applyStyles(t, item.styleText);
}
}
this._modifyToolsPosition();
}
this.panelBody.removeClass('fr-core-panel-body-noheader');
} else if (opts.miniExpand) {
var header = $("<div class='parameter-container-collapse'></div>")
.appendTo(self.element);
header.css({
position: 'absolute',
top: opts.height - 8,
left: 0,
'width': '100%',
'height': '8px',
'background': 'none repeat scroll 0 0 #EEEEEE'
});
var collapseImagWrapper = $("<div/>").css({
width: '112px',
height: '8px',
'margin-left': 'auto',
'margin-right': 'auto',
'position': 'relative'
}).appendTo(header);
var collapseImag = $("<div class='parameter-container-collapseimg-up'/>")
.appendTo(collapseImagWrapper)
.click(eval(opts.miniExpand.handler));
} else {
this.panelBody.addClass('fr-core-panel-body-noheader');
}
},
/**
* 设置面板容器的标题
* @param {String} title 要设置的新的标题
*/
setTitle: function (title) {
if (this.$innerHeader) {
this.$innerHeader.find(">div.fr-core-panel-title")
.html(title);
}
},
/**
* 设置指定的工具栏按钮的可见性
* @param {Number} index 要设置的按钮的索引
* @param {Boolean} visible 是否设置为可见
*/
setToolVisible: function (index, visible) {
var opts = this.options;
var ct = opts.tools[index];
if (ct && ct.el && ct.el.isVisible() != visible) {
visible ? ct.el.show() : ct.el.hide();
this._modifyToolsPosition();
}
},
_modifyToolsPosition: function () {
var rd = this.rightDistance, opts = this.options;
for (var i = opts.tools.length - 1; i >= 0; i--) {
var item = opts.tools[i];
if (item.el && item.el.isVisible()) {
item.el.css({right: rd});
rd += item.width;
}
}
},
/**
* 展示面板
*/
doOpen: function () {
this.element.show();
this.options.closed = false;
if ($.isFunction(this.options.onOpen)) {
this.options.onOpen.call(this);
}
},
/**
* 关闭面板
*/
doClose: function () {
var self = this;
this.element.hide(self.options.animate ? "fast" : 0, function () {
self.options.closed = true;
if ($.isFunction(self.options.onClose)) {
self.options.onClose.call(self);
}
});
},
/**
* 面板新的位置
* @param {Point} give 要移动到的新的位置
* @param {Number} give.left 新位置距离父容器的左边距
* @param {Number} give.top 新位置距离父容器的上边距
*/
doMove: function (give) {
var opts = this.options;
if (give) {
if (give.left != null) {
opts.left = give.left;
}
if (give.top != null) {
opts.top = give.top;
}
}
this.element.css({
left: opts.left,
top: opts.top
});
if ($.isFunction(opts.onMove)) {
opts.onMove.apply(this, [opts.left, opts.top]);
}
},
enable: function () {
if (this.mask) {
this.mask.hide();
}
},
disable: function () {
if (!this.mask) {
this.mask = $("<div/>").addClass("fr-core-window-mask").appendTo(this.element);
this.mask.css({
zIndex: FR.widget.opts.zIndex++,
width: this.element.width() ? this.element.width() : this.options.width,
height: this.element.height() ? this.element.height() : this.options.height,
background: 'gray'
});
}
this.mask.show();
},
doResize: function (give) {
var opts = this.options;
var self = this;
// 如果有给定的尺寸,那么久使用给定的尺寸大小
if (give) {
if (give.width) {
opts.width = give.width;
}
if (give.height) {
opts.height = give.height;
}
if (give.left != null) {
opts.left = give.left;
}
if (give.top != null) {
opts.top = give.top;
}
}
// 如果是自适应大小的,那么就根据父元素的大小的确定panel的大小
if (opts.fit === true) {
var p = this.element.parent();
opts.width = p.width();
opts.height = p.height();
}
this.element.css({
left: opts.left,
top: opts.top
});
if (opts.cls) {
this.element.addClass(opts.cls);
}
if (this.$header && opts.headerCls) {
this.$header.addClass(opts.headerCls);
}
if (opts.bodyCls) {
this.panelBody.addClass(opts.bodyCls);
}
if (!isNaN(opts.width)) {
if ($.support.boxModel === true) {
var panelWidth = opts.width - (this.element.outerWidth() - this.element.width());
this.element.width(panelWidth);
if (!FR.isEmpty(opts.title) && this.$header) {
this.$header.width(panelWidth - (this.$header.outerWidth() - this.$header.width()));
this.$innerHeader.width(panelWidth - (this.$header.outerWidth() - this.$header.width()));
}
this.panelBody.width(panelWidth - (this.panelBody.outerWidth() - this.panelBody.width()));
} else {
this.element.width(opts.width);
if (!FR.isEmpty(opts.title) && this.$header) {
this.$header.width(opts.width);
this.$innerHeader.width(opts.width);
}
this.panelBody.width(opts.width - this.borderFix4width);
}
} else {
this.element.width('auto');
this.panelBody.width('auto');
}
if (!isNaN(opts.height)) {
if ($.support.boxModel === true) {
var panelHeight = opts.height - (this.element.outerHeight() - this.element.height());
this.element.height(panelHeight);
if (!FR.isEmpty(opts.title) && this.$header) {
this.$header.height(this.headerHeight - (this.$header.outerHeight() - this.$header.height()));
this.$innerHeader.height(this.headerHeight - (this.$header.outerHeight() - this.$header.height()));
this.$titleText.css({lineHeight: this.headerHeight - (this.$header.outerHeight() - this.$header.height()) + "px"});
}
this.panelBody.height(panelHeight - this.headerHeight - (this.panelBody.outerHeight() - this.panelBody.height()));
} else {
this.element.height(opts.height);
if (!FR.isEmpty(opts.title) && this.$header) {
this.$header.height(this.headerHeight);
this.$innerHeader.height(this.headerHeight);
this.$titleText.css({lineHeight: this.headerHeight + "px"});
}
this.panelBody.height(opts.height - this.headerHeight - this.borderFix4height);
}
} else {
this.element.height('auto');
this.$contentPane.height('auto');
}
if ($.isFunction(opts.onResize)) {
opts.onResize.apply(this, [opts.width, opts.height]);
}
this._resizeContentWidget();
// 触发panel的resize事件
this.fireEvent(FR.Events.RESIZE);
this.element.doLayout();
},
/**
* @protected
*/
_resizeContentWidget: function () {
var opts = this.options;
// alex:不知道为什么IE下面也要用这样的方式才可以取到height,但width却不需要用这种方式
//wei : 宽度也会出问题..
var pbodystylestring = this.$contentPane.attr("style");
var pbodyheight = parseInt(pbodystylestring.replace(
/.*height\:\s*(\d+).*/gi, "$1"));
// ie6下iframeDialog时,iframe标签取宽度会受border-left-width等影响
var pbodywidth = parseInt(pbodystylestring.replace(
/.* width\:\s*(\d+).*/gi, "$1"));
if (opts.contentWidget) {
opts.contentWidget.doResize({
width: this.$contentPane.width(),
height: pbodyheight
});
} else if (opts.contentHtml && FR.Browser.isIE6()) {
$(opts.contentHtml).css({
width: pbodywidth,
height: pbodyheight
});
}
}
});
$.shortcut("panel", FR.Panel);
/**
* 带“确定”以及“取消”按钮的容器
*
* @example
* var $root = $("<div>").css({position:'absolute',top:10,left:10}).appendTo('body');
* var editor = new FR.ConfirmPane({
* renderEl:$root,
* title: "ConfirmPane",
* width : 250,
* closable:true,
* height : 100,
* doSize:true,
* border:true,
* });
*
* @class FR.ConfirmPane
* @extends FR.Panel
* @since 7.0.5
*
* @cfg {JSON} options 配置属性
* @cfg {String} [options.text4OK="确定"] “确定”按钮的文字
* @cfg {String} [options.text4Cancel="取消"] “取消”按钮的文字
* @cfg {Number} [options.width4OK=80] “确定”按钮的宽度
* @cfg {Number} [options.width4Cancel=80] “取消”按钮的宽度
* @cfg {Number} [options.height4OK=28] “确定”按钮的高度
* @cfg {Number} [options.height4Cancel=80] “取消”按钮的高度
* @cfg {Number} [options.controlPaneHeight=40] “确定”和“取消”按钮所在的区域的高度
* @cfg {Number} [options.btnsGap=20] “确定”和“取消”按钮之间的距离
* @cfg {Number} [options.firstBtnMargin=20] 第一个按钮与panel边界的距离,居左就是firstBtn为左边按钮,居右firstBtn为右边按钮
* @cfg {Boolean/Number} [options.needSeparate=false] 是否显示分割线, 直接写分割线距离底下按钮的高度
* @cfg {'right'/'left'/'center'} [options.btnsAlignment='right'] 按钮位置,默认在右边,右对齐时新添按钮从右向左添加,其他是从左向右添加
* @cfg {Boolean} [options.closeAfterAction=true] 是否点击按钮事件结束后关闭Panel,默认关闭
* @cfg {Function} [options.onOK] "确定"按钮点击事件
* @cfg {Function} [options.onCancel] "取消"按钮点击事件
*/
FR.ConfirmPane = FR.extend(FR.Panel, /**@class FR.ConfirmPane */{
_defaultConfig: function () {
return $.extend(FR.ConfirmPane.superclass._defaultConfig.apply(this, arguments), {
text4OK: FR.i18nText("FR-Basic_OK"),
text4Cancel: FR.i18nText("FR-Basic_Cancel"),
width4OK: 80,
width4Cancel: 80,
height4OK: 28,
height4Cancel: 28,
controlPaneHeight: 40,
btnsGap: 20,
firstBtnMargin: 20,
needSeparate: false,
btnsAlignment: 'right',
closeAfterAction: true,
onOK: null,
onCancel: null
});
},
_init: function () {
FR.ConfirmPane.superclass._init.apply(this, arguments);
},
_createContentPane: function () {
var opts = this.options;
var $contentPane = $('<div class="fr-core-panel-content">').css({
position: 'absolute',
top: 0,
left: 0
}).appendTo(this.panelBody);
var self = this;
//Sean: 为了兼容IE6必须再套一层
this.okdiv = $('<div style="position:absolute"/>').appendTo(this.panelBody);
this.canceldiv = $('<div style="position:absolute"/>').appendTo(this.panelBody);
if (!FR.isEmpty(opts.text4OK)) {
/**
* @property {FR.Widget} okButton “确定”按钮
*/
self.okButton = new FR.createWidget({
type: 'quickbutton',
text: opts.text4OK,
width: opts.width4OK,
height: opts.height4OK,
style: opts.style,
handler: function () {
if ($.isFunction(self.options.onOK)) {
var result = self.options.onOK.apply(self);
if (result === false) {
//不关闭对话框
return;
}
}
if (self.options.closeAfterAction) {
self.doClose();
}
}
});
this.okButton.element.appendTo(this.okdiv);
this.okdiv.css({width: opts.width4OK, height: opts.height4OK});
}
if (!FR.isEmpty(opts.text4Cancel)) {
/**
* @property {FR.Widget} cancelButton “取消”按钮
*/
self.cancelButton = new FR.createWidget({
type: 'quickbutton',
text: opts.text4Cancel,
// style : opts.style, //Sean:取消按钮采用默认'gray'样式,不随主题样式变化
width: opts.width4Cancel,
height: opts.height4Cancel,
handler: function () {
if ($.isFunction(self.options.onCancel)) {
self.options.onCancel.apply(self);
}
if (self.options.closeAfterAction) {
self.doClose();
}
}
});
this.cancelButton.element.appendTo(this.canceldiv);
this.canceldiv.css({width: opts.width4Cancel, height: opts.height4Cancel});
}
if (opts.needSeparate) {
$contentPane.addClass("fr-core-panel-content-separate");
this.okdiv && this.okdiv.css('margin-top', opts.needSeparate + 'px');
this.canceldiv && this.canceldiv.css('margin-top', opts.needSeparate + 'px');
}
return $contentPane;
},
doResize: function (give) {
FR.ConfirmPane.superclass.doResize.apply(this, arguments);
var opts = this.options;
var alignment = opts.btnsAlignment;
var oktop = 0, canceltop = 0, okalign = 0, cancelalign = 0;
var height = opts.height;
if (opts.needSeparate) {
height = height - opts.needSeparate;
}
if (!isNaN(height)) {
if ($.support.boxModel === true) {
this.$contentPane.css({
height: height - this.headerHeight - opts.controlPaneHeight - (this.$contentPane.outerHeight() - this.$contentPane.height()),
width: opts.width - (this.panelBody.outerWidth() - this.panelBody.width())
});
} else {
this.$contentPane.css({
height: height - this.headerHeight - opts.controlPaneHeight,
width: opts.width
});
}
}
oktop = height - this.headerHeight - opts.controlPaneHeight;
canceltop = height - this.headerHeight - opts.controlPaneHeight;
if (alignment == 'right') {
okalign = opts.width4Cancel + opts.firstBtnMargin + opts.btnsGap;
cancelalign = opts.firstBtnMargin;
}
else if (alignment == 'left') {
okalign = opts.firstBtnMargin;
cancelalign = opts.width4OK + opts.firstBtnMargin + opts.btnsGap;
}
else {
var allWidth = opts.width4OK + opts.width4Cancel + opts.btnsGap;
var Left = (opts.width - allWidth) / 2;
okalign = Left;
cancelalign = Left + opts.width4OK + opts.btnsGap;
alignment = 'left'; //center的时候,用left的距离来计算
}
if (this.okButton) {
this.okdiv.css('top', oktop);
this.okdiv.css(alignment, okalign);
}
if (this.cancelButton) {
this.canceldiv.css('top', canceltop);
this.canceldiv.css(alignment, cancelalign);
}
this._resizeContentWidget();
}
});
$.shortcut("confirm", FR.ConfirmPane);
/**
* 装载按钮的容器
* @class FR.ButtonPane
* @extends FR.Panel
* @private
*/
FR.ButtonPane = FR.extend(FR.Panel, {
_defaultConfig: function () {
return $.extend(FR.ButtonPane.superclass._defaultConfig.apply(this, arguments), {
text4Cancel: FR.i18nText("FR-Basic_Cancel"),
width4Cancel: 80,
button4Other: [], //wikky:添加两个以上的按钮[{bT:文字,bW:宽度,默认80,bF:按钮点击动作,bC:点击按钮后是否关闭Panel,默认false},{…}}]
controlPaneHeight: 40,
btnsAlignment: 'right',
closeAfterAction: true //Sean: 是否点击按钮事件结束后关闭Panel,默认关闭
});
},
_init: function () {
FR.ButtonPane.superclass._init.apply(this, arguments);
},
_createContentPane: function () {
var opts = this.options;
var $contentPane = $('<div class="fr-core-panel-content">').css({
position: 'absolute',
top: 0,
left: 0
}).appendTo(this.panelBody);
var other = opts.button4Other;
this.otherButton = [];
this.otherButtonWrap = [];
for (var i = 0; i < other.length; i++) {
this.otherButtonWrap[i] = $('<div style="position:absolute"/>').appendTo(this.panelBody);
this.otherButton[i] = new FR.createWidget({
type: 'quickbutton',
text: other[i].bT,
width: other[i].bW ? other[i].bW : 80,
baseCls: other[i].baseCls ? other[i].baseCls : '',
invisible: other[i].invisible,
style: opts.style,
handler: function () {
var onAct = this.element.data("func");
if ($.isFunction(onAct)) {
onAct.apply(self);
}
var aftAct = this.element.data("aftfunc");
if (aftAct) {
self.doClose();
}
}
});
this.otherButton[i].element.appendTo(this.otherButtonWrap[i]);
this.otherButtonWrap[i].css({width: other[i].bW, height: opts.height4Cancel});
this.otherButton[i].element.data("func", other[i].bF ? other[i].bF : FR.emptyFn());
this.otherButton[i].element.data("aftfunc", other[i].bC ? other[i].bC : false);
}
var self = this;
this.canceldiv = $('<div style="position:absolute"/>').appendTo(this.panelBody);
this.cancelButton = new FR.createWidget({
type: 'quickbutton',
text: opts.text4Cancel,
// style : opts.style, //Sean:取消按钮采用默认'gray'样式,不随主题样式变化
width: opts.width4Cancel,
height: opts.height4Cancel,
handler: function () {
if ($.isFunction(self.options.onCancel)) {
self.options.onCancel.apply(self);
}
if (self.options.closeAfterAction) {
self.doClose();
}
}
});
this.cancelButton.element.appendTo(this.canceldiv);
this.canceldiv.css({width: opts.width4Cancel, height: opts.height4Cancel});
if (opts.needSeparate) {
$contentPane.addClass("fr-core-panel-content-separate");
this.canceldiv && this.canceldiv.css('margin-top', opts.needSeparate + 'px');
for (var i = 0; i < this.otherButtonWrap.length; i++) {
this.otherButtonWrap[i] && this.otherButtonWrap[i].css('margin-top', opts.needSeparate + 'px');
}
}
return $contentPane;
},
doResize: function (give) {
FR.ButtonPane.superclass.doResize.apply(this, arguments);
var opts = this.options;
var other = opts.button4Other;
var alignment = opts.btnsAlignment;
var canceltop = 0, cancelalign = 0;
var height = opts.height;
if (opts.needSeparate) {
height = height - opts.needSeparate;
}
if (!isNaN(height)) {
if ($.support.boxModel === true) {
this.$contentPane.css({
height: height - this.headerHeight - opts.controlPaneHeight - (this.$contentPane.outerHeight() - this.$contentPane.height()),
width: opts.width - (this.panelBody.outerWidth() - this.panelBody.width())
});
} else {
this.$contentPane.css({
height: height - this.headerHeight - opts.controlPaneHeight,
width: opts.width
});
}
}
canceltop = height - this.headerHeight - opts.controlPaneHeight;
var alignment = opts.btnsAlignment;
if (alignment == 'right') {
var right = opts.width4Cancel + 40;
this.canceldiv.css(alignment, 20);
this.canceldiv.css('top', canceltop);
for (var i = 0; i < other.length; i++) {
this.otherButtonWrap[i].css(alignment, right);
this.otherButtonWrap[i].css('top', canceltop);
right = right + other[i].bW + 20;
}
}
else if (alignment == 'left') {
var left = opts.width4Cancel + 40;
this.canceldiv.css(alignment, 20);
this.canceldiv.css('top', canceltop);
for (var i = 0; i < other.length; i++) {
this.otherButtonWrap[i].css(alignment, left);
this.otherButtonWrap[i].css('top', canceltop);
left = left + other[i].bW + 20;
}
}
else {
var allWidth = 0;
for (var i = 0; i < other.length; i++) {
allWidth = allWidth + other[i].bW + 20;
}
allWidth = allWidth + opts.width4Cancel;
var otherLeft = (opts.width - allWidth) / 2;
for (var i = 0; i < other.length; i++) {
this.otherButtonWrap[i].css('left', otherLeft);
this.otherButtonWrap[i].css('top', canceltop);
otherLeft = otherLeft + other[i].bW + 20;
}
this.cancelButton.element.css('left', otherLeft);
}
this._resizeContentWidget();
}
});
$.shortcut("otherbutton", FR.ButtonPane);
/**
* 窗体控件
* @class FR.Window
* @extends FR.Widget
* @since 6.5.3
*
* @cfg {JSON} options 配置属性
* @cfg {String} [options.title='Window'] 窗体的标题
* @cfg {Number} [options.titleHeight=30] 窗体的标题高度
* @cfg {Boolean} [options.modal=true] 是否为模态窗体,模态窗体不允许点击对话框下层的区域
* @cfg {Boolean} [options.confirm=false] 是否为带“确定”和“取消”按钮的窗体
* @cfg {Object} options.otherButton
* @cfg {Boolean} [options.closable=true] 窗体是否可以关闭,如果可以关闭将会在左上角显示关闭按钮
* @cfg {Boolean} [options.collapsible=false] 窗体是否可以收缩
* @cfg {Boolean} [options.closed=true] 初始化完成后是否将窗体置为关闭状态
* @cfg {Boolean} [options.destroyOnClose=false] 窗体关闭后是否立即销毁窗体对象
* @cfg {Number} [options.width=300] 窗体的宽度
* @cfg {Number} [options.height=200] 窗体的高度
* @cfg {Boolean} [options.resizeable=true] 窗体是否可以拖拽调整大小
* @cfg {Boolean} [options.draggable=true] 窗体是否可以被拖动
* @cfg {JSON} [options.override] 覆盖内部FR.Panel属性的配置属性
* @cfg {Function} [options.onDialogResize] 窗体调整大小时触发的函数
*/
FR.Window = FR.extend(FR.Widget, {
_defaultConfig: function () {
return $.extend(FR.Window.superclass._defaultConfig.apply(), {
baseCls: "fr-core-window",
title: "Window",
titleHeight: 30,
modal: true,
confirm: false,
otherButton: false,
closable: true,
collapsible: false,
closed: true,
destroyOnClose: false,
width: 300,
height: 200,
resizeable: true,
draggable: true
});
},
_init: function () {
FR.Window.superclass._init.apply(this, arguments);
var o = this.options;
var win = this.win;
if (!$.support.boxModel) {
win.doResize({
// marro :这里比较特殊 win = this.el,
// 生成win的的时候大小由o确定了,而FR.Widget初始化时也会对this.el大小进行改变,并且还考虑了boxModel.因此,再reszie下。
width: o.width,
height: o.height
})
}
var self = this;
if (this.mask) {
this.mask.remove();
}
if (o.modal === true) {
this.mask = $('<div class="fr-core-window-mask"></div>')
.appendTo('body');
this.mask.css({
zIndex: FR.widget.opts.zIndex++,
width: this._getPageArea().width,
height: this._getPageArea().height,
display: 'none'
});
$(window).resize(function () {
self.mask.css({
width: self._getPageArea().width,
height: self._getPageArea().height
})
});
}
this.element.css({
zIndex: FR.widget.opts.zIndex++
});
if (win.options.left == null) {
var width = win.options.width;
if (isNaN(width)) {
width = this.element.outerWidth();
}
// var l = $(window.document).width() bug64304,ie,ff下不能取document高度
var l = $(window).width();
if (FR.Browser.isIE8Before()) {
l = $(window.document).width();
}
win.options.left = (l - width) / 2
+ $(document).scrollLeft();
}
if (win.options.top == null) {
var height = win.options.height;
if (isNaN(height)) {
height = this.element.outerHeight();
}
var h = $(window).height();
if (FR.Browser.isIE8Before()) {
h = $(window.document).height();
}
win.options.top = (h - height) / 2
+ $(document).scrollTop();
}
win.doMove();
this.setVisible(!o.closed);
if (this.options.draggable) {
this.element.draggable({
handle: ">div.fr-core-panel-header",
onStartDrag: function (e) {
if (self.mask) {
self.mask.css('z-index', FR.widget.opts.zIndex.zIndex++);
}
if (self.shadow) {
self.shadow.css('z-index', FR.widget.opts.zIndex.zIndex++);
}
self.element.css('z-index', FR.widget.opts.zIndex.zIndex++);
var $contentDiv = $(self.element.children()[0]);
$contentDiv.css('z-index', 0);
var top = $contentDiv.css("top");
var height = $contentDiv.css("height");
var width = $contentDiv.css("width");
var $transparentDiv = $('<div id="transparent-background" style="position:absolute;filter:alpha(opacity=50);opacity:0.5;"></div>');
$transparentDiv.css('left', "0px").css('top', top).css('width', width).css('height', height);
$transparentDiv.css('z-index', 1);
self.element.append($transparentDiv);
if (!self.proxy) {
self.proxy = $('<div class="fr-core-window-proxy"></div>').insertAfter(self.element);
}
self.proxy.css({
display: 'none',
zIndex: FR.widget.opts.zIndex.zIndex++,
left: e.data.left,
top: e.data.top
});
self.proxy._outerWidth(self.element._outerWidth());
self.proxy._outerHeight(self.element._outerHeight());
setTimeout(function () {
if (self.proxy) {
self.proxy.show();
}
}, 500);
},
onDrag: function (e) {
var pluginLimit = FR.Window.PluginDialogLimit;
if(pluginLimit){
e.data.top = pluginLimit.onDrag.pluginTopFn(e.data.top,self.element._outerHeight(),self._getPageArea().height);
e.data.left = pluginLimit.onDrag.pluginLeftFn(e.data.left,self.element._outerWidth(),self._getPageArea().width);
}
self.proxy.css({
display: 'block',
left: e.data.left,
top: e.data.top
});
return false;
},
onStopDrag: function (e) {
$("#transparent-background").remove();
self.proxy.remove();
self.proxy = null;
}
});
}
if (this.options.resizeable) {
this.element.resizable({
onStartResize: function (e) {
if (!self.pmask) {
self.pmask = $('<div class="fr-core-window-proxy-mask"></div>').insertAfter(self.element);
}
self.pmask.css({
zIndex: FR.widget.opts.zIndex++,
left: e.data.left,
top: e.data.top,
width: self.element._outerWidth(),
height: self.element._outerHeight()
});
if (!self.proxy) {
self.proxy = $('<div class="fr-core-window-proxy"></div>').insertAfter(self.element);
}
self.proxy.css({
zIndex: FR.widget.opts.zIndex++,
left: e.data.left,
top: e.data.top
});
self.proxy._outerWidth(e.data.width);
self.proxy._outerHeight(e.data.height);
},
onResize: function (e) {
if(!self.proxy){
return;
}
self.proxy.css({
left: e.data.left,
top: e.data.top
});
self.proxy._outerWidth(e.data.width);
self.proxy._outerHeight(e.data.height);
return false;
},
onStopResize: function (e) {
var pluginLimit = FR.Window.PluginDialogLimit;
if (pluginLimit) {
e.data.height = pluginLimit.onResize.pluginHeightFn(e.data.top, self.element._outerHeight(), self._getPageArea().height);
e.data.width = pluginLimit.onResize.pluginWidthFn(e.data.left, self.element._outerWidth(), self._getPageArea().width);
e.data.top = pluginLimit.onResize.pluginTopFn(e.data.top, self.element._outerHeight(), self._getPageArea().height);
e.data.left = pluginLimit.onResize.pluginLeftFn(e.data.left, self.element._outerWidth(), self._getPageArea().width);
}
$.extend(self.options, {
left: e.data.left,
top: e.data.top,
width: e.data.width,
height: e.data.height
});
self.doResize({
top: self.options.top,
left: self.options.left,
width: self.options.width,
height: self.options.height
});
self.pmask.remove();
self.pmask = null;
if(self.proxy) {
self.proxy.remove();
self.proxy = null;
}
}
});
}
},
_defaultRoot: function () {
var o = this.options, override = o.override;
// PIE ie8标准模式有黑框
if (FR.Browser.isIE() && !FR.Browser.r.quirks) {
o.baseCls += " fr-core-window-no-hack";
}
var self = this;
var panelType;
if (o.confirm) {
panelType = "confirm";
} else if (o.otherButton) {
panelType = "otherbutton";
} else {
panelType = "panel";
}
var winOpts = $.extend({}, o, {
type: panelType,
height: o.height - o.titleHeight,
fit: false,
renderEl: $('<div/>').appendTo("body"),
doSize: true,
border: true,
borderRadius: 'auto',
cls: o.baseCls,
headerCls: 'fr-core-window-header',
bodyCls: 'fr-core-window-body',
onClose: function () {
if (self.mask) {
self.mask.hide();
}
if (o.destroyOnClose) {
self.destroy();
}
},
onOpen: function () {
if (self.mask) {
self.mask.show();
}
},
onResize: function (width, heigh) {
if ($.isFunction(o.onDialogResize)) {
o.onDialogResize();
}
},
onMove: function (left, top) {
}
}, override);
this.win = FR.createWidget(winOpts);
return this.win.element;
},
_getPageArea: function () {
if (document.compatMode == 'BackCompat') {
return {
width: Math.max(document.body.scrollWidth,
document.body.clientWidth),
height: Math.max(document.body.scrollHeight,
document.body.clientHeight)
}
} else {
return {
width: Math.max(document.documentElement.scrollWidth,
document.documentElement.clientWidth),
height: Math.max(
document.documentElement.scrollHeight,
document.documentElement.clientHeight)
}
}
},
/**
* 关闭窗体
*/
doClose: function () {
this.win.doClose();
},
doResize: function (give) {
this.win.doResize(give);
},
/**
* 设置窗体的标题文本
* @param title 新的标题
*/
setTitle: function (title) {
this.win.setTitle(title);
},
/**
* 设置窗体的显示内容
* @param {Object} c 新的窗体内容
* @param {String} c.type 新内容的类型
* @param {String} c.content 新内容的具体文本
*
* setContent({type : "contentText" ,content : "1111"});
* setContent({type : "contentHtml" ,content : "<p><i>test</i></p>"});
*/
setContent: function (c) {
this.win.options[c.type] = c.content;
// 强制加载对话框内容
this.win._loadContent(true);
if (FR.Browser.isIE8Before()) {
var self = this;
setTimeout(function () {
self.doResize({'width': undefined, 'height': undefined});
}, 150);
}
},
setVisible: function (flag) {
// 需要设置为可见,并且该对话框当前是不可见的才去打开
if (flag === true && this.win.options.closed === true) {
this.win.doOpen();
} else if (flag === false && this.win.options.closed === false) {
this.win.doClose();
}
},
// 销毁整个FR.Window
destroy: function () {
this.element.remove();
this.mask.remove();
}
});
$.shortcut("window", FR.Window);
/**
* 对话框。可以同时显示多了对话框,但是只有最上层的活跃状态
*
* @example
* var dlg = new FR.Dialog({
* title : 'Dialog',
* height : 100,
* contentHtml : '<p>Hello Dialog!</p>'
* });
* dlg.setVisible(true);
*
* @class FR.Dialog
* @extends FR.Window
* @since 6.5.3
*/
FR.Dialog = FR.extend(FR.Window, {});
$.shortcut("dialog", FR.Dialog);
})(jQuery);