/// /// /// /// /// (function ($) { ke.rect = function () { this.left = arguments[0]; this.top = arguments[1]; this.width = arguments[2]; this.height = arguments[3]; if (arguments.length > 4) { this.horizontal = arguments[4]; this.vertical = arguments[5]; } return this; } ke.rect.prototype.getPos = function () { return { left: this.left, top: this.top } }; ke.rect.prototype.setPos = function (left, top) { this.left = left; this.top = top; } ke.rect.prototype.getRight = function () { return this.left + this.width; }; ke.rect.prototype.getBottom = function () { return this.top + this.height; }; ke.rect.prototype.diff = function (e) { var r = 0; if (e.width > this.width) r += e.width - this.width; if (e.height > this.height) r += e.height - this.height; return r; } ke.rect.prototype.getSplitRects = function (maxWidth, maxHeight) { var r = []; var left = this.left, top = this.top, h = this.height, w = this.width; var bottom = top + h, right = left + w; return [ new ke.rect(left, bottom, maxWidth - left, maxHeight - bottom, "ll", "tb"), //下方 new ke.rect(0, bottom, right, maxHeight - bottom, "rr", "tb"), new ke.rect(left, 0, maxWidth - left, top, "ll", "bt"), //上方 new ke.rect(0, 0, right, top, "rr", "bt"), new ke.rect(right, top, maxWidth - right, maxHeight - top, "lr", "tt"), //右侧 new ke.rect(right, 0, maxWidth - right, bottom, "lr", "bb"), //左侧 new ke.rect(0, top, left, maxHeight - top, "rl", "tt"), new ke.rect(0, 0, left, bottom, "rl", "bb")]; } /** * 将控件值组织成对象 * @id {string} [可空] 控件所在范围,若不指定则为整个document */ ke.createObject = function (id, preFix) { var info = {}; var cons = ke.ui.findControls(id, "input"); for (var i = 0; i < cons.length; i++) { var temp = cons[i]; var name = temp.skin.id; if (preFix) name = temp.skin.id.substr(preFix.length); info[name] = temp.get(); } return info; } /** * 将对象值绑定到控件 * @obj {object} 需要绑定的对象 * @id {string} [可空] 控件所在范围,若不指定则为整个document */ ke.bindObject = function (obj, id, preFix) { var cons = ke.ui.findControls(id, "input"); for (var i = 0; i < cons.length; i++) { var temp = cons[i]; if (temp.skin.id && (!preFix || temp.skin.id.indexOf(preFix) == 0)) { if (!preFix) cons[i].set(obj[temp.skin.id]); else cons[i].set(obj[temp.skin.id.substr(preFix.length)]); } } } /** * 根据传入的dom 转换成 table对象 * @el {object} dom节点 */ ke.createStore = function (el) { if (el && el.children.length > 0) { var items = el.children; var store = new ke.table(); store.addColumn("num"); store.addColumn("name"); store.addColumn("title"); store.addColumn("html"); for (var i = 0; i < items.length; i++) { var opt = new ke.options(items[i]); opt.parse({ value: "", title: "" }); var htm = items[i].innerHTML.trim(); var item = { num: opt.value, name: (opt.title || htm || opt.value), title: opt.nativeTitle, html: htm }; store.addRow(item); } return store; } return null; } ke.bindOrTrriger = function ($el, name, args) { if (args.length < 1) $el.trigger(name); else if (args.length < 2) $el.bind(name, args[0]); else $el.bind(name, args[0], args[1]); } ke.disable = function () { var r = arguments[0]; for (var i = 1; i < arguments.length; i++) arguments[i].disable(r); } ke.setElSize = function (dom, w, h) { var $el = $(dom); var con = ke.ui.find(dom); if (con) con.changeSize(w, h); else $el._setSize(dom.className.indexOf("keui-") < 0, w, h); return $el; } $.fn._getRect = function () { return new ke.rect(this.offset().left, this.offset().top, this._width(), this._height()); } $.fn._getPMB = function () { var cs = document.defaultView.getComputedStyle(this[0]); var m0 = parseInt(cs["marginLeft"]) + parseInt(cs["marginRight"]) + parseInt(cs["paddingLeft"]) + parseInt(cs["paddingRight"]) + parseInt(cs["borderLeftWidth"]) + parseInt(cs["borderRightWidth"]); var m1 = parseInt(cs["marginTop"]) + parseInt(cs["marginBottom"]) + parseInt(cs["paddingTop"]) + parseInt(cs["paddingBottom"]) + parseInt(cs["borderTopWidth"]) + parseInt(cs["borderBottomWidth"]); return [m0, m1]; } /*设置元素的宽高,参数为null则不设置此项 @minusPB {bool} 是否扣除padding、border的宽高 @w {int} [可空]宽度 @h {int} [可空]高度 @x {int} [可空]x坐标 @y {int} [可空]y坐标 */ $.fn._setSize = function (minusPB, w, h, left, top) { if (this.length) { if (minusPB && (w || h)) { //计算padding+margin+border var pb = this._getPMB(); if (w) w -= pb[0]; if (h) h -= pb[1]; } var css = {}; if (w > 0) css.width = parseInt(w); if (h > 0) css.height = parseInt(h); if (left != null) css.left = left; if (top != null) css.top = top; this.css(css); return css; } } /** * 判断x,y坐标是否在当前元素之上 * @x {int} x坐标 * @y {int} y坐标 */ $.fn._containsXY = function (x, y) { var x0 = this.offset().left; var y0 = this.offset().top; var w = this._width(); var h = this._height(); if (x < x0 || x > (x0 + w)) return false; if (y < y0 || y > (y0 + h)) return false; return true; } /** * 获取元素的包含margin,pading,border的宽度 */ $.fn._width = function () { return this.length ? this.outerWidth(true) : 0; } /** * 获取元素的包含margin,pading,border的高度 */ $.fn._height = function () { return this.length ? this.outerHeight(true) : 0; } /** * 组件继承 * @sup {object} 父类 */ $.fn._extend = function (sup, args) { sup.apply(this, args); $.extend(this, args.callee.methods); this.skin.parse(args.callee.defaults); return this; } /** * ke.ui全局对象,用以控件生成、尺寸计算等通用方法 */ function createUI() { var ui = $(window); ui.registerAsGlobal = true; ui.winWidth = ui.width(); ui.winHeight = ui.height(); ui.controls = []; //当前控件,注意这只是顶级控件,需要遍历才能访问到其它控件 ui.controlsCount = 0; ui.lang = function (wd) { return wd; } /** * 检测界面带有 keui-样式的dom,转换为目标控件 * @id {string} [可空] 控件所在范围,若不指定则为整个document * @_parent {object} [可空] 此对象的父控件 * @_global {bool} [可空] 是否注册成为全局对象 */ ui.render = function ($el, _parent, _global) { var exists = true; while (exists) { exists = false; var tag = "[class^='keui-']:first"; var cons = (!$el ? $(tag) : $el.find(tag)); for (var i = 0; i < cons.length; i++) { var el = cons[i]; var fn = el.className.split(" ")[0].substr(5); if (fn == "lang") { el.className = el.className.replace("keui-lang", "").trim(); el.innerHTML = ke.ui.lang(el.innerHTML); } else if (fn == "tooltip") { $(el).tooltip(); } else { ke.ui.controlsCount++; var con = $(el)[fn](); ke.ui.createEntity(con, _parent, _global); } exists = true; break; } } } /** * 根据传入的 component对象生成HTML并输出到界面 * @con {object} 需要生成的component对象 * @_parent {object} 此对象的父控件 */ ui.createEntity = function (con, _parent) { con.initSkin(); var skin = con.skin; var htm = "
"; con.after(htm); var dom = con[0].nextSibling; con.remove(); con[0] = dom; con.autoSizeBox = (skin.autoSizeBox || con.parent());//如果没有配置自动尺寸依赖的元素,则认为是组件的父容器 con.initHandler(); if (skin.data && skin.data.tooltip) con.tooltip(); if (con.documentClick) { $(window).click(con, con.documentClick); } con.initSize(true); if (con.hasClass("draggable") && $.drag) { $.drag.bind(con.skin.dragEl || con, { el: con }); } if (skin.hidden) con.hide(); delete skin.htm; delete skin.css; delete skin.data; ui.createRelation(con, _parent); return con; } /** * 根据传入的 component对象生成HTML并输出到界面 * @con {object} 需要生成的component对象 * @_parent {object} 此对象的父控件 */ ui.createRelation = function (con, _parent) { if (ui.registerAsGlobal && con.skin.id) window[con.skin.id] = con; _parent = (_parent || ui); con._parent = _parent; _parent.controls.push(con); } /** * 根据传入的 component对象销毁控件 * @con {object} 需要销毁的component对象 */ ui.destroy = function (con) { if (con) { for (var i = 0; i < con.controls.length; i++) ui.destroy(con.controls[i]); con.trigger("destroy"); if (con.layerCompnent) ke.ui.destroy(con.layerCompnent); var parent = (con._parent || ke.ui); var index = parent.controls.indexOf(con); if (index > -1) { parent.controls.splice(index, 1); con.remove(); delete con; } } } /** * 查找控件 * @dom { string或 原生dom } [可空] 控件所在范围,若不指定则为整个document * @isInput {bool} [可空] 是否必须是input类型控件 */ ui.findControls = function (dom, cls) { if (dom && ke.isString(dom)) dom = ke.get(dom); var result = []; $(dom || window.document.body).find("." + cls).each(function (i, d) { var t = ui.find(d); if (t) result.push(t); }); return result; } /** * 查找控件 * @dom { string或原生dom } 转换的目标 * @parent {ke.ui 控件对象} [可空] 查找范围 */ ui.find = function (dom, parent) { if (ke.isString(dom)) dom = ke.get(dom); parent = (parent || ke.ui); var r = null; for (var i = 0; i < parent.controls.length; i++) { var temp = parent.controls[i]; if (temp[0] == dom) r = temp; else r = ke.ui.find(dom, temp); if (r) break; } return r; } ui.parent = function (dom) { var r = null; while (!r && dom) { dom = dom.parentElement; r = ui.find(dom); } return r; } ui.size = function (con) { for (var i = 0; i < con.controls.length; i++) { var temp = con.controls[i]; temp.initSize(); ui.size(temp); } } ui.exists = function (con) { return ui.find(con[0]) != null; } window.onresize = function () { if (ke.ui.resizeEvent) clearTimeout(ke.ui.resizeEvent); ke.ui.resizeEvent = setTimeout("ke.ui.winWidth = ke.ui.width(); ke.ui.winHeight = ke.ui.height();$(\".mask\").css({ width: ke.ui.winWidth, height: ke.ui.winHeight });ke.ui.size(ke.ui);ke.ui.trigger(\"sizeEnd\");", 100); }; function stopEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.returnValue) e.returnValue = false; return false; } function stopBanBackSpace(e) { if (e.keyCode == 8) { var obj = e.target; if (!obj.isContentEditable) { var tagName = obj.nodeName; if (tagName != 'INPUT' && tagName != 'TEXTAREA') { return stopEvent(e); } var tagType = obj.type.toUpperCase(); if (tagName == 'INPUT' && (tagType != 'TEXT' && tagType != 'TEXTAREA' && tagType != 'PASSWORD')) { return ui.stopEvent(e); } if ((tagName == 'INPUT' || tagName == 'TEXTAREA') && (obj.readOnly == true || obj.disabled == true)) { return ui.stopEvent(e); } } } }; ui.keydown(stopBanBackSpace); return ui; } ke.ui = createUI(); ke.ui.mobile = false; ke.ui.version = "20190302"; /** * 根据dom的data-options属性或者配置实例,获取控件设定值 * @el{dom} 原生dom元素 * @config {object} 用户通过JS设定的配置,形如 ke.ui.defaults */ ke.options = function (el, config) { function getValue(name, def) { var r = data[name]; if (r != null) { if ($.isNumeric(def)) r = ke.getFloat(r, 2); else if (ke.isBool(def)) r = (r != "0" && r != "false"); } else r = def; return r; } /** * 根据配置默认值,提供转换后的结果 * @defaults {object} 默认的配置对象,特别注意此对象内的属性必须都是值引用属性,否则会导致混乱 * @obj {object} 结果转出目标,默认为自己 */ this.parse = function (defaults, target) { target = (target || this); for (var ff in defaults) { target[ff] = getValue(ff, defaults[ff]); } } this.getSize = function (name, el, v) { var val = (v || el.style[name]).toString(); if (!val) return -1; else if (val.indexOf("%") > 0) return parseInt(val) * 0.01; else return parseInt(val); } this.className = ""; this.attributes = ""; this.style = ""; var data = {}; if (el) { var opt = el.attributes["data-options"]; if (opt) { if (opt.value.indexOf(':') > 0) opt.value = '{' + opt.value + '}'; data = $.extend(data, (new Function("return " + opt.value + ";"))()); opt.value = ""; } opt = el.attributes["data-union"]; if (opt) { data.union = (new Function("return {" + opt.value + "};"))(); opt.value = ""; } opt = el.attributes["data-tooltip"]; if (opt) { data.tooltip = opt.value; opt.value = ""; } data.width = this.getSize("width", el, data.width); data.height = this.getSize("height", el, data.height); data.hidden = data.hidden || el.style.display == "none"; el.style.display = "" //el.style.width = el.style.height = el.style.display = ""; var attr = el.attributes; var keeps = ["id", "class", "title", "value", "placeholder", "disabled", "readonly"]; for (var i = 0; i < attr.length; i++) { var name = attr[i].name; var val = attr[i].value; if (keeps.indexOf(name) > -1) data[name] = val; else if (name == "style") this.style = val; else if (val) this.attributes += " " + name + "=\"" + val + "\""; } var cls = el.className.split(' '); for (var i = 0; i < cls.length; i++) { if (cls[i] && cls[i].indexOf("keui-") < 0) this.className += " " + cls[i]; } } this.data = $.extend(data, config); }; /** * 所有控件的基础类,定义控件事件+方法 * @settings {object} [可空] 配置项 */ $.fn.component = function (settings) { this._parent = null; //父级控件 this.controls = [];//保存了此控件所拥有的所有子级控件实例 /** * 控件外观与配置集合,子类函数主要是对此对象进行调整与设置 */ var sk = new ke.options(this[0], settings); sk.html = "";//最终输出的HTML sk.outputAttr = true;//是否在容器上保留原来的dom属性 sk.parse($.fn.component.defaults); $.extend(this, $.fn.component.methods); sk.layerOptions = $.extend({ horizontal: "auto", vertical: "auto" }, sk.layerOptions); this.skin = sk; return this; } $.fn.component.defaults = { width: -1,//小于0 即自适应父级容器高度 height: -1,//小于0 即自适应低级容器宽度 autoSizeBox: null,//如果指定此属性,则自动宽高依赖于此对象(jquery 对象) title: "",//控件标题 id: "", css: "",//附加在开头的CSS nativeTitle: "",//浏览器原生title hidden: false,//是否隐藏 disabled: false, //控件是否禁用, onClick: null, //控件点击事件 iconCls: "", //图标 dragEl: null, //当可拖动时需要点击的区域 formatContent: false,//生成控件时是否格式化 layerOptions: null //显示弹出层时所使用的配置 } $.fn.component.methods = { show: function () { this[0].style.display = "block"; this.skin.hidden = false; this.initSize(); this.trigger("onShow"); return this; }, hide: function () { this[0].style.display = "none"; this.skin.hidden = true; this.trigger("onHide"); return this; }, changeSize: function (w, h) { if (w != null) this.skin.width = w; if (h != null) this.skin.height = h; this.initSize(); return this; }, render: function () { return ke.ui.createEntity(this); }, //控件的弹出层 layerHtml: function (wd) { var htm = ""; if (ke.ui.mobile && this.skin.isInput) { htm += "
取消
" + this.skin.title + "
"; } var st = this.store; if (st) { var v = this.get(); var map = { }; for (var i = 0; i < st.rows.length; i++) { var row = st.rows[i]; var txt = (row.get("html") || row.get(this.skin.textField)); var key = row.get(this.skin.valueField); map[this.skin.valueField] = key; if (!wd || txt.indexOf(wd) > -1) { htm += "
" + txt + "
"; } } } htm = (htm || ""); return htm; }, layerHide: function () { ke.ui.destroy(this.layerCompnent); }, showLayer: function (wd) { this.trigger("layerShowBefore"); if (this.layerCompnent) ke.ui.destroy(this.layerCompnent); var htm = this.layerHtml(wd); htm = $.parseHTML("
" + this.layerHtml(wd) + "
"); $(document.body).append(htm); this.layerCompnent = $(htm).layer(this.skin.layerOptions).render().removeClass("fll").trigger("layerShow").show(); this.trigger("layerShowAfter"); return this.layerCompnent; } } /** * 布局控件基类 * @settings {object} [可空] 配置项 */ $.fn.layout = function () { return this._extend($.fn.component, arguments); } $.fn.layout.defaults = { scroller: true,//是否出现滚动条 url: "", urlParms: null } $.fn.layout.methods = { initSkin: function () { this.skin.parse($.fn.layout.defaults); }, initSize: function (first) { if (first) ke.ui.render(this, this); }, initHandler: function () { }, getSize: function () { var w = this.skin.width; var h = this.skin.height; if (w <= 1) w = this.autoSizeBox.width() * (w > 0 ? w : 1); if (h <= 1) h = this.autoSizeBox.height() * (h > 0 ? h : 1); return [w, h]; } } /** * 面板 */ $.fn.panel = function () { if (ke.ui.exists(this)) return ke.ui.find(this[0]); return this._extend($.fn.layout, arguments); } $.fn.panel.defaults = { collapsible: false,//折叠 closable: false,//关闭按钮 maximizable: false,//最大化 collapsed: false,//是否处于折叠态 minimizable: false,//是否支持最小化(对panel无效) state: "", //面板状态,支持 "max","min"或空白(表示正常) bodyCls: "",//向body部分附加的样式, frameAutoHeight: false,//根据frame自动扩展高度 onLoad: null //面板onload事件 } $.fn.panel.methods = { /** * 控件外观与生成 */ initSkin: function () { $.fn.layout.methods.initSkin.call(this); this.skin.css += "panel"; var htm = ""; if (this.skin.title) { htm = "
" + ke.ui.lang(this.skin.title) + "
"; if (this.skin.collapsible) htm += "
"; if (this.skin.minimizable) htm += "
"; if (this.skin.maximizable) htm += "
"; if (this.skin.closable) htm += "
"; htm += "
"; } htm += "
" + this.html() + "
"; }, initHandler: function () { var con = this; con.$header = con.find(".panel-header"); con.$body = con.find(".panel-body"); con.skin.dragEl = con.$header; con.bind("onShow", con, function (e) { if (e.data.skin.url) e.data.loadUrl(e.data.skin.url); }); this.pmb = this._getPMB(); con.find(".static-icon-btn").click(function (e) { if (ke.hasClass(e.target, "icon-collapse")) con.collapse(); else if (ke.hasClass(e.target, "icon-minimize")) con.minimumSize(); else if (ke.hasClass(e.target, "icon-maximize")) con.maximumSize(); else if (ke.hasClass(e.target, "icon-close")) con.hide(); }); }, initSize: function (first) { var con = this; var wh = con.getSize(); if (con.skin.state == "max") { wh[0] = con.autoSizeBox.width(); wh[1] = con.autoSizeBox.height(); } if (con.$header.length) { con.$header._setSize(true, wh[0]); wh[1] -= con.$header._height(); } con.$body._setSize(true, wh[0] - this.pmb[0], wh[1] - this.pmb[1]); if (first) { con[0].style.width = ""; con[0].style.height = ""; if (!this.skin.hidden && this.skin.url) this.loadUrl(this.skin.url); if (this.skin.onLoad) this.load(this.skin.onLoad); $.fn.layout.methods.initSize.call(this, first); } ke.ui.size(con); }, /* * 方法 */ collapse: function (v, callback) { this.skin.collapsed = v || !this.skin.collapsed; this.$header.find(".icon-collapse").toggleClass("icon-collapsed", this.skin.collapsed); if (this.skin.collapsed) this.$body.hide(); else this.$body.show(); }, maximumSize: function () { this.skin.state = (this.skin.state != "max" ? "max" : ""); this.$header.find(".icon-maximize").toggleClass("icon-maximized", this.skin.state == "max"); this.initSize(); }, setTitle: function (v) { this.$header.find(".fll").html(ke.ui.lang(v)); }, loadUrl: function (url, mustReload) { this.skin.url = url; if (this.skin.urlParms) url = url + this.skin.urlParms(); if (!this.skin.hidden || mustReload) { if (this.currentUrl != url || mustReload) { var fm = this.$body.find("iframe"); this.currentUrl = url; if (!fm.length) { this.$body.removeClass("scroller"); this.$body.html(""); if (this.skin.frameAutoHeight) { this.$body.find("iframe").bind("load", this, function (e) { e.data.skin.height = $(e.data.window().document.body).height(); e.data.resize(); // e.data.changeSize(true, null, $(e.data.window().document.body).height()); }); } } else fm.attr("src", url); } } return this; }, loadHtml: function (htm) { this.$body.html(htm); return this; }, window: function () { var r = this.find("iframe"); return r.length ? r[0].contentWindow : null; }, center: function () { var x = (this.skin.autoSizeBox.width() - this._width()) / 2; var y = (this.skin.autoSizeBox.height() - this._height()) / 2; this.css({ left: x, top: y }); this.skin.x = x; this.skin.y = y; } } /** * 绝对定位的悬浮层 */ $.fn.layer = function () { if (ke.ui.exists(this)) return ke.ui.find(this[0]); if (this[0].tagName != "BODY") {//所有层移动至body下 var el = this[0]; this.remove(); document.body.appendChild(el); this[0] = el; } return this._extend($.fn.panel, arguments); } $.fn.layer.defaults = { modal: false, //是否为模态 owner: null,//拥有者,弹出层的坐标定位将依赖于此对象,鼠标点击此对象不会隐藏层 syncOwnerWidth: false,//是否同步拥有者的宽度, syncOwnerHeight: false,//是否同步拥有得的高度 horizontal: "",//水平对齐方式 auto,ll,lr,rl,rr,center或空白(表示不需要计算,以层开始) vertical: "",//垂直对齐方式,支持 auto,tt,tb,bt,bb,center或空白(表示不需要计算,以层开始) allowOverflow: true,//是否允许溢出窗体外部 allowCoverOwner: true,//是否允许覆盖拥有者 ownerArrow: true,//显示指向 clickHide: true,//点击屏幕是否自动隐藏 clickSelfHide: false,//点击元素自身时是否自动隐藏 minWidth: 0, minHeight: 0, left: -1, top: -1 } $.fn.layer.methods = { initSkin: function () { $.fn.panel.methods.initSkin.call(this); this.skin.css += " layer"; this.skin.autoSizeBox = ke.ui; this.firstShow = true; if (this.skin.ownerArrow) this.skin.html = "
" + this.skin.html; }, initHandler: function () { $.fn.panel.methods.initHandler.call(this); if (this.skin.modal) { ke.mask(this.skin.id, true); this.bind("onShow", this, function (e) { ke.mask(e.data.skin.id, true); }); this.bind("destroy", this, function (e) { if (e.target == e.data[0]) ke.unMask(e.data.skin.id); }); this.bind("onHide", this, function (e) { ke.unMask(e.data.skin.id); }); } if (this.skin.minimizable) { this.$header.bind("dblclick", this, function (e) { e.data.minimumSize(); }); } //不设置宽高将自动认为是初次加载的自适应宽高 if (this.skin.width <= 0) this.skin.width = this._width(); if (this.skin.height <= 0) this.skin.height = this._height(); if (this.skin.ownerArrow) this.arrow = $(".triangle"); }, initSize: function (first) { $.fn.panel.methods.initSize.call(this, first); var sk = this.skin; var dr = new ke.rect(sk.left, sk.top, sk.width, sk.height); //x,y的定位基于水平、垂直对齐方式 var or = null; //指定了拥有者 if (sk.owner) { or = sk.owner._getRect(); if (sk.syncOwnerWidth) dr.width = or.width; if (sk.syncOwnerHeight) dr.height = or.height; if (!sk.allowCoverOwner && or) {//防止覆盖拥有者 var _bottom = ke.ui.winHeight - or.top - or.height; if (dr.height > or.top && dr.height > _bottom) { dr.height = (or.top > _bottom ? or.top : _bottom); } } } //限定了最小宽高 if (dr.width < sk.minWidth) dr.width = sk.minWidth; if (dr.height < sk.minHeight) dr.height = sk.minHeight; if (sk.state == "max") { //最大化 dr.width = ke.ui.winWidth; dr.height = ke.ui.winHeight; } else if (sk.state == "min") dr.height = this.$header._height(); else {//超出窗体大小 if (dr.width > ke.ui.winWidth) dr.width = ke.ui.winWidth - 10; if (dr.height > ke.ui.winHeight) dr.height = ke.ui.winHeight - 10; } this.$header._setSize(true, dr.width - this.pmb[0]); var h = dr.height - this.$header._height() - this.pmb[1]; this.$body._setSize(true, dr.width - this.pmb[0], h > 1 ? h : null); dr.height = this._height(); dr.width = this._width(); this.initPos(dr, or, sk); sk.left = dr.left; sk.top = dr.top; this.css(dr.getPos()); ke.ui.size(this); }, initPos: function (dr, or, sk) { if (sk.state == "max") dr.left = dr.top = 0; if (sk.state == "min") { dr.left = ke.ui.winWidth - dr.width; dr.top = ke.ui.winHeight - dr.height; } else { var fr = null; if (or) {//在8个区域中寻找最合适的 var rects = or.getSplitRects(ke.ui.winWidth, ke.ui.winHeight); var diff = -1; rects.forEach(function (d) { var temp = d.diff(dr); if (diff < 0 || temp < diff) { fr = d; diff = temp; if (temp <= 0) return; } }); } dr.left = this.calPosLeft(dr, or, sk, fr); dr.top = this.calPosTop(dr, or, sk, fr); var dir = this.initArrowDirect(dr, or, sk); if (!sk.allowOverflow) {//防止溢出屏幕 dr.left = dr.left < 0 ? 0 : dr.left; var dif = dr.left + dr.width - ke.ui.winWidth; if (dif > 0) dr.left -= dif; dr.top = dr.top < 0 ? 0 : dr.top; dif = dr.top + dr.height - ke.ui.winHeight; if (dif > 0) dr.top -= dif; } this.initArrowPos(dir, dr, or, sk); } }, calPosLeft: function (dr, or, sk, fr) { var max = ke.ui.winWidth; var align = (sk.horizontal || (fr && fr.horizontal)); var s = 0, e = max, val = dr.width; if (or) { s = or.left; e = or.left + or.width; } var r = dr.left; if (align == "auto") {//自动 align = "ll"; if (s + val > max && (s + val - max) > (val - e)) align = "rr"; } if (align == "center") { //居中对齐 var dif = (e - s - val) / 2; r = s + dif; } else if (align == "ll") //左左对齐 r = s; else if (align == "lr")//左右对齐 r = e; else if (align == "rl")//右左对齐 r = s - val; else if (align == "rr")//左右对齐 r = e - val; return r; }, calPosTop: function (dr, or, sk, fr) { var max = ke.ui.winHeight; var align = (this.skin.vertical || (fr && fr.vertical)); var s = 0, e = max, val = dr.height; if (or) { s = or.top; e = or.top + or.height; } s = s || 0; var r = dr.top; if (align == "auto") {//自动 align = "tb"; if (e + val > max && (s + val - max) > (val - e)) align = "bt"; } if (align == "center") { //居中对齐 var dif = (e - s - val) / 2; r = s + dif; } else if (align == "tt") //上上对齐 r = s; else if (align == "tb")//上下对齐 r = e; else if (align == "bt")//下上对齐 r = s - val; else if (align == "bb")//下下对齐 r = e - val; return r; }, initArrowDirect: function (dr, or, sk) { if (or && sk.ownerArrow) { if (!(dr.left >= or.getRight() || dr.getRight() <= or.left)) { if (or.top >= dr.top + dr.height && dr.top >= 6) { dr.top -= 8; return "bottom"; } else if (dr.top + dr.height >= or.top + or.height) { dr.top += 8; return "top"; } } else if (!(dr.top >= or.getBottom() || dr.getBottom() <= or.top)) { if (or.left >= dr.getRight() && dr.left >= 6) { dr.left -= 8; return "right"; } else if (dr.left >= or.getRight()) { dr.left += 8; return "left"; } } } return ""; }, initArrowPos: function (dir, dr, or, sk) { if (dir) { var r = this.arrow._getRect(); var cls = ""; if (dir == "bottom" || dir == "top") {//在元素上下 r.left = (or.left + (or.width - 16) / 2) - dr.left; r.left = (r.left < 5 ? 5 : r.left); r.top = (dir == "top" ? -8 : dr.height - 1); } else if (dir == "left" || dir == "right") { //在元素左右 r.top = (or.top + (or.height - 16) / 2) - dr.top; r.top = (r.top < 5 ? 5 : r.top); r.left = (dir == "left" ? -8 : dr.width - 1); } this.arrow.css(r.getPos()).removeClass().addClass("triangle triangle-" + dir).show(); } else if (this.arrow) this.arrow.hide(); }, documentClick: function (e) { var con = e.data; if (!con._showEvent || con._showEvent != event) { if (con.skin.clickHide) { if (!con.skin.hidden) { var ele = e.target; while (ele && !con.skin.clickSelfHide) { if (ele == con[0] || (con.skin.owner && con.skin.owner[0] == ele)) { return; } ele = ele.parentNode; } con.hide(); } } } }, minimumSize: function () { this.skin.state = (this.skin.state != "min" ? "min" : ""); if (this.skin.state == "min") { this.collapse(true); this.initSize(); } else { this.collapse(false); this.center(); } }, show: function () { this._showEvent = event; $.fn.component.methods.show.call(this); return this; }, showAt: function () { if (arguments.length > 1) { this.skin.left = arguments[0]; this.skin.top = arguments[1]; } else this.skin.owner = arguments[0]; this.show(); } } /** * 表单控件基类 * @settings {object} [可空] 配置项 */ $.fn.input = function () { this._extend($.fn.component, arguments); this.$text = null;//显示的文本 this.$value = null;//对应的存储值的域 this.selectedRow = null;//选中的数据行 return this; } $.fn.input.defaults = { type: "string",//get方法输出的数据类型 inline: false,//是否启用内联布局 nullable: true,//是否可空 disabled: false,//是否禁用 readonly: false, textField: "name", //显示文本对应数据源中的字段 valueField: "num",//显示值对应数据源中的字段 autoCreateStore: true,//是否从DOM中寻找并生成数据源 onChange: null, //change事件对应的函数 value: "",//初始默认值 placeholder: "", //水印, reg: "",//验证值的正则表达式, iconCls: "",//图标样式类 iconClsPosition: "left",//图标位置,默认为左边 store: null,//数据源 table类型 multiple: false,//是否支持多选 separator: ",", //如果多选情况下值连接符 clickShowLayer: true,//鼠标点击时显示层 valueInStore: false,//值是否必须在数据源里存在 union: null //映射,形式如:{ rate:TaxRate } 填充后形成联动,表示将行值 rate 填充至 TaxRate控件里 } $.fn.input.methods = { /** * 控件外观与生成 */ initSkin: function () { var sk = this.skin; var sklayer = sk.layerOptions; sk.css += " input"; sk.formatContent = true; sk.outputAttr = false; sk.isInput = true; sk.legal = true;//值是否合法 sk.css += (sk.inline ? " inline-block" : ""); sk.attributes += (sk.placeholder ? " placeholder=\"" + sk.placeholder + "\"" : ""); sk.attributes += (sk.readonly ? " readonly=\"readonly\"" : ""); sklayer.syncOwnerWidth = true; sklayer.allowCoverOwner = false; sklayer.allowOverflow = false; sklayer.ownerArrow = false; sklayer.minWidth = (sklayer.minWidth || 120); sklayer.bodyCls = "input-layer"; if (ke.ui.mobile) { sklayer.vertical = "bb"; sklayer.syncOwnerWidth = false; sklayer.width = ke.ui.winWidth; sklayer.height = ke.ui.winHeight / 2; sklayer.modal = true; } if (sk.store) this.store = sk.data.store; else if (sk.autoCreateStore) this.store = ke.createStore(this[0]); if (sk.data.tooltip) this.skin.hasTooltip = true; }, initHandler: function () { var con = this; if (!con.$value) { con.$value = con.find("input[type='text']"); con.$text = con.find("input[type='text']"); } con.$text.bind("blur", con, function (e) { e.data.removeClass("focus"); }); con.$text.bind("change", con, function (e) { e.data.validate(); e.data.change(); }); con.$text.bind("focus", con, function (e) { e.data.addClass("focus"); }); con.bind("layerShowAfter", this, function (e) { e.data.layerCompnent.find(".panel-body div").click(function (t) { e.data.itemClick(t.target); }); e.data.layerCompnent.find(".data-select-header .fll").click(function () { e.data.layerHide(); }) }); con.setTitle(con.skin.title); con.setIconCls(con.skin.iconCls, true, con.skin.iconClsPosition); }, initSize: function (first) { var con = this; var w = con.skin.width; if (w <= 1) { if (!con.skin.inline) w = con.autoSizeBox.width() * (w > 0 ? w : 1); } if (w > 0) { var css = con._setSize(true, w); w = css.width; var items = con.children(); for (var i = 0; i < items.length; i++) { if (items[i].className.indexOf("box") < 0) w -= $(items[i])._width(); } con.$text._setSize(true, w - con.find(".icon-btn")._width() - con.find("i")._width() - 2); } if (con.skin.height > 1) { con._setSize(true, null, con.skin.height); } if (first) { if (this.store) this.bindStore(this.store); if (this.skin.onChange) this.change(this.skin.onChange); if (!ke.ui.mobile) this.skin.layerOptions.owner = this.find(".box"); else this.skin.layerOptions.owner = null; this.disable(this.skin.disabled); if (this.skin.value != null && this.skin.value !== "") this.set(this.skin.value);//设置默认值 } }, /** * 绑定数据源,子类可重载 */ bindStore: function (store) { this.store = store; if (!ke.ui.mobile && !this.hasBindStoreClick && store && this.skin.clickShowLayer) { this.hasBindStoreClick = true; this.find(".box").click(this, function (e) { e.data.showLayer(); }); } this.set(this.get()); }, /** * 覆盖jquery原生方法 */ focus: function () { setTimeout(this.skin.id + ".$text.focus();", 100); return this; }, blur: function (data, fun) { ke.bindOrTrriger(this.$text, "blur", arguments); }, disable: function (v) { this.skin.disabled = v; if (v) { this.$text.attr("disabled", true); this.addClass("disabled"); } else { this.$text.removeAttr("disabled"); this.removeClass("disabled"); } return this; }, readonly: function (v) { this.skin.readonly = v; if (v) this.$text.attr("readonly", "readonly"); else this.$text.removeAttr("readonly"); }, change: function () { ke.bindOrTrriger(this, "keChange", arguments); if (arguments.length < 1) ke.ui.trigger("inputChange", this); }, val: function () { if (arguments.length == 0) return this.$value.val(); else this.set(arguments[0]); }, /** * 扩展方法表单控件的共性方法 */ setTitle: function (val) { // this.skin.title = val; var el = this.children("label"); if (val) { val = ke.ui.lang(val); if (this.skin.hasTooltip) val += ""; if (el.length) el.html(val); else this.prepend(""); } else el.remove(); }, setIconCls: function (v, first, pos) { if (v) { if (pos == "left") this.find(".box").prepend(""); else this.find(".box").append(""); } else if (!first) this.find(".box").find("i").remove(); }, validate: function () { var val = this.get(ke.types.string); var r = this.skin.nullable || val != ""; if (r && val != "" && this.skin.reg) r = val.match(this.skin.reg); this.find(".box").toggleClass("illegal", !r); this.skin.legal = r; return r; }, select: function (i) { this.layerHide(); this.set(this.store.rows[i].get(this.skin.valueField)); this.change(); }, getText: function (v) { return this.$text.val(); }, unionSet: function () { var data = (this.selectedRows.length ? this.selectedRows[0] : {}); var u = this.skin.union; for (var f in u) { if (u[f] != null) { u[f].set(data[f]); } } }, set: function (v) { var con = this; con.selectedRows = []; if (con.store) { var st = con.store; var vals = (v == null ? "" : v).toString().split(con.skin.separator); for (var i = 0; i < st.rows.length; i++) { var d = st.rows[i].data; var key = d[con.skin.valueField]; if (!con.skin.multiple) { if (key == v) { this.selectedRows.push(d); } } else { if (vals.indexOf(key) > -1) this.selectedRows.push(d); } } if (con.skin.valueInStore) { v = this.selectedRows.joinField(con.skin.valueField, this.skin.separator); } this.unionSet(); } con.$value.val(v); con.validate(); return this; }, setTriggerChange: function (v) { this.set(v); this.change(); }, get: function (type) { return ke.convert(this.$value.val(), type || this.skin.type); }, itemClick: function (dom) { var val = null; while (val == null && dom && dom.tagName != "BODY") { val = dom.getAttribute("data-value"); dom = dom.parentNode; } if (val) { var con = this; if (!con.skin.multiple) con.setTriggerChange(val); else { var items = con.get().split(con.skin.separator); var index = items.indexOf(val); if (index > -1) items.splice(index, 1); else items.push(val); con.setTriggerChange(items.join(con.skin.separator)); } this.layerHide(); } }, selectedRows: [] } /** * 按钮基础类 * @settings {object} [可空] 配置项 */ $.fn.button = function () { if (ke.ui.exists(this)) return ke.ui.find(this[0]); return this._extend($.fn.component, arguments); } $.fn.button.defaults = { disabled: false,//是否禁用 layerHtml: "",//点击展示的菜单内容 iconCls: "",//图标样式类 iconClsPosition: "left",//图标位置,默认为左边 onClick: null //点击事件 } $.fn.button.methods = { initSkin: function () { this.skin.css += " button inline-clear unselect"; this.skin.html = "
"; if (!this.skin.layerHtml) this.skin.layerHtml = this.html().trim(); this.skin.layerOptions.clickSelfHide = true; }, initHandler: function () { if (this.skin.onClick) this.click(this.skin.onClick); this.set(this.skin.title); this.setIconCls(this.skin.iconCls, true, this.skin.iconClsPosition); }, setIconCls: function (v, first, pos) { if (v) { if (pos == "left") this.find(".box").prepend(""); else this.find(".box").append(""); } else if (!first) this.find(".box").find("i").remove(); }, initSize: function (first) { var con = this; var w = con.skin.width; var h = con.skin.height; con._setSize(true, con.skin.width, con.skin.height); if (first) { this.disable(this.skin.disabled); if (this.skin.layerHtml) { this.skin.layerOptions.owner = this; this.layerHtml = function () { return this.skin.layerHtml; } this.click(this, function (e) { e.data.showLayer(); }); } } }, disable: function (v) { this.skin.disabled = v; this.toggleClass("disabled", v); return this; }, set: function (v) { var box = this.find(".box div"); if (v) v = ke.ui.lang(v); box.html(v); box.toggle(v != null && v !== ""); return this; }, show: function () { this[0].style.display = "inline-block"; this.skin.hidden = false; this.initSize(); this.trigger("onShow"); return this; }, setMsg: function (i) { var con = this.children(".button-msg"); if (i > 0) { if (!con.length) this.append("
" + i + "
"); else con.find("span").html(i); } else con.remove(); return this; } } //窗体 $.fn.window = function (config) { if (ke.ui.exists(this)) return ke.ui.find(this[0]); var con = this.layer(config); con.skin.parse({ closable: true,//显示关闭按钮 collapsible: true,//折叠 minimizable: true,//最小化 maximizable: true,//最大化 draggable: true, clickHide: false, ownerArrow: false, horizontal: "center", vertical: "center" }); con.skin.className += " window"; if (con.skin.draggable) con.skin.className += " draggable"; return con; } $.fn.window.create = function (config, html) { $(document.body).append("
" + html + "
"); var con = $("#" + config.id).window(config).render(); if (config.title && !config.height) con.changeSize(null, con.skin.height); return con; } //提示工具 $.fn.tooltip = function () { this.removeClass("keui-tooltip"); this.mouseover(function (e) { $.fn.tooltip.owner = $(this); setTimeout("$.fn.tooltip.show();", 500); }); this.click(function (e) { $.fn.tooltip.hide(); }); this.mouseout(function () { $.fn.tooltip.hide(); }); } $.fn.tooltip.render = function ($el) { var tips = $el ? $el.find(".keui-tooltip") : $(".keui-tooltip"); tips.each(function (i, d) { $(d).tooltip(); }); } $.fn.tooltip.show = function () { if ($.fn.tooltip.owner) { var config = { id: 'ke_tooltip', css: 'tooltip ', horizontal: 'center', vertical: 'auto', ownerArrow: true, allowOverflow: false, clickSelfHide: true }; ke.ui.destroy($.fn.tooltip.con); var tip = $.fn.tooltip.owner.attr("data-tooltip"); var con = $.fn.window.create(config, tip); con.showAt($.fn.tooltip.owner); con.$body.css({ height: "auto", width: "auto" }); $.fn.tooltip.con = con; } } $.fn.tooltip.hide = function () { if ($.fn.tooltip.con) $.fn.tooltip.con.hide(); $.fn.tooltip.owner = null; } //消息层 $.messager = { alter: function (msg, callback, icon) { this.show({ msg: msg, btnNo: false, callback: callback, modal: true, icon: (icon || "info") }); }, confirmMsg: function (msg, callback) { this.show({ title: "系统提示", msg: msg, callback: callback, modal: false, btnNo: false }); }, confirm: function (title, msg, callback, icon) { this.show({ title: title, msg: msg, callback: callback, modal: true, icon: (icon || "question") }); }, prompt: function (title, msg, callback, inputSelectItems) { this.show({ title: title, msg: msg, showInput: true, btnNo: true, callback: callback, modal: true, icon: "", inputSelectItems: inputSelectItems }); }, notify: function (msg, sec, config) { config = config || {}; config = $.extend({ id: "ke_messager_notify", msg: msg, btnNo: false, btnYes: false, btnClose: true, modal: false, callback: config.callback, center: false, css: "notify ", horizontal: config.horizontal || "center", vertical: config.vertical || "tt", animate: true }, config); var con = this.show(config); if (config.animate) { var w = con._width(); var h = con._height(); var from = { left: w * -1, top: 10 }; var to = { left: 10, top: 10 }; var cls = "left"; if (con.skin.horizontal == "center") { from = { top: h * -1 }; to = { top: 10 }; cls = "top"; if (con.skin.vertical == "bb") { cls = "bottom"; from = { top: ke.ui.winHeight }; to = { top: ke.ui.winHeight - h - 10 }; } else if (con.skin.vertical == "center") { cls = "center"; from = { top: con.skin.y - h }; to = { top: con.skin.y }; } } else if (con.skin.horizontal != "ll") { cls = "right"; from.left = ke.ui.winWidth; to.left = ke.ui.winWidth - w - 10; } con.skin.from = from; con.addClass("notify-" + cls).css(from); con.animate(to); } var evt = con.skin.id + "_evt"; clearTimeout($.messager[evt]); $.messager[evt] = setTimeout("$.messager.notifyHide(ke.ui.find('" + con.skin.id + "'))", sec || 5000); }, notifyHide: function (con) { if (con) { con.animate(con.skin.from, function () { ke.ui.destroy(con); }); } }, show: function (config) { var opt = new ke.options(null, config); opt.parse($.messager.defaults); config.maximizable = false; config.minimizable = false; config.width = 450; config.id = opt.id; ke.ui.destroy(ke.ui.find(opt.id)); var cols = 1; var htm = ""; if (opt.icon) { htm += ""; cols++; } htm += ""; if (opt.btnClose) { htm += ""; cols++; } htm += ""; if (opt.showInput) { htm += "" } htm += "
{ke.ui.lang(d.msg)}
"; if (opt.inputSelectItems) htm += ke.formatForeach("", opt.inputSelectItems); htm += "
"; var btns = ""; if (opt.btnYes) btns += "
{ke.ui.lang('确认')}
"; if (opt.btnNo) btns += "
{ke.ui.lang('取消')}
"; if (btns) btns = "
" + btns + "
"; htm += btns + "
"; config.css = " messager " + (config.css || ""); var con = $.fn.window.create(config, new ke.template(htm).render(opt, 0)); con.opt = opt; this.initHandler(con); if (opt.showInput) con.controls[0].set(opt.defaultValue); return con; }, initHandler: function (con) { con.find(".icon-cross").click(con, function (e) { $.messager.notifyHide(con); }); con.find(".btn").click(con, function (e) { var obj = $(e.target); if (obj.hasClass("btn-yes")) { con.hide(); if (con.opt.callback) con.opt.callback(con.opt.showInput ? con.controls[0].get() : ""); ke.ui.destroy(con); } else if (obj.hasClass("btn-cancel")) ke.ui.destroy(con); }); } } $.messager.defaults = { title: "", msg: "", btnYes: true, btnNo: true, btnClose: false, showInput: false, defaultValue: "", id: "ke_messager", icon: "info",//error,question,info,warning,ok modal: false, center: true, callback: null, inputOptions: null, inputSelectItems: null, height: null } ke.openWindow = function (title, url, w, h, config) { var id = "ke_open_window"; ke.ui.destroy(ke.ui.find(id)); $(document.body).append("
"); config = config || {}; config.title = title; config.url = url; config.width = w; config.height = h; var con = $("#" + id).window(config).render(); return con; } })(jQuery);