//------------------------------- 版本演化 ---------------------------------- // 20131205 : 加强了elagent.val()对integer和real的输出校验,将nan转换为0 // 20131201 : 为tree.editor增加字符串属性moveproc,用于替换标准的move动作远程调用名 // 20131121 : 为elagent增加p方法,实际就是span和text方法的组合,用于快速创建字符串。 // 20131120 : 为elagent增加了getoffsety(el)计算元素相对于el的相对y坐标和getoffsetx(el)计算元素相对于el的相对x坐标两个方法 // 为window,rswindow,box增加了clientreset方法,清空窗口client内的所有东西包括layout,使窗口就象才创建的新窗口一样,可以重新使用. // 20131118 :在tree.editor的元素项目对象上增加了moveto方法来调整树的显示顺序,包括对子元素的调整,使之在dict模块能保持树型顺序, //       同时增加了movegui方法来提供一个基于简单对话框sk.dlg.dialog的基本移动操作界面,当然应用也可自行构造界面,最后调用moveto来实施移动。 //       这是目前tree.editor唯一直接操作数据库的方法,必须对可写对象,即type=字典类型字符串的从数据库加载的对象且定义有op.sidmask数组, //       否则运行出错。 // 20131115 : 在sk中加入了tree子类,目前内有editor方法用来创建一个树编辑器(也可只读)框架; //       为elagent加入了layout方法,功能和sk.dlg.window等上的layout功能相同。 // 20131114 : 在sk.kit中引入了外来代码构成新的方法,sk.kit.numbertochinese,用于将数字转换为中文格式,如:123转换为一百二十三 // 20131112 : 去除了gridview和scgridview中自动加入window.resize消息处理列表的动作,因为当表格被安装在window或dialog或rswindow或box里的时候, // 是不需要同时也不应该在window.resize里进行调整的。所以现在要求应用程序自已根据情况进行调整处理即对adjust方法的调用。 // 20131110 : 有三处修改 // 一.为elagent增加了一个生成弹出菜单的方法menu(text, w, op, createmenufunc); // text:菜单文字; w:弹出的菜单宽度; op:菜单柄abutton的创建op // createmenufunc:创建菜单内容的回调函数,以弹出的菜单合box为this, // 可在函数内调用this上的addmenuitem,addmenuline函数构建菜单,这些是popbox中的tomenu内定义的函数. // 返回菜单box对象 // 二.强化了elagent对象上的attr和css方法,使其当只输入一个参数时,当参数是字符串时,返回指定的属性值, // 如果是这个参数是对象则按{"属性名1":"属性值1","属性名2":"属性值2",....}进行一组属性设置 // 当输入两个参数时,则只用后一个参数设置前一个参数指定的属性名 // 三.为window,rswindow,box的close方法增加了一个可选参数close(just)当just=true或为窗口增加了justclose=true内部标志时不进行延迟关闭, // 而是立即开始关闭过程,默认则为延迟关闭,当某些应用要严格依赖窗口关闭顺序时就需要以just=true调用close或在该窗口上附加justclose=true. // 但一般情况下,当窗口关闭动作被whenclose阻断或在其中弹出过系统框如alert等时,为正常清理一些窗口附属物则应just=false且不指定justclose. // 20131108 : 将sdict模块做为可选功能移入sk范围,用initstaticdict函数调用来启用,移入的原因是这个模块也是一种基础功能 // 但这个模块依赖外部的js字典文件,对格式是有要求的,具体结构如下 // window.sdict['dwxz']=[{"v":"10000162","t":"xxx","p":"0","c":"gyqy","pc":null},{"v":"10000185","t":"fdsaffew","p":"0","c":null,"pc":null}]; // v:字典代码(数字); // c:字典的附加代码(字符); // t:字典字面值; // p:字典项的上级代码v(可用totree()构建多层字典结构,p=0为顶级项目; // pc:字典项目的控制数据,可用于描述特定的字典项目对应的功能或功能参数,可以为数字,字符,对象,数组等 // 通过totree()后将根据p的指向将字典构建为树型,在child中包含子节点数组 // 20131107 : 为可编辑的gridview的可编辑列定义增加了更多的功能标志,具体如下,完整定义说明在4276行附近 // sbc : 有自动转半角功能 // trim : 去头尾空格 // int : 整数录入 // uint : 正整数录入 // real : 小数录入 // 20131031 : 对window\box\rswindow的close方法和内部函数mup进行修正,以使关闭过程被whenclose阻塞时消息能以正确顺序进行, //       特别是关闭被whenclose中止后的处理和对agent_bk的清理. // 20131022 : 修改了input.xm,trim,sfz等方法的内部事件绑定方式,改用addevent进行,以防止应用代码修改onblur属性使功能意外丧失。 // 增加input.uint,.int,.real的val()方法返回值前进行int(v)或float(v)变换 // 20131018 : 修正array.clear中严重错误,之前的无法工作。 // 20131017 : 修正了jsonobject和array的tojson方法中的错误,使多维数组可以正确转换,同时增加了array的clone方法 // 20131010 : 修正了scgridview中的opt类单元格中高度限定无效的问题 // 20130913 : 修正了element 中的方法removeclass, replaceclass内包含的错误,该错误会引起第一个class不能被操作 // 20130926 : 引入了一些外来代码,扩展了一些新的功能函数。 // // 20140430 : 修正getoffsetx、getoffsety在计算含有滚动区域时结果错误的问题。 // 20140512 : 为scrollgrid加入了scrollsave和scrollstore函数用来保存和恢复表格的滚动位置 // 20140901 : 在element 中加入了方法iframewithsrc即通过外部文件建立一个iframe对象 // 20141217 : 为可编辑的gridview的可编辑单元格增加了able函数接口, // if (this.op.able) // return this.op.able.call(this, this.rownumb, this.colnumb); // else // 缺省的able函数 // return this.ctrol.celleditable(this.rownumb, this.colnumb); // 使应用可以控制每一个单元格的可编辑性,this = 可编辑单元格对象. // // 20150407 : 参照jquery中的ajax部分的相关代码,对sk.ajax中的返回处理流程进行修改,以提高适应性。 // 修正input.downlistbox中的位置处理错误 // // 20200115 : 针对chrome内核对grid的按建处理进行修补。增加scgridview通过拖动表头列修改列宽的功能,并新增 // getcolwidth(colindex)和setcolwidth(colindex, newwidth)两个方法函数。 // 可以在scgridview实例上定义colsetwidthafter方法用于在列宽被修改后自动被调用以进行后续处理。 // // 20200528 : 在element中增加 uploadlargefile 方法,提供基于html5和ajax的大文件分块上传按钮。 //----------------------------------------------------------------- //============================================================================================================= // 服务器端-->客户器端时的数据转换 function c(v) {return v?v:'';} function s(v) {return v==null||v==''?null:v;} // 从日期时间中取日期部分 function d(s) { if (s == null||s == '') return ''; return s.split(' ')[0]; } function int(v) {return parseint(v, 10);} function float(v) {return parsefloat(v);} (function(){ if (window.json) { string.prototype.json_parse = function () { try { return window.json.parse(this); } catch (e) { throw error(this); } }; } else { string.prototype.json_parse = function () { return eval("(" + this + ")"); }; } // 字符串转换 function md5(smessage) { function rotateleft(lvalue, ishiftbits) {return (lvalue<>>(32-ishiftbits));} function addunsigned(lx,ly) { var lx4,ly4,lx8,ly8,lresult; lx8 = (lx & 0x80000000); ly8 = (ly & 0x80000000); lx4 = (lx & 0x40000000); ly4 = (ly & 0x40000000); lresult = (lx & 0x3fffffff)+(ly & 0x3fffffff); if (lx4 & ly4) return (lresult ^ 0x80000000 ^ lx8 ^ ly8); if (lx4 | ly4) { if (lresult & 0x40000000) return (lresult ^ 0xc0000000 ^ lx8 ^ ly8); else return (lresult ^ 0x40000000 ^ lx8 ^ ly8); } else return (lresult ^ lx8 ^ ly8); } function f(x,y,z) {return (x & y) | ((~x) & z);} function g(x,y,z) {return (x & z) | (y & (~z));} function h(x,y,z) {return (x ^ y ^ z);} function i(x,y,z) {return (y ^ (x | (~z)));} function ff(a,b,c,d,x,s,ac) { a = addunsigned(a, addunsigned(addunsigned(f(b, c, d), x), ac)); return addunsigned(rotateleft(a, s), b); } function gg(a,b,c,d,x,s,ac) { a = addunsigned(a, addunsigned(addunsigned(g(b, c, d), x), ac)); return addunsigned(rotateleft(a, s), b); } function hh(a,b,c,d,x,s,ac) { a = addunsigned(a, addunsigned(addunsigned(h(b, c, d), x), ac)); return addunsigned(rotateleft(a, s), b); } function ii(a,b,c,d,x,s,ac) { a = addunsigned(a, addunsigned(addunsigned(i(b, c, d), x), ac)); return addunsigned(rotateleft(a, s), b); } function converttowordarray(smessage) { var lwordcount; var lmessagelength = smessage.length; var lnumberofwords_temp1=lmessagelength + 8; var lnumberofwords_temp2=(lnumberofwords_temp1-(lnumberofwords_temp1 % 64))/64; var lnumberofwords = (lnumberofwords_temp2+1)*16; var lwordarray=array(lnumberofwords-1); var lbyteposition = 0; var lbytecount = 0; while ( lbytecount < lmessagelength ) { lwordcount = (lbytecount-(lbytecount % 4))/4; lbyteposition = (lbytecount % 4)*8; lwordarray[lwordcount] = (lwordarray[lwordcount] | (smessage.charcodeat(lbytecount)<>>29; return lwordarray; } function wordtohex(lvalue) { var wordtohexvalue="",wordtohexvalue_temp="",lbyte,lcount; for (lcount = 0;lcount<=3;lcount++) { lbyte = (lvalue>>>(lcount*8)) & 255; wordtohexvalue_temp = "0" + lbyte.tostring(16); wordtohexvalue = wordtohexvalue + wordtohexvalue_temp.substr(wordtohexvalue_temp.length-2,2); } return wordtohexvalue; } var x=array(); var k,aa,bb,cc,dd,a,b,c,d; var s11=7, s12=12, s13=17, s14=22; var s21=5, s22=9, s23=14, s24=20; var s31=4, s32=11, s33=16, s34=23; var s41=6, s42=10, s43=15, s44=21; // steps 1 and 2. append padding bits and length and convert to words x = converttowordarray(smessage); // step 3. initialise a = 0x67452301;b = 0xefcdab89;c = 0x98badcfe;d = 0x10325476; // step 4. process the message in 16-word blocks for (k=0;k/g,'>'); str = str.replace(/"/g,'"'); str = str.replace(/\n/g,'
'); str = str.replace(/ /g,' '); return str; } function eschtag(str) { if (!str) return str; // str = str.replace(/&/g,'&'); // str = str.replace(/"/g,'"'); str = str.replace(/\n/g,'
'); // str = str.replace(/ /g,' '); return str; } function isallchinese(temp) { var re=/[^\u4e00-\u9fa5]/; if(re.test(temp)) return false; return true; } function dbc2sbc(str) { var result = ''; for (var i=0 ; i= 65281 && code <= 65373) { //在这个unicode编码范围中的是所有的英文字母已经各种字符 result += string.fromcharcode(str.charcodeat(i) - 65248);//把全角字符的unicode编码转换为对应半角字符的unicode码 } else if (code == 12288) {//空格 result += string.fromcharcode(str.charcodeat(i) - 12288 + 32); } else { result += str.charat(i); } } return result; } function todate(str){ if(!str.match(/^\d{4}\-\d\d?\-\d\d?$/)) return null; var ar=str.replace(/\-0/g,"-").split("-"); return new date(ar[0],ar[1]-1,ar[2]); } // 测试一个字符串中的内容是否是一个合法的日期,是则返回yyyy-mm-dd格式(不足两位的月日将在前面补0) function formatdate(str){ if(!str.match(/^\d{4}\-\d\d?\-\d\d?$/)) return null; var ar = str.replace(/\-0/g,"-").split("-"); var d = new date(ar[0],ar[1]-1,ar[2]); if(d.getfullyear()==ar[0] && d.getmonth()==ar[1]-1 && d.getdate()==ar[2]) return ar[0] + '-' + ((parseint(ar[1])+100)+'').substr(1) + '-' + ((parseint(ar[2])+100)+'').substr(1); else return null; } function chinadate(dstr) { var tab = ['〇','一','二','三','四','五','六','七','八','九', '十','十一','十二','十三','十四','十五','十六','十七','十八','十九', '二十','二十一','二十二','二十三','二十四','二十五','二十六','二十七','二十八','二十九','三十', '三十一']; var da = dstr.split('-'); if (da.length != 3) return null; var ret = ''; ret += tab[parseint(da[0].substr(0,1),10)]; ret += tab[parseint(da[0].substr(1,1),10)]; ret += tab[parseint(da[0].substr(2,1),10)]; ret += tab[parseint(da[0].substr(3,1),10)] + '年'; ret += tab[parseint(da[1],10)] + '月'; ret += tab[parseint(da[2],10)] + '日'; return ret; } function chinadate2(dstr) { var da = dstr.split('-'); if (da.length != 3) return null; var ret = ''; ret += parseint(da[0],10) + '年'; ret += parseint(da[1],10) + '月'; ret += parseint(da[2],10) + '日'; return ret; } function ss(v) {return (v==null || v.length==0)?null:v + '';} function strdefault(v, d) {return (v.length==0?d + '':v + '');} // 字符串比较和校验 function isimgfilename(fn) {return (/^.+\.(gif|jpg|jpeg|png|bmp)$/i.test(fn.tolowercase()));} function isemail(mail) { var patrn=/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/; return patrn.exec(mail); } function isdate(str){ if(!str.match(/^\d{4}\-\d\d?\-\d\d?$/)) return false; var ar=str.replace(/\-0/g,"-").split("-"); var d = new date(ar[0],ar[1]-1,ar[2]); return d.getfullyear()==ar[0] && d.getmonth()==parseint(ar[1])-1 && d.getdate()==ar[2]; } //验证中国电话号码 function isphone(str) { var reg = /^([0-9]|[\-])+$/g; if (str.length < 7 || str.length > 18) { return false; } else { return reg.test(str); } } function isdatetime(str){ var r=str.match(/^(\d{4})-(\d{1,2})-(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/); if(r==null) return false; var d= new date(r[1],r[2]-1,r[3],r[4],r[5],r[6]); if(d.getfullyear()!=r[1]) return false; if(d.getmonth()+1!=r[2]) return false; if(d.getdate()!=r[3]) return false; if(d.gethours()!=r[4]) return false; if(d.getminutes()!=r[5]) return false; if(d.getseconds()!=r[6]) return false; return true; } // 比较字符串相对于服务器端是否发生了变化,主要在于null和''在此被认为是相同的值 function equ(v1, v2) {return ss(v1) == ss(v2);} // 检查值是否对于服务器端为空值 function empty(v) {return v==null||v.trim()=='';} string.prototype.md5 = function() {return md5(this);}; string.prototype.esctag = function() {return esctag(this);}; string.prototype.eschtag = function() {return eschtag(this);}; string.prototype.dbc2sbc = function() {return dbc2sbc(this).trim();}; string.prototype.todate = function() {return todate(this);}; string.prototype.formatdate = function() {return formatdate(this);}; string.prototype.chinadate = function() {return chinadate(this);}; string.prototype.chinadate2 = function() {return chinadate2(this);}; string.prototype.uri = function() {return encodeuricomponent(this);}; string.prototype.trim = function() {return this.replace(/(^\s*)|(\s*$)/g, "");}; string.prototype.ltrim = function() { return this.replace(/(^\s*)/g, ""); }; string.prototype.rtrim = function() { return this.replace(/(\s*$)/g, ""); }; string.prototype.replaceall = function(oldstr,restr){return this.split(oldstr).join(restr);}; // 外来代码 string.prototype.isallchinese = function() {return isallchinese(this);}; string.prototype.replace2 = function(str1, str2) {return this.replace(new regexp(str1, "gm"), str2);}; string.prototype.startwith = function(str) {var reg = new regexp("^" + str); return reg.test(this);}; /*字符串以str开始*/ string.prototype.endwith = function(str) {var reg = new regexp(str + "$"); return reg.test(this);}; /*字符串以str结束 */ string.prototype.getextension = function() {var ret = this.match(/\.([^\.]+)$/i); return (ret == null ? '' : ret[1]);}; /*获取文件后缀,如xx.doc返回doc*/ string.prototype.reverse = function() {//字符串倒序 var temp = new array(); for (var i = this.length - 1; i > -1; i--) { temp.push(this.charat(i)); } return temp.join("").tostring(); }; //字符串实际长度(全角、汉子为2个字符),对于纯utf-8编码的应用(包括后端数据库)无用 string.prototype.bytelen = function() { var arr = this.match(/[^\x00-\xff]/ig); return this.length + (arr == null ? 0 : arr.length); }; string.prototype.default = function(v) {return strdefault(this, v);}; string.prototype.s = function() {return ss(this);}; string.prototype.isimgfilename = function() {return isimgfilename(this);}; string.prototype.isemail = function() {return isemail(this);}; string.prototype.isphone = function() {return isphone(this);}; string.prototype.isdate = function() {return isdate(this);}; string.prototype.isdatetime = function() {return isdatetime(this);}; string.prototype.equ = function(v){return equ(this, v);}; string.prototype.empty = function() {return empty(this);}; //是否是数字,外来代码 string.prototype.isnumeric = function(flag) { if (isnan(this)) { return false; } switch (flag) { case "": //参数为空,与"f"条件一样 return /(^-?|^\+?|^\d?)\d*\.\d+$/.test(this); case "+": //正数 return /(^\+?|^\d?)\d*\.?\d+$/.test(this); case "-": //负数 return /^-\d*\.?\d+$/.test(this); case "i": //整数 return /(^-?|^\+?|\d)\d+$/.test(this); case "+i": //正整数 return /(^\d+$)|(^\+?\d+$)/.test(this); case "-i": //负整数 return /^[-]\d+$/.test(this); case "f": //浮点数 return /(^-?|^\+?|^\d?)\d*\.\d+$/.test(this); case "+f": //正浮点数 return /(^\+?|^\d?)\d*\.\d+$/.test(this); case "-f": //负浮点数 return /^[-]\d*\.\d$/.test(this); default: //缺省 return true; } }; //只能输入数字,外来代码,尚不完善 string.prototype.numeric = function(flag) { //alert(this); switch (flag) { case "": //参数为空,与"f"条件一样 return this.replace(/(^-?|^\+?|^\d?)\d*\.\d+$/, ""); case "+": //正数 return this.replace(/(^\+?|^\d?)\d*\.?\d+$/, ""); case "-": //负数 return this.replace(/^-\d*\.?\d+$/, ""); case "i": //整数 return this.replace(/(^-?|^\+?|\d)\d+$/, ""); case "+i": //正整数 return this.replace(/[^\d]/g, ''); case "-i": //负整数 return this.replace(/^[-]\d+$/, ""); case "f": //浮点数 return this.replace(/(^-?|^\+?|^\d?)\d*\.\d+$/, ""); case "+f": //正浮点数 return this.replace(/(^\+?|^\d?)\d*\.\d+$/, ""); case "-f": //负浮点数 return this.replace(/^[-]\d*\.\d$/, ""); default: //缺省 return this; } }; date.prototype.string = function() {return this.getfullyear() + '-' + ((this.getmonth() + 101) + '').substr(1,2) + '-' + ((this.getdate() + 100) + '').substr(1,2);}; date.prototype.string = function() { return this.getfullyear() + '-' + ((this.getmonth() + 101) + '').substr(1,2) + '-' + ((this.getdate() + 100) + '').substr(1,2) + ' ' + ((this.gethours() + 100 + '').substr(1,2)) + ':' + ((this.getminutes() + 100 + '').substr(1,2)) + ':' + ((this.getseconds() + 100 + '').substr(1,2)); }; boolean.prototype.tojson = function(){return this;}; function.prototype.tojson = function(){return this;}; number.prototype.tojson = function(){return this;}; regexp.prototype.tojson = function(){return this;}; // strict but slow string.prototype.tojson = function(){ var tmp = this.split(""); for(var i=0;i= ' ') ? (c == '\\') ? (tmp[i] = '\\\\'): (c == '"') ? (tmp[i] = '\\"' ): 0 : (tmp[i] = (c == '\n') ? '\\n' : (c == '\r') ? '\\r' : (c == '\t') ? '\\t' : (c == '\b') ? '\\b' : (c == '\f') ? '\\f' : (c = c.charcodeat(),('\\u00' + ((c>15)?1:0)+(c%16))) ); } return '"' + tmp.join("") + '"'; }; array.prototype.tojson = function(){ for(var i=0,json=[];i= 0; i--) func(this[i], i); }; array.prototype.first = function() { if (this.length > 0) return this[0]; else return null; }; array.prototype.last = function() { if (this.length > 0) return this[this.length - 1]; else return null; }; array.prototype.has = function(v) { for (var i = 0; i < this.length; i++) if(this[i] == v) return true; return false; }; array.prototype.count = function() {return this.length;}; array.prototype.clear = function() {this.length = 0;}; array.prototype.getdata = function() {return this;}; array.prototype.clone = function() {return eval("("+this.tojson()+")");}; // 对函数的运行上下文进行绑定 function.prototype.bind = function(context) { var fn = this; return function() {return fn.apply(context, arguments);}; }; // 对函数进行节流,如果在小于指定的时间间隔内频繁调用这个函数,则进行节流,以防止系统过于繁忙 function.prototype.throttel = function(context, ms) { var fn = this; return function() { if (fn.tid) { cleartimeout(fn.tid); } var p = arguments; fn.tid = settimeout(function(){fn.apply(context, p);}, ms?ms:100); }; }; // --- 以上为对原生对象string, date, array, function的扩展 // 以下为工具包sk window.sk = { browser : null, _browser : '', nop : function() {}, isobject : function(v) {return typeof v === "object" && typeof v.length !== 'number';}, isarray : function(v) {return typeof v === "object" && typeof v.length === 'number';}, isnumber : function(v) {return typeof v === "number";}, isstring : function(v) {return typeof v === "string";}, isboolean : function(v) {return typeof v === "boolean";}, isfunction : function(v) {return typeof v === "function";} }; })(); // 配置================================================= sk.config = { respath : '/nw/sk/', css:{ downlistbox : {position:'absolute', zindex:'20000',backgroundcolor:'#e0f0fc', border:'1px solid #777777',fontsize:'14px', overflow:'auto'}, popbox : {position:'absolute', zindex:'20000',backgroundcolor:'#e0f0fc', border:'1px solid #777777',fontsize:'14px', top:'0px'}, wingrap : 'ddgl_win_grap', wingrap0 : 'ddgl_win_grap0', wingrap1 : 'ddgl_win_grap1', pagesorthead : 'sorthead', hover : 'mmover' } }; (function(){ // 杂项函数======================================================================= /* 将身份证号规范为新的18位号码 */ function china18idcard(a){ if(checkidcard(a)){ return false; } if(a.length==15){ a=a.substr(0,6)+"19"+a.substr(6,9)+callastidcardno(a); } return a; } // 检查字符串c是否是一个正确的身份证号,这是一种比更为严格的算法,成功返回null,否则返回错误描述字符串 function checkidcard(c){ c=c.tostring(); if(c.length==18){ if(!isinteger(c.substr(0,17))){ return "身份证号码错误,前17位应为数字!"; } var b,a; b=callastidcardno(c); a=c.substr(17,1); if(a=="x"||a=="x"){ a="x"; } if(b!=a){ return "身份证号码有误,请核对!"; } else{ return isvaliddate(c.substr(6,4),c.substr(10,2),c.substr(12,2)); } } else if(c.length==15){ // if(!isinteger(c)){ // return "身份证号码错误,前15位应为数字!"; // } // else{ // return isvaliddate("19"+c.substr(6,2),c.substr(8,2),c.substr(10,2)); // } return '请填写二代身份证号'; } // else if(c.length==8){ // return null; // } else { return "身份证号码必须为18位身份证号!"; } } // 检查日期是否正确,正确返回null,否则返回错误描述字符串 function isvaliddate(d,g,e){ var c=new date(d,g-1,e); var b=c.getfullyear(); var a=c.getmonth(); var f=c.getdate(); if(b!=d||a!=(g-1)||f!=e){ return "身份证号码内日期错误!"; } return null; } //判断是否是整数 function isinteger(str) {return !(/[^\d]+$/.test(str));} //计算18位身份证中的最后一位 function callastidcardno(c){ if(c.length==18){ c=c.substr(0,17); } else{ if(c.length==15){ c=c.substr(0,6)+"19"+c.substr(6,9); } } var a=["1","0","x","9","8","7","6","5","4","3","2"]; var d=[7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,1]; var b=0; for(var i=0;i //则传入参数 filename:common.js tag:script //返回值:js/ getfolderpath : function(filename, tagname) { //若filename为空,则默认查找script标签 if (!filename) filename = "sk.js"; //若tagname为空,则默认查找script标签 if (!tagname) tagname = "script"; var tags = document.getelementsbytagname(tagname); for (var i = 0; i < tags.length; i++) { var src = tags[i].src; if (!src) continue; if (src.substring(src.lastindexof("/") + 1).tolowercase() == filename.tolowercase()) { return src.substr(0, src.lastindexof("/") + 1); } } return ""; }, // 格式化数字,保留指定的小数位数 formatnnumber : function (pnumber,decimals){ if (isnan(pnumber)) {return 0;} if (pnumber==='') {return 0;} var snum = new string(pnumber); if (snum.substr(snum.length - 1,1)=='.') snum += '0'; var sec = snum.split('.'); var whole = parsefloat(sec[0]); var result = ''; if(sec.length > 1){ var dec = new string(sec[1]); dec = string(parsefloat(sec[1])/math.pow(10,(dec.length - decimals))); dec = string(whole + math.round(parsefloat(dec))/math.pow(10,decimals)); var dot = dec.indexof('.'); if(dot == -1){ dec += '.'; dot = dec.indexof('.'); } while(dec.length <= dot + decimals) {dec += '0';} result = dec; } else{ dec = new string(whole); dec += '.'; dot = dec.indexof('.'); while(dec.length <= dot + decimals) {dec += '0';} result = dec; } return result; }, /** * 数字转中文(外来代码:http://flyash.itcao.com/post_984.html) * number {integer} 形如123的数字 * return {string} 返回转换成的形如 一百二十三 的字符串 */ numbertochinese : function(number) { /* 单位 */ var units = '个十百千万@#%亿^&~'; /* 字符 */ var chars = '零一二三四五六七八九'; var a = (number + '').split(''), s = []; if (a.length > 12) { throw new error('数值过大无法转换为汉字'); } else { for ( var i = 0, j = a.length - 1; i <= j; i++) { if (j == 1 || j == 5 || j == 9) {// 两位数 处理特殊的 1* if (i == 0) { if (a[i] != '1') s.push(chars.charat(a[i])); } else { s.push(chars.charat(a[i])); } } else { s.push(chars.charat(a[i])); } if (i != j) { s.push(units.charat(j - i)); } } } // return s; return s.join('').replace(/零([十百千万亿@#%^&~])/g, function(m, d, b) {// 优先处理 零百 零千 等 b = units.indexof(d); if (b != -1) { if (d == '亿') return d; if (d == '万') return d; if (a[j - b] == '0') return '零'; } return ''; }).replace(/零+/g, '零').replace(/零([万亿])/g, function(m, b) {// 零百 零千处理后 可能出现 零零相连的 再处理结尾为零的 return b; }).replace(/亿[万千百]/g, '亿').replace(/[零]$/, '').replace(/[@#%^&~]/g, function(m) { return { '@' : '十', '#' : '百', '%' : '千', '^' : '十', '&' : '百', '~' : '千' }[m]; }).replace(/([亿万])([一-九])/g, function(m, d, b, c) { c = units.indexof(d); if (c != -1) { if (a[j - c] == '0') return d + '零' + b; } return m; }); } }; })(); sk.cookie = { getval : function(offset) { //获得cookie解码后的值 var endstr = document.cookie.indexof (";", offset); if (endstr == -1) endstr = document.cookie.length; return decodeuri(document.cookie.substring(offset, endstr)); }, set : function(name, value) { //设定cookie值 var expdate = new date(); var argv = arguments; var argc = arguments.length; var expires = (argc > 2) ? argv[2] : null; var path = (argc > 3) ? argv[3] : null; var domain = (argc > 4) ? argv[4] : null; var secure = (argc > 5) ? argv[5] : false; if(expires!=null) expdate.settime(expdate.gettime() + ( expires * 1000 )); document.cookie = name + "=" + encodeuri (value) +((expires == null) ? "" : ("; expires="+ expdate.togmtstring())) +((path == null) ? "" : ("; path=" + path)) +((domain == null) ? "" : ("; domain=" + domain)) +((secure == true) ? "; secure" : ""); }, get : function(name) { //获得cookie的原始值 var arg = name + "="; var alen = arg.length; var clen = document.cookie.length; var i = 0; while (i < clen) { var j = i + alen; if (document.cookie.substring(i, j) == arg) return sk.cookie.getval(j); i = document.cookie.indexof(" ", i) + 1; if (i == 0) break; } return null; }, del : function(name) { //删除cookie var exp = new date(); exp.settime (exp.gettime() - 1); var cval = sk.cookie.get(name); document.cookie = name + "=" + cval + "; expires="+ exp.togmtstring(); } }; // 浏览器窗户区尺寸================================================================================================================== sk.bwc = { // 取浏览器窗口高度 getheight : function() { // 取窗口可见部分的高度 return (window.innerheight) ? window.innerheight : (document.documentelement && document.documentelement.clientheight) ? document.documentelement.clientheight : document.body.offsetheight; }, // 取浏览器窗口宽度 getwidth : function() { // 取窗口可见部分的高度 return (window.innerwidth) ? window.innerwidth : (document.documentelement && document.documentelement.clientwidth) ? document.documentelement.clientwidth : document.body.offsetwidth; }, // 取浏览器窗口垂直方向的滚动尺寸 getscrolltop : function() { return document.body.scrolltop?document.body.scrolltop:document.documentelement.scrolltop; /* switch(sk._browser) { case 'sa':case 'ff':case 'ie':case'op': return document.body.scrolltop?document.body.scrolltop:document.documentelement.scrolltop; default: return document.documentelement.scrolltop; } */ }, // 取浏览器窗口水平滚动尺寸 getscrollleft : function() { return document.body.scrollleft?document.body.scrollleft:document.documentelement.scrollleft; /* switch(sk._browser) { case 'sa':case 'ff':case 'ie':case'op': return document.body.scrollleft?document.body.scrollleft:document.documentelement.scrollleft; default: return document.documentelement.scrollleft; } */ } }; // 消息类===================================================================================================================== sk.evt = { // 停止消息向上传递 stop : function(e) { if(e && e.stoppropagation){ e.stoppropagation(); } else{ window.event.cancelbubble = true; } }, mover : function() {sk.dom.addclass(this, sk.config.css.hover);}, mout : function() {sk.dom.removeclass(this, sk.config.css.hover);} }; // url解析(外来代码)===================================================================================================== sk.url = { querystring: function(key) {// 取url中的指定参数内容 var val = window.location.search.match(new regexp("[\?\&]" + key + "=([^\&]*)(\&?)", "i")); return val ? val[1] : val; }, root: function() {//网站的根路径 var _fullpath = location.href; var _path = location.pathname; return (_fullpath.substring(0, _fullpath.indexof(_path)) + "/"); }, pageroot: function() {//当前运行页面(asp、aspx、html、jsp etc)文件路径 var _fullpath = location.href; var _path = location.pathname; return (_fullpath.substring(0, _fullpath.indexof(_path.substr(_path.lastindexof("/")))) + "/"); }, virtualroot: function() {//虚拟目录的根路径(网站下的虚拟目录) var _path = location.pathname; return (this.root() + _path.substring(1, _path.substr(1).indexof("/") + 1) + "/"); } }; // ajax 通信类===================================================================================================================== (function(){ var _httpstatustext_ = []; _httpstatustext_[100]="初始的请求已经接受,客户应当继续发送请求的其余部分"; _httpstatustext_[101]="服务器将遵从客户的请求转换到另外一种协议"; _httpstatustext_[200]="一切正常,对get和post请求的应答文档跟在后面。"; _httpstatustext_[201]="服务器已经创建了文档,location头给出了它的url。"; _httpstatustext_[202]="已经接受请求,但处理尚未完成。 "; _httpstatustext_[203]="文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝 "; _httpstatustext_[204]="没有新文档,浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而servlet可以确定用户文档足够新,这个状态代码是很有用的"; _httpstatustext_[205]="没有新的内容,但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容"; _httpstatustext_[206]="客户发送了一个带有range头的get请求,服务器完成了它"; _httpstatustext_[300]="客户请求的文档可以在多个位置找到,这些位置已经在返回的文档内列出。如果服务器要提出优先选择,则应该在location应答头指明。 "; _httpstatustext_[301]="客户请求的文档在其他地方,新的url在location头中给出,浏览器应该自动地访问新的url。 "; _httpstatustext_[302]="类似于301,但新的url应该被视为临时性的替代,而不是永久性的。 "; _httpstatustext_[303]="类似于301/302,不同之处在于,如果原来的请求是post,location头指定的重定向目标文档应该通过get提取"; _httpstatustext_[304]="客户端有缓冲的文档并发出了一个条件性的请求(一般是提供if-modified-since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。 "; _httpstatustext_[305]="客户请求的文档应该通过location头所指明的代理服务器提取"; _httpstatustext_[307]="和302(found)相同。许多浏览器会错误地响应302应答进行重定向,即使原来的请求是post,即使它实际上只能在post请求的应答是303时才能重定向。由于这个原因,http 1.1新增了307,以便更加清除地区分几个状态代码:当出现303应答时,浏览器可以跟随重定向的get和post请求;如果是307应答,则浏览器只能跟随对get请求的重定向。 "; _httpstatustext_[400]="请求出现语法错误。 "; _httpstatustext_[401]="客户试图未经授权访问受密码保护的页面。应答中会包含一个www-authenticate头,浏览器据此显示用户名字/密码对话框,然后在填写合适的authorization头后再次发出请求。 "; _httpstatustext_[403]="资源不可用。"; _httpstatustext_[404]="无法找到指定位置的资源"; _httpstatustext_[405]="请求方法(get、post、head、delete、put、trace等)对指定的资源不适用。"; _httpstatustext_[406]="指定的资源已经找到,但它的mime类型和客户在accpet头中所指定的不兼容"; _httpstatustext_[407]="类似于401,表示客户必须先经过代理服务器的授权。"; _httpstatustext_[408]="在服务器许可的等待时间内,客户一直没有发出任何请求。客户可以在以后重复同一请求。 "; _httpstatustext_[409]="通常和put请求有关。由于请求和资源的当前状态相冲突,因此请求不能成功。"; _httpstatustext_[410]="所请求的文档已经不再可用,而且服务器不知道应该重定向到哪一个地址。它和404的不同在于,返回407表示文档永久地离开了指定的位置,而404表示由于未知的原因文档不可用。 "; _httpstatustext_[411]="服务器不能处理请求,除非客户发送一个content-length头。 "; _httpstatustext_[412]="请求头中指定的一些前提条件失败"; _httpstatustext_[413]="目标文档的大小超过服务器当前愿意处理的大小。如果服务器认为自己能够稍后再处理该请求,则应该提供一个retry-after头 "; _httpstatustext_[414]="uri太长 "; _httpstatustext_[416]="服务器不能满足客户在请求中指定的range头"; _httpstatustext_[500]="服务器遇到了意料不到的情况,不能完成客户的请求"; _httpstatustext_[501]="服务器不支持实现请求所需要的功能。例如,客户发出了一个服务器不支持的put请求 "; _httpstatustext_[502]="服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答 "; _httpstatustext_[503]="服务器由于维护或者负载过重未能应答。例如,servlet可能在数据库连接池已满的情况下返回503。服务器返回503时可以提供一个retry-after头 "; _httpstatustext_[504]="由作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答 "; _httpstatustext_[505]="服务器不支持请求中所指明的http版本"; sk.ajax = { errmsg : function(xml) { var status = xml.status; if ( status >= 200 && status < 300 || status === 304 ) { return null; } var str = _httpstatustext_[xml.status]; return (str?str:"未知错误") + "|statuscode:" + xml.status; }, connect : function() { var gxmlhttp; if (window.activexobject) { gxmlhttp = new activexobject('microsoft.xmlhttp'); } else { gxmlhttp = new xmlhttprequest(); } if (gxmlhttp == null) { alert("建立连结失败!"); return null; } return gxmlhttp; }, lasterror : '', // 同步(阻塞)方式进行ajax操作 synpost : function (url, arg) { try { var xmlhttp = sk.ajax.connect(); var param = url + '?timestamp=' + new date().gettime(); xmlhttp.open('post', param, false); // xmlhttp.setrequestheader("content-length", arg.length); xmlhttp.setrequestheader("content-type","application/x-www-form-urlencoded"); xmlhttp.send(arg); var msg = sk.ajax.errmsg(xmlhttp); if (msg != null) { sk.ajax.lasterror = msg; xmlhttp = null; return null; } var ret = xmlhttp.responsetext; xmlhttp = null; return ret; } catch (e) { sk.ajax.lasterror = "synpost错误!" + e.name + ":" + e.message; return null; } }, // 复杂的json结构数据用这个函数更可靠. asynpostjson : function(url, jsonstr, back) { try { var xmlhttp = sk.ajax.connect(); xmlhttp.onreadystatechange = function() { if (xmlhttp.readystate != 4) return; var msg = sk.ajax.errmsg(xmlhttp); if (msg != null) { sk.ajax.lasterror = msg; xmlhttp = null; back(null); return; } var ret = xmlhttp.responsetext; xmlhttp = null; back(ret); }; xmlhttp.open('post', url + '?json=true&' + '×tamp=' + new date().gettime(), true); // xmlhttp.setrequestheader("content-length", jsonstr.length); xmlhttp.setrequestheader("content-type","application/json"); xmlhttp.setrequestheader("charset", "utf-8"); xmlhttp.send(jsonstr); } catch (e) { sk.ajax.lasterror = "asynpostjson错误!" + e.name + ":" + e.message; back(null); return; } }, // 异步(非阻塞)方式进行ajax操作 asynpost : function (url, arg, back) { // obj为回调对象(可选,也可为null),back为回调函数必须的参数 try { var xmlhttp = sk.ajax.connect(); xmlhttp.onreadystatechange = function() { if (xmlhttp.readystate != 4) return; var msg = sk.ajax.errmsg(xmlhttp); if (msg != null) { sk.ajax.lasterror = msg; xmlhttp = null; back(null); return; } var ret = xmlhttp.responsetext; xmlhttp = null; back(ret); }; url = url + '?timestamp=' + new date().gettime(); xmlhttp.open('post', url, true); // xmlhttp.setrequestheader("content-length", arg.length); xmlhttp.setrequestheader("content-type","application/x-www-form-urlencoded"); // xmlhttp.setrequestheader("connection", "close"); //xmlhttp.setrequestheader("content-type","application/json"); // xmlhttp.setrequestheader("content-type", "text/html "); // xmlhttp.setrequestheader("charset", "utf-8"); xmlhttp.send(arg); } catch (e) { sk.ajax.lasterror = "asynpost错误!" + e.name + ":" + e.message; back(null); return; } }, synget : function (url, arg) { try { var xmlhttp = sk.ajax.connect(); if (arg) var param = url + '?timestamp=' + new date().gettime() + '&' + arg; else param = url; xmlhttp.open('get', param, false); xmlhttp.send(null); var msg = sk.ajax.errmsg(xmlhttp); if (msg !== null) { sk.ajax.lasterror = msg; xmlhttp = null; return null; } var ret = xmlhttp.responsetext; xmlhttp = null; return ret; } catch (e) { sk.ajax.lasterror = "synget错误!" + e.name + ":" + e.message; return null; } }, // 异步(非阻塞)方式进行ajax操作 asynget : function (url, arg, back) { // obj为回调对象(可选,也可为null),back为回调函数必须的参数 try { var xmlhttp = sk.ajax.connect(); xmlhttp.onreadystatechange = function() { if (xmlhttp.readystate != 4) return; var msg = sk.ajax.errmsg(xmlhttp); if (msg != null) { sk.ajax.lasterror = msg; xmlhttp = null; back(null); return; } var ret = xmlhttp.responsetext; xmlhttp = null; back(ret); }; if (arg) var param = url + '?timestamp=' + new date().gettime() + '&' + arg; else param = url; xmlhttp.open('get', param, true); xmlhttp.send(null); } catch (e) { sk.ajax.lasterror = "asynget错误!" + e.name + ":" + e.message; back(null); return; } }, // 根据本应用的自身协议,检验返回是不是以特定标记开头,不是则是出问题了 // 这个函数不是通用的,返回null说明服务器返回的数据不可用,同时通过messagebox报错。否则为可用 after : function(obj) { }, // sk.ajax.getobj取得一个对象后的附加动作getobjafter(obj),可被重新定义以附加其他动作 onerror : function(obj) { if (obj) window.alert(obj.msg); else alert('返回null'); }, // str是返回的结果串,proc如果存在,则在将str成功转换为结果对象时,将以proc(结果对象)的形式调用这个传入的函数. // error为错误入口函数,空则使用默认的处理即:alert(errormsg); getobj : function(str, proc, error) { sk.dlg.closeprocbox(); if (!str) { if (error) error({msg:sk.ajax.lasterror + '\n通信失败,可能是网络已断开或连接不稳定,请检查网络连接后再次尝试。'}); else sk.ajax.onerror({msg:sk.ajax.lasterror + '\n通信失败,可能是网络已断开或连接不稳定,请检查网络连接后再次尝试。'}); return null; } try { var obj = str.json_parse(); } catch(e) { if (error) error({msg:'对服务器返回数据进行解析时出错:' + e.name + ":" + e.message}); else sk.ajax.onerror({msg:'对服务器返回数据进行解析时出错:' + e.name + ":" + e.message}); return null; } if (obj && obj.status == 'ok') { if (sk.ajax.after) sk.ajax.after(obj); if (proc) proc(obj); return obj; } else { if (sk.ajax.after) sk.ajax.after(obj); if (error) error(obj); else sk.ajax.onerror(obj); return null; } } }; // 基于sk.ajax的远程调用,使用统一的远程处理模块处理各类请求,具体的请求项目由mod指定基本格式为<模块名.函数名>如:user.login。参数为data对象 sk.rc = { procurl : "", // 由应用定义的远程处理模块的url,最好为绝对路径 // 用get方式进行完全阻塞式同步调用,直接返回结果对象 sget : function(mod, data, error) { var param = "mod=" + encodeuricomponent(mod) + "&data=" + encodeuricomponent(o(data).tojson()); return sk.ajax.getobj(sk.ajax.synget(sk.rc.procurl, param), false, error); }, // 用post方式进行完全阻塞式同步调用,直接返回结果对象 spost : function(mod, data, error) { var param = "mod=" + encodeuricomponent(mod) + "&data=" + encodeuricomponent(o(data).tojson()); return sk.ajax.getobj(sk.ajax.synpost(sk.rc.procurl, param), false, error); }, // 用get方式进行延时同步调用,以回调方式返回结果对象,同异步方式保持了调用方式的一致,便于修改工作方式 get : function(mod, data, msg, proc, error) { if (msg) sk.dlg.showprocbox(msg); var param = "mod=" + encodeuricomponent(mod) + "&data=" + encodeuricomponent(o(data).tojson()); settimeout(function(){sk.ajax.getobj(sk.ajax.synget(sk.rc.procurl, param), proc, error);}, 1); }, // 用post方式进行延时同步调用,以回调方式返回结果对象,同异步方式保持了调用方式的一致,便于修改工作方式 post : function(mod, data, msg, proc, error) { if (msg) sk.dlg.showprocbox(msg); var param = "mod=" + encodeuricomponent(mod) + "&data=" + encodeuricomponent(o(data).tojson()); settimeout(function(){sk.ajax.getobj(sk.ajax.synpost(sk.rc.procurl, param), proc, error);}, 1); }, // 用get方式进行异步调用,返回结果对象后以proc(returnobj)调用的形式对结果进行进一步处理 aget : function(mod, data, msg, proc, error) { if (msg) sk.dlg.showprocbox(msg); var param = "mod=" + encodeuricomponent(mod) + "&data=" + encodeuricomponent(o(data).tojson()); settimeout(function(){sk.ajax.asynget(sk.rc.procurl, param, function(str) {sk.ajax.getobj(str, proc, error);});}, 1); }, // 用post方式进行异步调用,返回结果对象后以proc(returnobj)调用的形式对结果进行进一步处理 apost : function(mod, data, msg, proc, error) { if (msg) sk.dlg.showprocbox(msg); var param = "mod=" + encodeuricomponent(mod) + "&data=" + encodeuricomponent(o(data).tojson()); settimeout(function(){sk.ajax.asynpost(sk.rc.procurl, param, function(str) {sk.ajax.getobj(str, proc, error);});}, 1); }, // 复杂结构的json数据在有的浏览器上会出现通讯问题时,改用这个函数可解决问题,但这个函数代价相对高一些.决大部分情况下用apost更实惠. // 同时这个函数发送的数据不利于调试. apostjson : function(mod, data, msg, proc, error) { if (msg) sk.dlg.showprocbox(msg); data['__mod__'] = mod; var param = encodeuricomponent(o(data).tojson()); settimeout(function(){sk.ajax.asynpostjson(sk.rc.procurl, param, function(str) {sk.ajax.getobj(str, proc, error);});}, 1); } }; })(); // dom元素的快捷操作类,及一些简单组件==================================================================================== (function() { var swtab = {}; // 元素属性缩写表,用于在创建元素时简化属性名称,简写为全大写字母 function dom(doc) { this.doc = doc; this.domidtab = {}; } // 设置或获取一项属性值,使用简写访问时大小写都可以,但原名必须注意大小写问题. function attr(obj, attrname, attrvalue) { var p = swtab[attrname.touppercase()]; if (!p) p = attrname; // 如果在简写表中无记录则用原名 if (arguments.length > 2) { obj[p] = attrvalue; return attrvalue; } else return obj[p]; } // 用一个对象(map)进行批量的属性设置,pf=true时不复制函数成员,这 function setattr(obj, valobj, pf) { for (var p in valobj) { if (pf && typeof valobj[p] === 'function') continue; attr(obj, p, valobj[p]); } } dom.prototype = { create : function(tag) {return new elagent(this.doc.createelement(tag), this);}, createdom : function(tag) { return this.doc.createelement(tag); }, createse : function(tag) { return new elagent(this.doc.createelement(tag), this); }, createel : function(tag, cs, style, attr) { var el = this.createse(tag); if (cs) el.em.classname = cs; if (style) { setattr(el.em.style, style, true); // style上不能设置函数属性,否则在一些浏览器上会出错. } if (attr) { setattr(el.em, attr); } return el; }, root : function() { // body只应有一个对应的代理对象实例 if (!this.docbody) this.docbody = new elagent(this.doc.body, this); return this.docbody; }, getel : function (id) { if (this.domidtab[id]) return this.domidtab[id]; var el = this.doc.getelementbyid(id); if (!el) { alert(id + ':找不到!'); return null; } return (this.domidtab[id] = new elagent(el, this)); }, // 注册属性名的简写名(别名) regattrname : function(name, alias) { swtab[alias.touppercase()] = name; }, // 为elagent增加方法 addmethod : function(mn, func) { elagent.prototype[mn] = func; }, addclass : function (el, cls) { if (el.classname.indexof(cls) < 0) el.classname += (' ' + cls); }, removeclass : function (el, cls) { var str = el.classname; str = str.replaceall('' + cls, ''); el.classname = str.trim(); }, hasclass : function (el, cls) { return (el.classname.indexof(cls) < 0); }, clearselectarea : function() { // 清除文档中被鼠标选中的部分 try { this.doc.selection && this.doc.selection.empty && ( this.doc.selection.empty(), 1) || window.getselection && window.getselection().removeallranges(); } catch(e) {} } }; sk.dom = new dom(document); // 当前文档对象 // dom操作类====================================================== function getinputcurpos(em) { var ctrl = em; try { //获取光标位置函数 var caretpos = 0; //ie support if (document.selection) { ctrl.focus(); var sel = document.selection.createrange (); sel.movestart ('character', -ctrl.value.length); caretpos = sel.text.length; } // firefox support else if (ctrl.selectionstart || ctrl.selectionstart == '0') caretpos = ctrl.selectionstart; return (caretpos); } catch(e) { return 0; } } // input输入检验 function uintinputproc(evt) { var e = evt||window.event; var keycode = e.keycode||e.which||e.charcode; var cp = getinputcurpos(this); if ((keycode >= 48 && keycode <= 57) ||(keycode >= 96 && keycode <= 105) ||(keycode < 20)||(keycode == 46)||(keycode == 37)||(keycode == 39)||(keycode==13) ) return true; e.returnvalue = false; return false; } function integerinputproc(evt) { var e = evt||window.event; var keycode = e.keycode||e.which||e.charcode; var cp = getinputcurpos(this); if (cp == 0 && this.value.substr(0,1)=='-' && keycode > 48) { e.returnvalue = false; return false; } if ((keycode >= 48 && keycode <= 57)||(cp==0&&(keycode==109||keycode==173)) ||(keycode >= 96 && keycode <= 105) ||(keycode < 20)||(keycode == 46)||(keycode == 37)||(keycode == 39)||(keycode==13) ) return true; e.returnvalue = false; return false; } function realinputproc(evt) { var e = evt||window.event; var keycode = e.keycode||e.which||e.charcode; var cp = getinputcurpos(this); if (cp == 0 && this.value.substr(0,1)=='-' && keycode > 48) { e.returnvalue = false; return false; } else if (keycode == 110 || keycode==190) { if (cp > 0 && this.value.substr(cp-1,1)!='-' && this.value.indexof('.')<0) return true; } if ((keycode >= 48 && keycode <= 57)||(cp==0&&(keycode==109||keycode==173)) ||(keycode >= 96 && keycode <= 105)//||(keycode=190) ||(keycode < 20)||(keycode == 46)||(keycode == 37)||(keycode == 39)||(keycode==13) ) return true; e.returnvalue = false; return false; } function codeupperinputproc() {this.value = this.value.dbc2sbc().touppercase();} function trimproc() {this.value = this.value.trim();} function sbcproc() {this.value = this.value.trim().dbc2sbc();} function dateproc() { var v = this.value.trim(); if (v.length == 0) return; v = v.dbc2sbc().formatdate(); if (!v) { alert('输入的日期为非法值(格式:yyyy-mm-dd)'); var em = this; settimeout(function(){em.focus();}, 100); //this.value = ''; return; } this.value = v; } // 不严谨的身份证号校验,如需严谨检验可用sk.kit.idcard.check function sfzproc() { var val = this.value = this.value.trim().dbc2sbc().touppercase(); if (this.value.length == 0) return false; if (this.value.length == 15) { var y = '19' + val.substr(6,2); var m = val.substr(8,2); var d = val.substr(10,2); } else if (this.value.length == 18) { y = val.substr(6,4); m = val.substr(10,2); d = val.substr(12,2); } else{ alert('身份证号码长度为15位或18位。'); var em = this; settimeout(function(){em.focus();}, 100); return false; } var v = (y + '-' + m + '-' + d).formatdate(); if (!v) { em = this; settimeout(function(){em.focus();}, 100); alert('身份证号中包含的日期为非法日期。'); return false; } return true; } function checksfzproc() { return sfzproc.call(this.em); } function xmproc() { var val = this.value.trim().dbc2sbc(); this.value = val.replaceall(' ','').replaceall(' ',''); } function ivixm(ml) { this.em.maxlength=ml; // this.em.onblur = xmproc; this.addevent('blur', xmproc.bind(this.em)); this.needsbc=true; return this; } function ivisfz() { this.em.maxlength=18; // this.em.onblur = sfzproc; this.addevent('blur', sfzproc.bind(this.em)); this.needsbc=true; this.checksfz = checksfzproc; return this; } function ividate() { // this.em.onblur = dateproc; this.addevent('blur', dateproc.bind(this.em)); this.needsbc=true; return this; } function ivisbc(ml) { if (ml) this.em.maxlength=ml; // this.em.onblur = sbcproc; this.addevent('blur', sbcproc.bind(this.em)); this.needsbc=true; return this; } function ivitrim(ml) { if (ml) this.em.maxlength=ml; // this.em.onblur = trimproc; this.addevent('blur', trimproc.bind(this.em)); this.needtrim=true; return this; } function ivimaxlen(ml) {this.em.maxlength=ml;return this;} function ivikeydown(func, ml) { if (ml) this.em.maxlenght = ml; var self = this; this.addevent('keydown', function(evt) { var e = evt||window.event; var keycode = e.keycode||e.which||e.charcode; func.call(self, keycode, e); }); return this; } function ivicodeupper(ml) { if (ml) this.em.maxlength=ml; //this.addevent('keyup', codeupperinputproc); // ie上无效所以.... this.em.onkeyup = codeupperinputproc; return this; } function kuint() {this.value = this.value.dbc2sbc(); this.value = this.value.numeric("i");} function kuuint(){this.value = this.value.dbc2sbc(); this.value = this.value.replace(/[^\d]/g, '');} function kureal(){this.value = this.value.dbc2sbc(); this.value = this.value.numeric("f");} function iviuint(ml) { if (ml) this.em.maxlength=ml; this.em.onkeydown = uintinputproc; // if (sk.browser.isfirefox) this.addevent('keyup', kuuint.bind(this.em)); this.needsbc=true; this.isinteger=true; return this; } function iviinteger(ml) { if (ml) this.em.maxlength=ml; this.em.onkeydown = integerinputproc; // if (sk.browser.isfirefox) this.addevent('keyup', kuint.bind(this.em)); this.needsbc=true; this.isinteger=true; return this; } function ivireal(ml) { if (ml) this.em.maxlength=ml; this.em.onkeydown = realinputproc; // if (sk.browser.isfirefox) this.addevent('keyup', kureal.bind(this.em)); this.needsbc=true; this.isfloat=true; return this; } function iviselectchange(func) { this.em.onchange = func; return this; } function getcurpos() { var ctrl = this.em; try { //获取光标位置函数 var caretpos = 0; //ie support if (this.dom.doc.selection) { ctrl.focus(); var sel = this.dom.doc.selection.createrange (); sel.movestart ('character', -ctrl.value.length); caretpos = sel.text.length; } // firefox support else if (ctrl.selectionstart || ctrl.selectionstart == '0') caretpos = ctrl.selectionstart; return (caretpos); } catch(e) { return 0; } } function setcurpos(pos){ var ctrl = this.em; if(ctrl.setselectionrange){ try { ctrl.setselectionrange(pos,pos); } catch (e) {} } else if (ctrl.createtextrange) { try { var range = ctrl.createtextrange(); range.collapse(true); range.moveend('character', pos); range.movestart('character', pos); range.select(); } catch (e) {} } } function settextselected(startindex, endindex) { try { var inputdom = this.em; if (inputdom.setselectionrange) { inputdom.setselectionrange(startindex, endindex); } else if (inputdom.createtextrange) { var range = inputdom.createtextrange(); range.collapse(true); range.movestart('character', startindex); range.moveend('character', endindex - startindex-1); range.select(); } } catch(e) {} } function getinputtype() {return this.em.type.tolowercase();} function textinputempty() { if (this.em.value.trim().length > 0) return false; if (this.defaultval) { this.em.value = this.defaultval; return false; } return true; } // 为元素el ,在消息evtname上加一个处理函数func,obj为传递到func的this,如不填写则以el为this // 返回一个句柄,在后面删除这个函数时使用 var listerid = 0; // 监听函数句柄生成子,全局变量 var _gentabindex = 1; var _genid = 0; sk.dom.currenttabindex = function() {return _gentabindex;}; sk.dom.gettabindex = function() {return ++_gentabindex;}; function genid() { return 'skaid' + (++_genid); } function abuttonhover() {sk.dom.addclass(this, 'abuttonhover');} function abuttonhout() {sk.dom.removeclass(this, 'abuttonhover');} function selectappenditem(v, t) { var o = this.dom.createdom('option'); o.value = v; o.innerhtml = t; this.em.appendchild(o); return this; } // 当iframe提交了一个页面后,其之前的document将失效,此时应用这个方法重新获得新的document function iframe_reset() { var con = this.em.contentdocument || this.em.contentwindow.document; if (!con) throw new error('未能获取docment对象,无法创建iframe.'); this.dom = new dom(con); var rel = ""; for (var i=0; i'; con.open(); con.write('' + rel +''); con.close(); } function elagent(em, dom) { // dom元素操作代理对象 this.em = em; this.dom = dom; } elagent.prototype = { // 如果对象是select时则使用nv的值表达空值,对其他类型的对象nv无用. clear : function(nv) { var el = this.em; var tag = el.tagname.tolowercase(); if (tag!="input" && tag!='select' && tag!='textarea') { return this.clearchilden(); } else { if (tag == "input") { var type = el.type.tolowercase(); if (type=='checkbox' ||type=='radio') el.checked = false; else el.value = ''; } else el.value = (arguments.length > 0)?nv:''; return this; } }, tag : function() {return this.em.tagname.tolowercase();}, disabled : function(v) { if (arguments.length > 0) { this.em.disabled = v; return this; } else { return this.em.disabled; } }, val : function(v) { var el = this.em; var tag = el.tagname.tolowercase(); if (arguments.length > 0) { if (tag!="input" && tag!='select' && tag!='textarea') return el.innerhtml = v; else if (el.type && (el.type.tolowercase()=='checkbox'||el.type.tolowercase()=='radio')) el.checked = v?true:false; else { v = v?v+'':(typeof(v)==='number'?v+'':""); if (this.needsbc) v = v.dbc2sbc(); else if (this.needtrim) v = v.trim(); el.value = v; } return this; } else { if (tag!="input" && tag!='select' && tag!='textarea') return el.innerhtml; else if (el.type &&(el.type.tolowercase()=='checkbox'||el.type.tolowercase() == 'radio')) return el.checked; else { if (el.value.length > 0) { if (this.needsbc) el.value = el.value.dbc2sbc(); else if (this.needtrim) el.value = el.value.trim(); if (this.isinteger) { v = int(el.value); el.value = isnan(v)?'0':v + ""; } else if (this.isfloat) { v = float(el.value); el.value = isnan(v)?'0.0':v + ""; } return el.value; } else { if (this.defaultval) el.value = this.defaultval; else { if (this.isinteger) { v = int(el.value); el.value = isnan(v)?'0':v + ""; } else if (this.isfloat) { v = float(el.value); el.value = isnan(v)?'0.0':v + ""; } } return el.value; } } } }, bind : function(evtname, func, nbself) { // nbself是否将this进行绑定,默认为绑定 this.em[evtname] = nbself?func:func.bind(this); return this; }, // 为兼容旧代码保留的函数,新应用一般建议使用addevent,但也要注意addevent在ie和ff中的this不一致所以,addlister则没有这个问题,但效率要低一些. addlister : function (evtname, func) { if (!this.flst) { this.flst = {}; } var type = evtname.substr(2); // evt.type的值没有on头,如onchick的type为chick所以要去掉前两个字符 if (!this.flst[type]) { this.flst[type] = []; this.em[evtname] = function(evt) { var e = evt||window.event; var flst = this.flst[e.type]; for (var i = 0; i < flst.length; i++) flst[i].fn.call(this, evt); }.bind(this); } var p = this.flst[type].length; this.flst[type][p] = {}; this.flst[type][p].fn = func; this.flst[type][p].key = ++listerid; return this.flst[type][p].key; }, // 删除一个上在元素上的消息函数,key为addlister返回的句柄 // 为兼容旧代码保留的函数,新应用应使用removeevent removelister : function (evtname, key) { if (!this.flst) return false; evtname = evtname.substr(2); for (var i = 0; i < this.flst[evtname].length; i ++) { if (this.flst[evtname][i].key == key) { for (; i < this.flst[evtname].length - 1; i ++) this.flst[evtname][i] = this.flst[evtname][i + 1]; this.flst[evtname].pop(); return true; } } return false; }, // evtype的值没有on头,如onchick的为chick,在ie和ff等不同浏览器中fn的this是不一样的,所以要明确this必须从外部进行绑定 addevent : function(evtype, fn) { var obj = this.em; if (obj.addeventlistener) {//用于mozilla系列 obj.addeventlistener(evtype, fn, false); return true; } else if (obj.attachevent) {//用于ie系列 var r = obj.attachevent("on" + evtype, fn); return r; } else { return false; } }, // 删除addevent加入的处理函数 removeevent : function(evtype, fn) { var obj = this.em; if (obj.addeventlistener) { obj.removeeventlistener(evtype, fn, true); } else { obj.detachevent(evtype, fn); } }, parent : function() { if (!this._parentelement) this._parentelement = new elagent(this.em.parentnode, this.dom); return this._parentelement; }, getattr : function(k) {return attr(this.em, k);}, setattr : function(k, v) {attr(this.em, k, v);return this;}, getstyle : function(k) {return attr(this.em.style, k);}, setstyle : function(k, v) {attr(this.em.style, k, v);return this;}, getclass : function() {return this.em.classname;}, setclass : function(cls){this.em.classname = cls;return this;}, click : function(func) { if (func) { this.em.onclick = func; return this; } else { this.em.click(); return this; } }, focus : function(ns) { if (!ns) { if (this.setcurpos) this.setcurpos(this.val().length+1); if (this.select) this.select(0, this.val().length+1); } this.em.focus(); return this; }, before : function(tag, op) { if (op) { var el = this.dom.createel(tag, op.cls, op.css, op.attr); if (op.w) el.em.style.width = op.w + 'px'; if (op.h) el.em.style.height = op.h + 'px'; if (op.html) el.em.innerhtml = op.html; } else el = this.dom.createse(tag); this.em.parentnode.insertbefore(el.em, this.em); return el; }, after : function(tag, op) { if (op) { var el = this.dom.createel(tag, op.cls, op.css, op.attr); if (op.w) el.em.style.width = op.w + 'px'; if (op.h) el.em.style.height = op.h + 'px'; if (op.html) el.em.innerhtml = op.html; } else el = this.dom.createse(tag); if(this.em.parentnode.lastchild==this.em) { this.em.parentnode.appendchild(el.em); } else { this.em.parentnode.insertbefore(el.em, this.em.nextsibling); } return el; }, // appendchild el : function(tag, op) { if (op) { var el = this.dom.createel(tag, op.cls, op.css, op.attr); if (op.x) el.em.style.left = op.x + 'px'; if (op.y) el.em.style.top = op.y + 'px'; if (op.w) el.em.style.width = op.w + 'px'; if (op.h) el.em.style.height = op.h + 'px'; if (op.html) el.em.innerhtml = op.html; } else el = this.dom.createse(tag); this.em.appendchild(el.em); return el; }, appendchild : function(child) { this.em.appendchild(child.em); return this; }, removechild : function(child) { // 对于延时关闭效果的代码有时可能会导致重复removechild同一元素,所以在此进行一个简单的容错性检查. // 为保证效率,其他方法不进行这个检查,而由应用通过valid方法检查元素是否还有效,即没有被removechild过 if (!child.em) return this; try {this.em.removechild(child.em);}catch(e){} // 被移出的元素不再可用 child.em = null; return this; }, valid : function() { return this.em !== null; }, clearchilden : function () { if (this.em.haschildnodes()) { var cl = this.em.childnodes; while (0 < cl.length) this.em.removechild(cl[0]); } return this; }, swap : function(el) { if (sk.browser.isie) this.em.swapnode(el.em); else { function swapnode(node1,node2) { var parent = node1.parentnode;//父节点 var t1 = node1.nextsibling;//两节点的相对位置 var t2 = node2.nextsibling; //如果是插入到最后就用appendchild if(t1) parent.insertbefore(node2,t1); else parent.appendchild(node2); if(t2) parent.insertbefore(node1,t2); else parent.appendchild(node1); } swapnode(this.em, el.em); } return this; }, getxy : function(){ var x = 0,y = 0; var obj = this.em; if (obj.getboundingclientrect) { var box = obj.getboundingclientrect(); var d = this.dom.documentelement; x = box.left + math.max(d.scrollleft, this.dom.body.scrollleft) - d.clientleft; y = box.top + math.max(d.scrolltop, this.dom.body.scrolltop) - d.clienttop; } else{ for (; obj != this.dom.body; x += obj.offsetleft, y += obj.offsettop, obj = obj.offsetparent) {} } return { x: x, y: y }; }, getleft : function () { var obj = this.em; try { var l = obj.offsetleft; while((obj = obj.offsetparent)) { l += obj.offsetleft; //l -= obj.scrollleft; } return l; } catch(e) {} }, gettop : function() { var obj = this.em; try { var l = obj.offsettop; while((obj = obj.offsetparent)) { l += obj.offsettop; //l -= obj.scrolltop; } return l; } catch(e) {} }, // 计算元素相对于el的相对y坐标 getoffsety : function(el) { var obj = this.em; var l = obj.offsettop; // 必须在parentnode链上搜索并比对offsetparent因为浏览器不同这两个链是不同的,这种方式才可靠。 var p = obj.parentnode; while(p && p !== el.em) { if (p.offsetparent !== obj.offsetparent) { l += p.offsettop; l -= p.scrolltop; obj = p; } // p = p.parentnode; p = p.offsetparent; } return l; }, // 计算元素相对于el的相对x坐标 getoffsetx : function(el) { var obj = this.em; var l = obj.offsetleft; var p = obj.parentnode; while(p && p !== el.em) { if (p.offsetparent !== obj.offsetparent) { l += p.offsetleft; l -= p.scrollleft; obj = p; } // p = p.parentnode; p = p.offsetparent; } return l; }, getwidth : function() { var obj = this.em; try { return obj.offsetwidth; } catch(e) {} }, getheight : function() { var obj = this.em; try { return obj.offsetheight; } catch(e) {} }, settop : function(i) {try {this.em.style.top = i + "px";}catch(e){}return this;}, setleft : function(i) {try {this.em.style.left = i + "px";}catch(e){}return this;}, setwidth : function(i) { try { // wpatch是ie浏览器中对input.text的尺寸补偿值,其情况时为0或不存在这个属性 this.em.style.width = (i + (this.wpatch?this.wpatch:0)) + "px"; }catch(e){}return this; }, setheight : function(i) { try { this.em.style.height = (i + (this.hpatch?this.hpatch:0)) + "px"; }catch(e){}return this; }, scrollleft : function(n) { if (arguments.length > 0) return this.em.scrollleft = n; else return this.em.scrollleft; }, scrolltop : function(n) { if (arguments.length > 0) return this.em.scrolltop = n; else return this.em.scrolltop; }, x : function(n) { if (arguments.length > 0) { return this.setleft(n); } else return this.getleft(); }, y : function(n) { if (arguments.length > 0) { return this.settop(n); } else return this.gettop(); }, w : function(n) { if (arguments.length > 0) { return this.setwidth(n); } else return this.getwidth(); }, h : function(n) { if (arguments.length > 0) { return this.setheight(n); } else return this.getheight(); }, sethtml : function(str) { this.em.innerhtml = str; return this; }, settext : function (str) { /* 以前使用过的方式,效率低下 var el = this.em; if (str == null || str == '') el.innerhtml = ' '; else el.innerhtml = str.esctag(); */ if (!str) str = ""; this.em[sk.textnodename] = str; return this; }, gettext : function() { return this.em[sk.textnodename]; }, addclass : function (cls) { if (this.em.classname.indexof(cls) < 0) this.em.classname += (' ' + cls); return this; }, removeclass : function (cls) { var str = this.em.classname; str = str.replaceall('' + cls, ''); this.em.classname = str.trim(); return this; }, replaceclass : function (cls1, cls2) { var str = this.em.classname; str = str.replaceall('' + cls1, ''+cls2); this.em.classname = str.trim(); return this; }, hasclass : function (cls) { return (this.em.classname.indexof(cls) < 0); }, setdisplay : function(f) { if (f) { this.em.style.display = 'block'; } else { this.em.style.display = "none"; } return this; }, setvisible : function(f) { if (f) this.em.style.visibility = 'visible'; else this.em.style.visibility = 'hidden'; return this; }, setalpha : function(alpha) { this.em.style.filter = "alpha(opacity=" + alpha + ')'; this.em.style.opacity = (alpha/100) + ''; return this; }, spaceline : function(height) { return this.el('div', {h:height, css:{overflow:'hidden'}}); }, tbody : function(op) { if (op) { var tab = this.dom.createel('table', op.cls, op.css, op.attr); if (op.id) tab.em.id = op.id; if (op.cp) tab.em.cellpadding=op.cp; else tab.em.cellpadding='0'; if (op.cs) tab.em.cellspacing=op.cs; else tab.em.cellspacing='0'; if (op.w) tab.em.style.width = op.w + 'px'; if (op.h) tab.em.style.height = op.h + 'px'; } else tab = this.dom.createse('table'); this.appendchild(tab); var tb = this.dom.createse('tbody'); tab.appendchild(tb); return tb; }, input : function(type, op, notab) { if (op.lab) { if (!op.attr) op.attr = {}; if (op.attr.id) var forid = op.attr.id; else forid = op.attr.id = genid(); if (!op.labelafter) { var labelel = this.el('label', {attr:{"for":forid}}).settext(op.lab); if (op.mal) labelel.setstyle('marginleft', op.mal + 'px'); } } // 如果是创建文本输入框则套用一个自定的css类 type = type.tolowercase(); var wpatch = 0; var hpatch = 0; if (type == "text" || type == "password") { if (!op.cls) op.cls = "sktextinput"; else op.cls += " sktextinput"; if (sk.browser.isie) wpatch = -2; hpatch = -2; } var obj = this.dom.createel('input', op.cls, op.css, op.attr); var el = obj.em; el.type = type; if (type == "text" || type == "password" || type == "number") obj.empty = textinputempty; obj.wpatch = wpatch; obj.hpatch = hpatch; if (op.mar && (!op.lab||!op.labelafter)) el.style.marginright = op.mar + 'px'; if (op.mal && (!op.lab||op.labelafter)) el.style.marginleft = op.mal + 'px'; if (op.w) el.style.width = (op.w + wpatch) + 'px'; if (op.h) el.style.height = (op.h + hpatch) + 'px'; if (op.maxlen) el.maxlength = op.maxlen; if (op.ro) el.readonly = op.ro; /* if (op.name) { el.name = op.name; el.id = op.name + op.value; } */ if (op.defaultval) // 缺省值,如果定义过,则当内容为空时用这个值作为val()的返回 obj.defaultval = op.defaultval; if (op.op) obj.op = op.op; // 供应用使用的一些需要附加在input上的数据对象 this.em.appendchild(el); if (!notab) el.tabindex = ++ _gentabindex; if (op.value) { if (type == 'checkbox') el.checked = op.value?true:false; else el.value = op.value; } obj.sfz = ivisfz; obj.xm = ivixm; obj.date = ividate; obj.sbc = ivisbc; obj.integer = iviinteger; obj.uint = iviuint; obj.real = ivireal; obj.trim = ivitrim; obj.code = ivicodeupper; obj.len = ivimaxlen; obj.keydown = ivikeydown; obj.setcurpos = setcurpos; obj.getcurpos = getcurpos; obj.type = getinputtype; obj.select = settextselected; if (op.lab) { obj.label = op.lab; if (op.labelafter) { labelel = this.el('label', {attr:{"for":forid}}).settext(op.lab); if (op.mar) labelel.setstyle('marginright',op.mar + 'px'); } obj.labelel = labelel; } return obj; }, // 附加方法keydown | change | empty selectmapvt : function(op, mapa, notab) { if (op.lab) { if (!op.attr) op.attr = {}; if (op.attr.id) var forid = op.attr.id; else forid = op.attr.id = genid(); if (!op.labelafter) { var labelel = this.el('label', {attr:{"for":forid}}).settext(op.lab); if (op.mal) labelel.setstyle('marginleft', op.mal + 'px'); } } var obj = this.dom.createel('select', op.cls, op.css, op.attr); var el = obj.em; if (op.mar && (!op.lab||!op.labelafter)) el.style.marginright = op.mar + 'px'; if (op.mal && (!op.lab||op.labelafter)) el.style.marginleft = op.mal + 'px'; obj.wpatch = 2; if (op.w) el.style.width = (op.w + 2) + 'px'; if (op.h) el.style.height = op.h + 'px'; if (mapa) { if (op.null) { var o = this.dom.createdom('option'); o.value = op.null.v; o.innerhtml = op.null.t; el.appendchild(o); } for (var i=0; i < mapa.length; i++) { o = this.dom.createdom('option'); o.value = mapa[i].v; o.innerhtml = mapa[i].t; el.appendchild(o); } } this.em.appendchild(el); if (!notab) el.tabindex = ++_gentabindex; if (op.value) el.value = op.value; obj.keydown = ivikeydown; obj.change = iviselectchange; obj.empty = textinputempty; obj.append = selectappenditem; if (op.lab) { obj.label = op.lab; if (op.labelafter) { labelel = this.el('label', {attr:{"for":forid}}).settext(op.lab); if (op.mar) labelel.setstyle('marginright',op.mar + 'px'); } obj.labelel = labelel; } if (op.op) obj.op = op.op; // 供应用使用的一些需要附加在input上的数据对象 return obj; }, abutton : function(text, func, op, notab) { if (!op) op = {}; if (!op.css) op.css = {}; op.css.cursor = 'pointer'; if (op.mar) op.css.marginright = op.mar + 'px'; if (op.mal) op.css.marginleft = op.mal + 'px'; if (!op.attr) op.attr = {}; //op.html = text; op.attr.onmouseover = abuttonhover; op.attr.onmouseout = abuttonhout; op.attr.tabindex = (!notab)? 0 : ++_gentabindex; if (!func) func = sk.nop; op.attr.onclick = function(evt) {sk.dom.removeclass(this, 'abuttonhover');func();}; op.attr.ondblclick = sk.evt.stop; var el = this.el('a', op).sethtml(text); el.click = function(f) {func = f;return this;}; return el; }, downlistbox : function(w, h) { //position: absolute; z-index: 20000; background-color:#e0f0fc; border: 1px solid #777777; overflow: auto; font-size: 14px; var root = this.dom.root(); // box.onclick = function(e) {stopbubble(e);}; var sh = sk.bwc.getheight() + sk.bwc.getscrolltop(); var sw = sk.bwc.getwidth(); var left = this.getoffsetx(sk.dom.root()); var top = this.getoffsety(sk.dom.root()) + this.getheight(); var height = h?h:150; var width = w?w:this.getwidth() + 2; if (top + height + 4 > sh) top = top - this.getheight() - 2 - height -(sk.browser.isie && sk.browser.ieversion<8?2:2); if (left + width > sw) left = sw - w - 2; var box = root.el('div', {css:sk.config.css.downlistbox}); box.setleft(left); // var t = sk.dom.getel('mainclient'); // box.setleft(t.getleft()); // box.setwidth(t.getwidth()); box.settop(top); box.setwidth(width); box.setheight(height); box.root = root; box.close = function() { this.root.removechild(this); }; return box; }, // 带下拉框的文本输入,可在下拉框中选内容 inputwithlist : function(op, list, notab) { var input = this.input('text', op, notab); function createlist() { var box = input.downlistbox(op.w /* + (sk.browser.isfirefox?0:2) */, op.listheight);//如果input没有边框则注释应去掉,因为ie的input宽度计算和ff是不同的。 box.innerhtml = ''; var cd = box.el('div', {cls:'downlistbox'}); for (var i = 0; i < list.length; i++) { var sl = cd.el('div',{}).settext(list[i]); sl.inputel = input; sl.selectstring = list[i]; sl.setattr("onmouseover" ,function(){this.addclass(sk.config.css.hover);this.inputel.inbox = true;}.bind(sl)); sl.setattr("onmouseout" ,function(){this.removeclass(sk.config.css.hover);this.inputel.inbox = false;}.bind(sl)); sl.setattr("onclick" ,function(){ this.inputel.em.value = this.selectstring; this.inputel.inbox = false; this.inputel.listbox.close(); this.inputel.listbox = null; if (this.inputel.listselected) this.inputel.listselected(this.selectstring); this.inputel.em.focus(); }.bind(sl)); } return box; } input.addevent('click', function() { if (this.listbox) return; this.listbox = createlist(); this.inbox = false; }.bind(input)); input.addevent('blur' , function() { if (!this.listbox || this.inbox) return; this.listbox.close(); this.listbox = null; this.em.value = this.em.value.trim(); }.bind(input)); input.addevent('keyup' , function(evt) { if (!this.listbox) return; var e = evt||window.event; var keycode = e.keycode||e.which||e.charcode; if (keycode == 27) { this.listbox.close(); this.listbox = null; return; } }.bind(input)); input.exttype = "inputwithlist" return input; }, inputdatewp : window.wdatepicker? function(op, notab) { op.maxlen = 10; var input = this.input('text', op, notab); input.setattr('onclick', wdatepicker); return input; }: function() { throw new error('需要引入wdatepicker.js'); }, inputdate : function(op, notab) { op.maxlen = 10; var input = this.input('text', op, notab); var click = function () { if (this.listbox) return; this.listbox = createdatebox(this); this.inbox = false; }.bind(input); input.setattr('onclick', click); input.off = function() { if (this.listbox) { this.listbox.close(); this.listbox = null; } input.setattr("onclick", sk.nop); }; input.on = function() { input.setattr("onclick", click); }; input.setattr('onblur' , function() { if (!this.listbox || this.inbox) { if (this.exitfunc) // 由于onblur被占用,所以可在此定义一个退出函数 this.exitfunc(); return; } this.listbox.close(); this.listbox = null; this.val(this.val().dbc2sbc().trim()); if (this.exitfunc) // 由于onblur被占用,所以可在此定义一个退出函数 this.exitfunc(); }.bind(input)); input.setattr('onkeyup' , function(evt) { if (!this.listbox) return; var e = evt||window.event; var keycode = e.keycode||e.which||e.charcode; if (keycode == 27) { this.listbox.close(); this.listbox = null; return; } }.bind(input)); input.exttype = "dateinput"; return input; }, // 可通过iframe.dom.root()获取iframe中的body然后在其上构建dom,效果同普通div,但iframe不能尺寸自适应,不能使消息上浮到父body,所以 // 一般不应使用,只在文件上传等特定场合用一下. iframe : function(op, cssfilelist) { if (!cssfilelist) cssfilelist = []; var fm = this.el('iframe', op); fm.cssfilelist = cssfilelist; var con = fm.em.contentdocument || fm.em.contentwindow.document; if (!con) throw new error('未能获取document对象,不能创建iframe.'); fm.dom = new dom(con); var rel = ""; for (var i=0; i'; con.open(); con.write('' + rel +''); con.close(); fm.window = fm.em.contentwindow; fm.reset = iframe_reset; return fm; }, iframefromsrc : function(op, src) { if (!op) op = {} if (!op.attr) op.attr = {}; op.attr.src = src; var fm = this.el('iframe', op); var con = fm.em.contentdocument || fm.em.contentwindow.document; if (!con) throw new error('未能获取document对象,不能创建iframe.'); fm.dom = new dom(con); fm.window = fm.em.contentwindow; fm.em.tabindex = -1; fm.reset = nosupport; return fm; } }; function nosupport() {alert("error:这个方法不被该对象支持!")} function createdatebox(input) { var box = input.downlistbox(175, 133); box.innerhtml = 'dd'; box.input = input; box.setattr("id", "calendar"); box.setstyle("border", "1px solid #fefefe"); box.setattr("onmouseover" ,function(){this.input.inbox = true;}.bind(box)); box.setattr("onmouseout" ,function(){this.input.inbox = false;this.input.focus();}.bind(box)); var tab = box.tbody({cs:1}); var tr = tab.tr(); tr.td({attr:{cls:"butt", onclick:function(){ box.today.setfullyear(box.today.getfullyear()-1); writecalendar.call(box); }}}).span().text("<"); box.year = tr.td({attr:{colspan:2}}).input('text',{w:46}).integer(4).keydown(function(keycode){ if (keycode == 13) { box.today.setfullyear(parseint(box.year.val(),10)); writecalendar.call(box); } }); tr.td({attr:{cls:"butt", onclick:function(){ box.today.setfullyear(box.today.getfullyear()+1); writecalendar.call(box); }}}).span().text(">"); tr.td({attr:{cls:"butt", onclick:function(){ box.today.setmonth(box.today.getmonth()-1); writecalendar.call(box); }}}).span().text("<"); box.month = tr.td().input('text',{w:22}).integer(2).keydown(function(keycode){ if (keycode == 13) { box.today.setmonth(parseint(box.month.val(),10)-1); writecalendar.call(box); } }); tr.td({attr:{cls:"butt", onclick:function(){ box.today.setmonth(box.today.getmonth()+1); writecalendar.call(box); }}}).span().text(">"); tr = tab.tr(); tr.td({cls:"head"}).span().text('日'); tr.td({cls:"head"}).span().text('一'); tr.td({cls:"head"}).span().text('二'); tr.td({cls:"head"}).span().text('三'); tr.td({cls:"head"}).span().text('四'); tr.td({cls:"head"}).span().text('五'); tr.td({cls:"head"}).span().text('六'); box.cells = []; var p = 0; for (var i=0; i < 6; i++) { tr = tab.tr(); for (var j=0; j < 7; j++,p++) { var td = tr.td({cls:'cell'}); td.lab = td.span(); box.cells[p] = td; } } box.today = input.val().todate(); if (!box.today) box.today = new date(); writecalendar.call(box); return box; } function writecalendar() { var monthdays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; function getdays(year, month) { if (month == 2) { if (((year % 4 == 0) && (year % 100 != 0))||(year % 400 == 0)) return 29; else return 28; } else return monthdays[month -1]; } function calcstartday(today) { var ts = today.gettime(); var firstday = today; firstday.setdate(1); var testme = firstday.getdate(); if (testme == 2) firstday.setdate(0); var fd = firstday.getday(); today.settime(ts); return fd; } var self = this; function click(i) { var d = i; return function() { self.input.val(self.today.getfullyear() + '-' + ((self.today.getmonth() + 101) + '').substr(1,2) + '-' + ((d + 100) + '').substr(1,2)); self.input.listbox = null; var input = self.input; settimeout(function(){ input.focus(); if (input.dateselected) input.dateselected(); },50); self.close(); }; } var year = this.today.getfullyear(); var month = this.today.getmonth() + 1; this.year.val(year); this.month.val(month); var startday = calcstartday(this.today); var today = this.today.getdate(); var daycount = getdays(year, month); today = today <= daycount? today : daycount; for (var i = 0; i < startday; i ++) { var td = this.cells[i]; td.lab.settext(''); td.setattr("onmouseover", sk.nop); td.setattr("onmouseout", sk.nop); td.setattr("onclick", sk.nop); } for (; i < startday + daycount; i ++) { td = this.cells[i]; if (today == i - startday + 1) td.lab.setclass("today"); else td.lab.setclass(""); var day = (i - startday) + 1; td.lab.settext(day); td.setattr("onmouseover", sk.evt.mover); td.setattr("onmouseout", sk.evt.mout); td.setattr("onclick", click(day)); } for (; i < this.cells.length; i ++) { td = this.cells[i]; td.lab.settext(''); td.setattr("onmouseover", sk.nop); td.setattr("onmouseout", sk.nop); td.setattr("onclick", sk.nop); } } // 大附件上传按钮 elagent.prototype.uploadlargefile = function(label, op, mod, param, backcall, error) { var input = this.div({cls:"hide_div"}).input("file", {attr:{ name : 'file', onchange:function() {startupload.call(this, mod, param, backcall, error);} }}); this.button(label, op).click(function(){ input.click(); }); }; // 每块10m,需根据服务器配置进行调整,不能大于服务器上传最大尺寸 var upload_black_size = 4*1024*1024; function startupload(mod, param, backcall, error) { var file = this.files[0]; var bkcount = math.floor(file.size/upload_black_size)+1; var totalsize = file.size; var start = 0;//每次上传的开始字节 var end = start + upload_black_size;//每次上传的结尾字节 param.f_size = file.size; param.bk_count = bkcount; param.filename = (mod + file.name + new date().gettime()).md5(); param.bk_sn = 1; var box = sk.dlg.popbox(0, 0, 270, 80); box.tt = box.div({cls:"am", css:{pa:"8px"}}).text("正在上传数据,请等待..."); box.pr = box.div({cls:"am", css:{pa:"4px"}}).div({w:260, h:10, css:{border:"1px solid #000000"}}); box.prog = box.pr.div({w:"0", h:10, css:{bgc:"red"}}); box.box = box; box.adjustpos().center(); sendbk(); function sendbk() { var url = sk.rc.procurl+"?mod=" + encodeuricomponent(mod) + "&data=" + encodeuricomponent(o(param).tojson());// + '×tamp=' + new date().gettime(); var fd = new formdata();//每一次需要重新创建 var blob = file.slice(start,end);//根据长度截取每次需要上传的数据 fd.append('file',blob);//添加数据到fd对象中 try { var xmlhttp = sk.ajax.connect(); xmlhttp.onreadystatechange = function() { if (xmlhttp.readystate != 4) return; var msg = sk.ajax.errmsg(xmlhttp); if (msg != null) { sk.ajax.lasterror = msg; xmlhttp = null; alert(msg); box.close(); return; } var rs = xmlhttp.responsetext; xmlhttp = null; sk.ajax.getobj(rs, function(ret){ box.prog.setwidth((box.pr.getwidth()-2)*param.bk_sn/param.bk_count); start = end; end = start + upload_black_size; param.bk_sn ++; if (start < totalsize) { sendbk(); } else { box.close(); backcall(ret); } }, function(obj){ box.close(); if (error) error(obj); else sk.ajax.onerror(obj); }); }; xmlhttp.open('post', url, true); xmlhttp.send(fd); } catch (e) { sk.ajax.lasterror = "uploadlargefile错误!" + e.name + ":" + e.message; alert(msg); return; } } } })(); // dom操作类=============end========================================= // 控制组件========================================================================================================================== sk.ctrl = {}; (function(){ // 两个对象叠加出一个新的对象。 sk.objectadd = function(obj1, obj2) { var obj = {}; for (var p in obj1) obj[p] = obj1[p]; for ( p in obj2) obj[p] = obj2[p]; return obj; }; // 单重单次局限继承,即父对象不能是继承结果对象,结果对象也不能再被继承 sk.finalextends = function(superclass, class) { var obj = {}; obj.super = {}; for (var p in superclass) { if (typeof superclass[p] == 'function') { obj.super[p] = superclass[p]; } obj[p] = superclass[p]; } for (p in class) obj[p] = class[p]; return obj; }; // table控制页的基本结构 sk.ctrl.tablepageclientbase = { client : null, // 可能有的独立客户区,由genclient创建 foot : null, // 可能有的独立页脚区,由genclient创建 enter : function() { if (!this.client) this.init(); else { if (this.client) this.client.show(); if (this.foot) this.foot.show(); } }, exit : function(destory) { if (destory) { if (this.client) this.client.parent().removechild(this.client); if (this.foot) this.foot.parent().removechild(this.foot); } else { if (this.client) this.client.hide(); if (this.foot) this.foot.hide(); } }, // 派生对象中定义的方法 init : sk.nop }; // headdiv安装控制头的区域,clientdiv内容区域, // vdir控制头排列方向,默认水平上方,vdir=true则垂直左侧 function etable(headdiv, clientdiv, vdir) { var tab = this.handtab = headdiv.tbody({cls:vdir?'tab_ctrol_hand_v':'tab_ctrol_hand_h'}); this.sptr = tab.tr(); this.space = this.sptr.td({cls:'tab_blc tab_handsp'}); this.vdf = vdir; this.client = clientdiv; clientdiv.addclass('tab_ctrol_blc'); clientdiv.addclass(vdir?'tab_client_v':'tab_client_h'); this.handa = []; this.activepage = -1; } sk.ctrl.tablectrol = function(headdiv, clientdiv, vdir) { return new etable(headdiv, clientdiv, vdir); }; function gotopage(index) { if (index<0) index = 0; else if (index >= this.handa.length) index = this.handa.length - 1; if (index == this.activepage) return; if (this.activepage >= 0) { var oldpage = this.handa[this.activepage]; oldpage.removeclass('active'); oldpage.addclass('unactive'); oldpage.exitfunc(); oldpage.setattr('onmouseover', sk.evt.mover); oldpage.setattr('onmouseout', sk.evt.mout); } var newpage = this.handa[index]; newpage.removeclass('unactive'); newpage.addclass('active'); newpage.enterfunc(); newpage.setattr('onmouseover', sk.nop); newpage.setattr('onmouseout', sk.nop); newpage.removeclass('mmover'); this.activepage = index; } etable.prototype = { // 增加一个页,title:标题,size:宽度或高度,被排列方向而定,pageclient页客户对象 append : function(title, size, pageclient, op) { if (this.vdf) { // 垂直排列 var hand = this.sptr.before('tr').td({h:size, cls:'tab_blc unactive'}); hand.split = this.sptr.before('tr').td({cls:'tab_blc split'}); } else { // 水平排列 hand = this.space.before('td', {w:size, cls:'tab_blc unactive'}); hand.split = this.space.before('td', {cls:'tab_blc split'}); } hand.split.div({cls:'fulldiv'}).text(' '); hand.index = this.handa.length; hand.enterfunc = function() {pageclient.enter();}; hand.exitfunc = function(df){pageclient.exit(df);}; hand.mgr = this; this.handa[hand.index] = hand; if (typeof title != 'function') hand.div(op).text(title); else title(hand); hand.setattr('onmouseover', sk.evt.mover); hand.setattr('onmouseout', sk.evt.mout); hand.setattr('onclick',function(){ this.mgr.gotopage(this.index); }.bind(hand)); }, // 一般只用于垂直排列的tabctrol调用, adjustsize:function() { this.handtab.parent().hide(); if (this.vdf) this.handtab.parent().setheight(this.client.getheight()); else this.handtab.parent().setwidth(this.client.getwidth()); this.handtab.parent().show(); }, // 删除指定的页,索引从0开始 remove : function(ind) { if (this.handa.length==0 || this.handa.length <= ind) return; var needgoto = -1; var hand = this.handa[ind]; if (this.activepage == ind) { needgoto = this.activepage; this.activepage = -1; } else { if (this.activepage > ind) this.activepage --; } // 删除页头 hand.exitfunc(true); // 表示是删除页而不是退出页,提示外部应用做一些必要的特殊处理 if (this.vdf) { this.handtab.removechild(hand.split); this.handtab.removechild(hand); } else { this.sptr.removechild(hand.split); this.sptr.removechild(hand); } // 调整页数组 for (var i = ind + 1; i < this.handa.length; i++) { this.handa[i-1] = this.handa[i]; this.handa[i-1].index = i-1; } this.handa.length --; if (needgoto >= 0) { if (needgoto < this.handa.length) this.gotopage(needgoto); else { needgoto = this.handa.length - 1; if (needgoto >= 0) this.gotopage(needgoto); } } }, // 转到指定的tab,函数内不对pn范围进行校验,如果越界将出错 gotopage : function(pn) { gotopage.call(this, pn); }, // 设置指定页头标的内容,可以是文字也可以是html内容,如果要在上面创建元素,则可以tabobj.hand[i].appendchild(el) settitle : function(ind, data) { this.handa[ind].settext(data); } }; })(); sk.grid = {}; (function() { // 翻页显示的数据模型控制逻辑 /* function pagecontrol( pagesize, // 每页的项目数 fnlist, //int list(po)方法,接受对象参数po,其中pageno指明读哪一页,pagesize指明一页项目数,其他域由应用自定;返回总的数据项目数 extobj // 扩展参数对象{ pageindi:页数指示元素, pagesel:页面跳转输入框, listbefore:数据装入前的附加动作, listbeforeparam:数据装入前的附加动作参数,普通调用 listafter:数据装入后的附加动作, listafterparam:数据装入后的附加动作参数,普通调用 rcafter :远程调用,在更新视图前后对返回数据进行处理的函数,以模型本身为this,call(this, ret) ) **/ function datamodel( psize, fnlist, extobj ) { this.fnlist = fnlist; this.ext = extobj; this.data = null; this.viewlist = []; this.listpo = { pagesize : psize, totalpage : 0, totalrec : 0, pageno : 0, sortmode : extobj&&extobj.sortmode?extobj.sortmode:0 }; if (this.ext.pageselect) { this.ext.pageselect.setattr('onkeydown', gotopage.bind(this)); } } function gotopage(evt) { var e = evt||window.event; var keycode = e.keycode||e.which||e.charcode; if (keycode != 13) // 回车 return; var ps = this.ext.pageselect; var page = parseint(ps.val().trim().dbc2sbc(), 10); ps.val(page); if (isnan(page)) { ps.val(''); return; } if (page > this.listpo.totalpage) page = this.listpo.totalpage; else if (page <= 0) page = 1; this.listpo.pageno = page - 1; this.list(); } sk.grid.datamodel = function(psize, fnlist, extobj) {return new datamodel(psize, fnlist, extobj);}; // 带有简单页面控制的功能按钮的翻页器,这是一个工厂方法 sk.grid.basedatamodel = function ( psize, // 页行数 fnlist, // 取数据函数,func(po) return string // 返回读取数据的uri,同时设置一些过滤(查找)的条件等,默认以get方式读取,除非设置po.post = true; // 默认以同步方式工作,除非设置po.asyn = true; pcp, // 安装翻页控制的区域 pvp, // 安装页数显示的区域 po ) { var pagectrl = null; var ctrpage = null; var selpage = null; var totalpagev = null; if (!po) po = {}; if (pcp) { if (po.button) pcp.button('上一页').click(function(){pagectrl.prevpage();}); else pcp.abutton('上一页', function(){pagectrl.prevpage();}); ctrpage = pcp.el('span', {}); if (po.button) pcp.button('下一页').click(function(){pagectrl.nextpage();}); else pcp.abutton('下一页', function(){pagectrl.nextpage();}); if (po.nopagegoto) { selpage = pcp.input('text', {w:40}).hide(); } else { pcp.el('span', {html:' 转第'}); selpage = pcp.input('text', {w:40}); pcp.el('span', {html:'页'}); } if (po.cflushbutton) { pcp.el('span', {html:po.cflushbutton}); pcp.abutton('刷新', function(){pagectrl.list();}); } } if (pvp) { pvp.el('span', {html:'共'}); totalpagev = pvp.el('span', {}); pvp.el('span', {html:'条记录'}); } po.pageindicator = ctrpage, po.pageselect = selpage, po.reccount = totalpagev; pagectrl = sk.grid.datamodel(psize, fnlist, po); return pagectrl; }; datamodel.prototype = { super : datamodel.prototype, getlistpo : function() { return o(this.listpo).clone(); }, getdata : function() { return this.data; }, // 返回服务器端的数据包形式数据,用于list(tp, data)调用以实现本地刷新 getservreturn : function() { }, getcell : function(rownumb, colname) { return this.data[rownumb][colname]; }, updateview : function() { var self = this; this.viewlist.each(function(o){o.update(self.data, self.listpo);}); }, getalldata : function(sortmode) { var vo = {page:0, size:-1, sort:sortmode?sortmode:0}; var mod = this.fnlist(vo); var d = sk.rc.sget(mod, vo); return d?d.list:[]; }, // tp是用于改变内部po的外部参数如页尺寸,页码等,如空则使用内部po参数进行刷新,一般都为空,只在一些特殊场合可能会使用 // data是外部提供的数据,如果空则向服务器获取数据。一般都为空而由模型自己从服务器上取数据,只在一些特殊场合可能会从外部提供数据 list : function(tp, data) { var exit = false; this.viewlist.each(function(o){ if (o.editctrol) exit |= (!o.editctrol.pagechange()); }); if (exit) return; var self = this; var po = this.listpo; if (!tp) tp = {}; if (self.ext) { var ext = self.ext; if (ext.listbefore) // 固定的前函数 ext.listbefore.call(this, ext.listbeforeparam); } if (tp && tp.listbefore) // 临时的前函数 tp.listbefore(tp.listbeforeparam); // 用传入的数据刷新视图和相关的一些状态显示 function flushviews(ret){ if (ret) { if (ret.list) self.data = ret.list; else self.data = []; po.totalrec = ret.count; po.pageno = ret.pagenumb; } else { self.data = []; po.totalrec = 0; po.pageno = 0; } po.totalpage = math.floor(po.totalrec / po.pagesize); if (po.totalrec % po.pagesize> 0) po.totalpage ++; if (self.ext && self.ext.rcafter) self.ext.rcafter.call(self, ret); // 更新视图 self.updateview(); if (self.ext) { var ext = self.ext; if (ext.pageindicator) ext.pageindicator.setattr('html', " | 第" + (po.pageno + 1) + '页,共' + po.totalpage + '页 | '); if (ext.pageselect) { ext.pageselect.setattr('value', self.listpo.pageno + 1); } if (ext.reccount) { ext.reccount.settext(po.totalrec); } if (ext.listafter) // 固定的后函数 ext.listafter(ext.listafterparam); } if (tp && tp.listafter) // 临时的后函数 tp.listafter(tp.listafterparam); } if (data) { flushviews(data); return; } if (tp.pageno) po.pageno = tp.pageno; if (tp.pagesize) po.pagesize = tp.pagesize; if (tp.sortmode) po.sortmode = tp.sortmode; var vo = {page:po.pageno, size:po.pagesize, sort:po.sortmode}; var mod = self.fnlist(vo); var rccaller = sk.rc.get; if (vo.post) { if (vo.asyn) rccaller = sk.rc.apost; else rccaller = sk.rc.post; } else { if (vo.asyn) rccaller = sk.rc.aget; else rccaller = sk.rc.get; } var msg = '正在读取数据...'; if (vo.msg) { msg = vo.msg; delete vo.msg; } rccaller(mod, vo, msg, flushviews); }, getlistparam : function() { var po = this.listpo; var vo = {page:po.pageno, size:po.pagesize, sort:po.sortmode}; this.fnlist(vo); return vo; }, nextpage : function(po) { if (this.listpo.pageno < this.listpo.totalpage -1) { this.listpo.pageno ++; this.list(po); } }, prevpage : function(po) { if (this.listpo.pageno > 0) { this.listpo.pageno --; this.list(po); } }, firstpage : function(po) { this.listpo.pageno = 0; this.list(po); }, lastpage : function(po) { this.listpo.pageno = -1; // 告诉服务器返回最后一页 this.list(po); }, reset : function(po) { this.listpo.pageno = 0; this.list(po); }, getpagesize : function() { return this.listpo.pagesize; }, gettotalrecnumb : function() { return this.listpo.totalrec; }, setpagesize : function(ps, po) { this.listpo.pagesize = ps; this.viewlist.each(function(o){o.rebuild();}); this.reset(po); }, // rm指定排序方式改变后的数据页变化,缺省为转第一页,1:页码不变,2:转最后一页 // force=true时强制指定升降序,缺省为自动切换升降序 // sortmode的值为正负值时对应某种排列方式的升或降序。 setsortmode : function(m, rm, force, po) { if (force) this.listpo.sortmode = m; else { if (math.abs(m) == math.abs(this.listpo.sortmode)) this.listpo.sortmode = -this.listpo.sortmode; else this.listpo.sortmode = m; } if (rm == 1) this.list(); else if (rm == 2) this.lastpage(po); else this.reset(po); return this; }, getsortmode : function(abs) { if (abs) return math.abs(this.listpo.sortmode); else return this.listpo.sortmode; } }; //====================================================================================== // 创建翻页表格图视的框架性函数 /* gridview(...showfunc范例) function showfunc(data, po) { if (po.totalrec == 0) { this.nonedatapane.removeclass('hide'); } else { this.nonedatapane.addclass('hide'); } for (var i = 0; i < po.pagesize && i < data.length; i++) { var row = this.urow[i]; var d = data[i]; row.setattr('onmouseover', sk.evt.mover); row.setattr('onmouseout', sk.evt.mout); if (d.act != 't') { // 禁用 row.setclass('redrow'); } else { row.setclass('row'); } row.id.update(d.id); . . row.act.update(); editctrol.roweditable(i, true); } for (; i < po.pagesize; i++) { editctrol.roweditable(i, false); row = this.urow[i]; row.setclass('nonerow'); row.id.update(''); . . row.act.update(); } this.adjust(); } */ function gridviewframe( headheight, tabw, // 表格宽度 wunit, // 宽度单位(px或%) rowcount, // 一页的行数 chead, // 创建头部各列的函数 crow // 创建表体中行各列的函数 ) { this.bodydiv.sethtml(""); var body = this.bodydiv.el('div', {}); if (this.headdiv) { this.headdiv.sethtml(""); var th = this.headdiv.tbody({cls:'formual relat', cs:this.linewidth, css:{h:headheight, w:tabw + wunit, mal:this.marginwidth}}); this.headtable = th.parent(); // 独立的表头 this.bodydiv.setattr("onscroll", gscroll.bind(this)); } else// 没有头部则将头创建在表体上 th = body.tbody({cls:'formual', cs:this.linewidth, css:{h:headheight, w:tabw + wunit, mal:this.marginwidth}}); // 创建表头部分 chead(th); if (this.headdiv) var tab = body.tbody({cls:'formual', cs:this.linewidth, css:{mal:this.marginwidth, w:tabw + wunit}, attr:{align:'left'}}); else// 没有头部则在表头部分继续创建表体,因为头部就在表体上了 tab = th; tab.head = this.headdiv; for (var i = 0; i < rowcount; i ++) { // 逐行创建表体 crow(tab, i); } this.nonedatapane = this.bodydiv.el('div', {cls:'fz20 am red hide', html:'没有相应数据!'}); this.body = tab.parent(); this.head = th.parent(); this.width = tabw; this.unit = wunit; // var root = sk.dom.root(); // if (this.resizefid) root.removelister("onresize", this.resizefid); // root.addlister("onresize", this.adjust.throttel(this)); } function gscroll() { this.headtable.setleft(-1*this.bodydiv.scrollleft()); } // 重新排序后,将转到第一页 function gridviewcolsort(n) {this.setsortmode(n);} // 视图定义表为一个两维数组,一行定义一个列,列的出现排序和数组的行顺序一致 // 0 1 2 3 4 5 6 7 // [列宽,表头cls, 列名文本, 列排序代号, 列数cls, 列数据名, 列编辑器配置,列保存函数] // 7空则创建不可编辑的列, // 3=0则为不可排序的列, // 3=-1则创建内容为6(此时6为字符串)的固定标签,并以7作为点击时的动作函数,5为管理用的列名,而非数据列名,但不可与数据列重名 // 当创建不可编辑的列时,6为一个函数(show.call(单元格显示元素对象, rd, colname)用于在数据显示前进行变换)或空. // 当创建可编辑的列时6为一个包含一组函数和数据的对象 // op { // size : 指定可输入的最大字符数,只在使用缺省编辑框时有效,当制定时,则这个参数不起作用 // editctrol : 定制编辑框的函数,不指定则使用editdefaultcreater // set : 定制从数据源向编辑框设置数据时的过滤函数,默认为val() // get : 定制在从编辑框取数据的到数据源进行保存时的过滤函数,可以在此进行数据检查和一些其他转换等,默认为val() * 当需要对输入的空值给缺省值时可在此进行 // show : 定制将数据源中的内容显示在非编辑模式下时的单元格中时的文本过滤函数,默认为直接赋值 // able : 定制单元格是否可被编辑的判定函数,able.call(可编辑单元格对象, rownumb, colnumb) return boolean; // 以上所指数据源为sk.ctrl.gridpagecontrol中的数据,即从服务器返回的对象数组 // } function gridview( viewdef, // 视图定义数组表 datamodel, createfunc, // 从外部定义的调用create方法来创建视图的函数,但也可以重新定义视图以实现更复杂的视图将视图分为横滚和不横滚两部分 po /* : headdiv, bodydiv, editctrol, // 编辑控制器,如果这个表视图不可编辑则不需要这个参数 showfunc, // 显示视图的函数,定义视图显示的总方法,一般不需使用这个函数,建议以updatesetup设置视图显示方法 selectfunc // 行被点击选中时的功能函数,传入所选行的数据,视图加载或翻页时将自动清除选择。如不指定则视图无行选功能。 unselectfunc // 行被取消选择时的功能函数,传入所选行的数据。但在视图数据重载或翻页时则传入null,因为此时数据可能已变为其他页上的内容。 selectclass // 行被点击选中时的颜色式样,如不指定但有selectfunc被指定时则使用默认值 */ ){ this.viewdef = viewdef; this.datamodel = datamodel; this.createfunc = createfunc; this.headdiv = po.headdiv; this.bodydiv = po.bodydiv; this.showfunc = po.showfunc; this.editctrol = po.editctrol; this.selectfunc = po.selectfunc; this.unselectfunc = po.unselectfunc; this.singleline = po.singleline?true:false; this.linewidth = po.linewidth?po.linewidth:'1'; this.selectrownumb = -1; this.marginwidth = po.marginwidth?po.marginwidth:'4px'; if (po.selectclass) this.selectclass = po.selectclass; else this.selectclass = 'selectrow'; if (po.editctrol) { po.editctrol.datamodel = datamodel; po.editctrol.view = this; } this.hcols = []; this.urow = []; this.htitles = []; this.sortmode = 0; datamodel.viewlist.append(this); this.rebuild(); } sk.grid.gridview = function(viewdef, datamodel, createfunc, op){ return new gridview(viewdef, datamodel, createfunc, op); }; function createtablecell(tr, tdh, i, d, clipf) { if (d[3]<0) // cls, w, h, text, view, rownumb, func, owner 所在的行对象 return tr.newopt(d[4], d[0], tdh, d[6], this, i, d[7], clipf); else if (!d[7]) { if (d[6]=='calc') return tr.newncell(d[4], d[0], tdh, this, this.datamodel, i, d[5], clipf); else //sk.dom.addmethod("newcell", function(cls, w, tdh, datamodel, rownumb, colname, showfunc) { return tr.newcell(d[4], d[0], tdh, this, this.datamodel, i, d[5], d[6], clipf); } else //sk.dom.addmethod("neweditcell", function(cls, w, tdh, colname, editctrol, datasaver, op) { return tr.neweditcell(d[4], d[0], tdh, d[5], this.editctrol, d[7], d[6], clipf); } // 默认的行标记方法 function defaultmarkrow(cls, flag) { if (flag == "+") this.addclass(cls); else this.removeclass(cls); } function rowselect() { var dm = this.view.datamodel; var vi = this.view; if (!vi.selectfunc) return; if (vi.selectrownumb == this.index) return; if (this.index >= dm.getdata().length) return; if (vi.selectrownumb >= 0) { var rd = dm.getdata()[vi.selectrownumb]; var tr = vi.urow[vi.selectrownumb]; if (vi.unselectfunc) vi.unselectfunc.call(tr, rd); tr.mark(vi.selectclass, '-'); } vi.selectrownumb = this.index; rd = dm.getdata()[this.index]; this.mark(vi.selectclass, '+'); vi.selectfunc.call(this, rd); } function mover() {this.addclass(sk.config.css.hover);} function mout() {this.removeclass(sk.config.css.hover);} gridview.prototype = { super : gridview.prototype, selectrow : function(rno) { if (rno == this.selectrownumb) return 0; if (rno<0 || rno>=this.datamodel.getdata().length) return -1; rowselect.call(this.urow[rno]); return 1; }, hide : function() { if (this.headdiv) this.headdiv.setstyle("display", "none"); if (this.bodydiv) this.bodydiv.setstyle("display", "none"); }, show : function() { if (this.headdiv) this.headdiv.setstyle("display", ""); if (this.bodydiv) this.bodydiv.setstyle("display", ""); }, colcount : function() {return this.viewdef.length;}, // 重建视图 rebuild : function() {this.createfunc.call(this);return this;}, adjust : function() { if (this.unit != "%") { if (this.headdiv) this.head.setwidth(this.body.getwidth()); return this; } this.body.hide();if (this.head) this.head.hide(); var diffw = sk.dom.root().getwidth() - this.bodydiv.getwidth(); var w = (sk.dom.root().getwidth()- (sk.browser.isie && sk.browser.ieversion<8 ? 0 : 21) - diffw)*(this.width/100); this.body.show();if (this.head) this.head.show(); //sk.dom.popmsg("w=" + w + ",root=" + sk.dom.root().getwidth() + ",this.diffw=" + this.diffw); this.body.setwidth(w); if (this.head) // 有独立的头部则按体宽来设定头部 this.head.setwidth(this.body.getwidth()); return this; }, // 按参数构建视图的构架性函数,一般不在外部直接调用这个函数 // gridview的createfunc一般可通过调用本函数来创建视图,但也可另写函数自行定义视图 create : function( headheight, // 表头高度 rowheight, tabwidth, widthunit, rowcreateafter // 行创建后的附加动作 ){ function s(i,self) { return function(){gridviewcolsort.call(self, i);}; } if (this.editctrol) this.editctrol.clear(); var tdh = rowheight; this.hcols.length = 0; this.urow.length = 0; gridviewframe.call(this, headheight, tabwidth, widthunit, this.datamodel.listpo.pagesize, function(th) { var defa = this.viewdef; var thr = th.el('tr', {attr:{classname:'head', valign:'center'}, css:{h:headheight}}); this.hrow = {}; for (var i = 0; i < defa.length; i++) { var d = defa[i]; this.htitles[i] = this.hrow[d[5]] = this.hcols[d[3]] = thr.newthc(d[1], d[0], d[2], (d[3]<=0)?false:s(d[3], this)); } }.bind(this), function(tab, i){ var defa = this.viewdef; var tr = this.urow[i] = tab.el('tr', {attr:{valign:'center', classname:'nullrow', index : i, onmouseover:sk.nop, onmouseout :sk.nop}}); tr.mark = defaultmarkrow; tr.setattr("onclick", rowselect.bind(tr)); tr.index = i; tr.view = this; if (this.editctrol) this.editctrol.addrow(); // 0 1 2 3 4 5 6 7 // [列宽,表头cls, 列名文本, 列排序代号, 列cls, 列数据名, 列编辑器配置,列保存函数] for (var j = 0; j< defa.length; j++) { var d = defa[j]; this.urow[i][d[5]] = createtablecell.call(this, tr, tdh, i, d, this.singleline); } if (rowcreateafter) rowcreateafter.call(this, tab, tr, i); }.bind(this) ); return this; }, // rm指定排序方式改变后的数据页变化,缺省为转第一页,1:页码不变,2:转最后一页 // force=true时强制指定升降序,缺省为自动切换升降序 // sortmode的值为正负值时对应某种排列方式的升或降序。 setsortmode : function(m, rm, force) { this.datamodel.setsortmode(m, rm, force); return this; }, update : function(data, po) { if (this.datamodel.listpo.sortmode != this.sortmode) { if (this.sortmode != 0) this.hcols[math.abs(this.sortmode)].removeclass(sk.config.css.pagesorthead); this.sortmode = this.datamodel.listpo.sortmode; if (this.sortmode != 0) this.hcols[math.abs(this.sortmode)].addclass(sk.config.css.pagesorthead); } var vi = this; var orgselectrownumb = vi.selectrownumb; if (vi.selectfunc) { if (vi.selectrownumb >= 0) { var tr = vi.urow[vi.selectrownumb]; if (vi.unselectfunc) vi.unselectfunc.call(tr, null); tr.mark(vi.selectclass, '-'); vi.selectrownumb = -1; } } this.showfunc.call(this, data, po); if (vi.selectfunc) { if (orgselectrownumb < 0) orgselectrownumb = 0; if (orgselectrownumb >= data.length) orgselectrownumb = data.length - 1; if (orgselectrownumb >= 0) { rowselect.call(vi.urow[orgselectrownumb]); } } }, // 设置视力更新方式,以替换创建datamodel时所设置的更新方式,也可在创建时不指定更新方式,而在加载数据前用本函数设置 updatesetup : function( rowproc, // 对数据行进行处理的函数 emptyrowproc, // 当数据行数少于视图行数时,对没有对应数据的行的管理函数 rowhover, // 是否指示鼠标所在行 enter, // 对数据行进行处理前的预处理函数,如果返回true则整个更新将中止,空则使用标准处理过程:根据totalrec的值对nonedatapane进行操作 exit // 更新完成后退出前的处理函数,空则使用标准处理,调用adjust过程确保视图完整性。 ) { this.showfunc = function(data, po) { if (enter) { if (enter.call(this, data, po)) return; } else { if (po.totalrec == 0) { this.nonedatapane.removeclass('hide'); } else { this.nonedatapane.addclass('hide'); } } // 如果数据为空则要取消行选 if (data.length == 0 && this.unselectfunc) { this.unselectfunc.call(null, null); this.selectrownumb = -1; } var flag = rowhover; var defa = this.viewdef; for (var i = 0; i < po.pagesize && i < data.length; i++) { var row = this.urow[i]; var d = data[i]; if (flag) { row.setattr('onmouseover', mover.bind(row)); row.setattr('onmouseout', mout.bind(row)); } for (var j = 0; j < defa.length; j++) { if (defa[j]) row[defa[j][5]].update(); } if (row.swh) { // 特定的列名,用于显示序号,这是一种特殊的opt列.[ 40, "am", "序号", -1, "am", "swh", '' , sk.nop], row.swh.hand.text(i + 1 + (po.pagesize * po.pageno)); } if (this.editctrol) this.editctrol.roweditable(i, true); rowproc.call(this, row, d, i); if (this.editingrow == i) row.mark("editing", "+"); } for (; i < po.pagesize; i++) { row = this.urow[i]; if (flag) { row.setattr('onmouseover', sk.nop); row.setattr('onmouseout', sk.nop); } for (j = 0; j < defa.length; j++) { if (defa[j]) row[defa[j][5]].clear(); } if (this.editctrol) this.editctrol.roweditable(i, false); emptyrowproc.call(this, row, i); } if (exit) exit.call(this, data, po); else this.adjust(); }; return this; }, markrow : function(rownumb, cls, flag) { this.urow[rownumb].mark(cls, flag); }, hidecol : function(colname, flag) { flag = (flag?'none':''); this.hrow[colname].setstyle("display", flag); for (var i=0; i < this.urow.length; i++) this.urow[i][colname].td.setstyle("display", flag); } }; // ------------------------------------------------------------------------ // 在指定区域创建带固定头和左侧固定列的表格,尺寸由外部的区域指定 function scgscroll() { this.scrollheadc.setleft(-1*this.scrollbodydiv.scrollleft()); this.fixbodyc.settop(-1 * this.scrollbodydiv.scrolltop()); } function scg_hdtr_mmov(evt) { var e = evt||window.event; if (resizing) return; var dx = e.clientx - this.headtr.getleft() - int(this.marginwidth); var scleft = this.scrollbodydiv.scrollleft(); // sk.dlg.popmsg('x:'+ dx + ', y:' + dy + ', sc:' + scleft); var i = 0; var rx = 0; this.cwresizeindex = -1; while (i=rx-1 && dx<=rx+1) { this.maindiv.css("cursor","e-resize"); this.mousedx = rx + this.headtr.getleft() + int(this.marginwidth); this.cwresizeindex = i; return; } i++; } this.maindiv.css("cursor","default"); } function scg_hdtr_mdn(evt) { if (this.cwresizeindex < 0) return; var e = evt||window.event; agenton(this); agentbk.objcolwidth = agentbk.grid.viewdef[agentbk.grid.cwresizeindex][0]; } function agentmup(evt) { var grid = agentbk.grid; grid.setcolwidth(grid.cwresizeindex, agentbk.objcolwidth); agentoff(); sk.evt.stop(evt); } function agentmmov(evt){ var minwidth = 30; var e = evt||window.event; var vdef = agentbk.grid.viewdef[agentbk.grid.cwresizeindex]; var cw = vdef[0] - agentbk.grid.mousedx + e.clientx; if (cw >= minwidth) { xagent.x(e.clientx); agentbk.objcolwidth = cw; } else { xagent.x(agentbk.grid.mousedx - vdef[0] + minwidth); agentbk.objcolwidth = minwidth; } //sk.dlg.popmsg('cw:'+ agentbk.objcolwidth); sk.dom.clearselectarea(); sk.evt.stop(evt); } function agentoff() { var body = sk.dom.root(); body.setattr('onmousemove', null); body.setattr('onmouseup', null); agentbk.hide(); xagent.hide(); agentbk.grid.maindiv.css("cursor","default"); agentbk.grid = null; resizing = false; } var agentbk= null; var xagent = null; var resizing = false; function agenton(sender) { var body = sk.dom.root(); agentbk.grid = sender; agentbk.show(); agentbk.w(body.em.clientwidth).h(math.max(body.em.scrollheight, sk.bwc.getheight())); xagent.show(); xagent.h(sk.bwc.getheight()).x(sender.mousedx); body.setattr("onmouseup", agentmup); body.setattr("onmousemove", agentmmov); resizing = true; } function scgridviewframe( headheight, rowcount, // 一页的行数 chead, // 创建头部各列的函数 crow // 创建表体中行各列的函数 ) { if (!agentbk) { // 列宽调整拖动背板 var body = sk.dom.root(); agentbk = body.div({cls:"ddgl_agent_bkg onlyscreen show"}).css("cursor","e-resize"); xagent = agentbk.div({cls:'ddgl_agent_div', w:1, h:sk.bwc.getheight()}).css("bgc","#dd0000"); agentbk.w(body.em.clientwidth).h(math.max(body.em.scrollheight, sk.bwc.getheight())); agentbk.css("zindex",11001); xagent.css("zindex",12001).x(1); agentbk.hide(); xagent.hide(); } var maindiv = this.maindiv; maindiv.sethtml(""); maindiv.setclass("tablehead al"); var tab = maindiv.tbody({cs:'0'}); this.isscgrid = true; this.maintab = tab.parent(); var tr = this.headtr = tab.tr(); // 包含表头的行 tr.setattr("onmousemove", scg_hdtr_mmov.bind(this)); tr.setattr("onmousedown", scg_hdtr_mdn.bind(this)); this.fixheaddiv = tr.td().div({h:headheight}); this.scrollheaddiv = tr.td().div({h:headheight, cls:"tablehead relat"}); tr = tab.tr(); this.fixbodydiv = tr.td().div({cls:"tablehead relat"}); this.scrollbodydiv = tr.td().div({cls:"ascrollclient relat"}); this.fixheadc = this.fixheaddiv.div(); this.fixbodyc = this.fixbodydiv.div({cls:'relat'}); this.scrollheadc = this.scrollheaddiv.div({cls:'relat'}); this.scrollbodyc = this.scrollbodydiv.div({cls:'relat'}); this.scrollbodydiv.setattr("onscroll", scgscroll.bind(this)); // 填充四区 var fth = this.fixheadc.tbody({cls:'formual', cs:this.linewidth, css:{h:headheight + 'px', mal:this.marginwidth}}); var sth = this.scrollheadc.tbody({cls:'formual', cs:this.linewidth, css:{h:headheight + 'px', mar:this.marginwidth}}); // 创建表头部分 chead(fth, sth); var ftab = this.fixbodyc.tbody({cls:'formual', cs:this.linewidth, css:{mal:this.marginwidth, mab:this.marginwidth}}); var stab = this.scrollbodyc.tbody({cls:'formual', cs:this.linewidth, css:{mar:this.marginwidth, mab:this.marginwidth}}); for (var i = 0; i < rowcount; i ++) { // 逐行创建表体 crow(ftab, stab, i); } this.nonedatapane = this.scrollbodyc.el('div', {cls:'fz20 am red hide', html:'没有相应数据!'}); this.adjust.throttel(this)(); // var root = sk.dom.root(); // if (this.resizefid) root.removelister("onresize", this.resizefid); // root.addlister("onresize", this.adjust.throttel(this)); } function scgridview( viewdef, // 视图定义数组表 datamodel, createfunc, // 从外部定义的调用create方法来创建视图的函数,但也可以重新定义视图以实现更复杂的视图将视图分为横滚和不横滚两部分 maindiv, po /* : editctrol, // 编辑控制器,如果这个表视图不可编辑则不需要这个参数 showfunc, // 显示视图的函数,定义视图显示的总方法,一般不需使用这个函数,建议以updatesetup设置视图显示方法 selectfunc // 行被点击选中时的功能函数,传入所选行的数据,视图加载或翻页时将自动清除选择。如不指定则视图无行选功能。 unselectfunc // 行被取消选择时的功能函数,传入所选行的数据。但在视图数据重载或翻页时则传入null,因为此时数据可能已变为其他页上的内容。 selectclass // 行被点击选中时的颜色式样,如不指定但有selectfunc被指定时则使用默认值 */ ){ this.viewdef = viewdef; this.datamodel = datamodel; this.maindiv = maindiv; this.createfunc = createfunc; this.showfunc = po.showfunc; this.editctrol = po.editctrol; this.selectfunc = po.selectfunc; this.unselectfunc = po.unselectfunc; this.marginwidth = po.marginwidth?po.marginwidth:'4px'; this.singleline = po.singleline?true:false; this.linewidth = po.linewidth?po.linewidth:'1'; this.selectrownumb = -1; if (po.selectclass) this.selectclass = po.selectclass; else this.selectclass = 'selectrow'; if (po.editctrol) { po.editctrol.datamodel = datamodel; po.editctrol.view = this; } this.hcols = []; this.urow = []; this.htitles = []; this.sortmode = 0; datamodel.viewlist.append(this); this.rebuild(); } function storescroll(){ this.scrollheadc.setleft(-1 * this.saveleft); this.fixbodyc.settop(-1 * this.savetop); this.scrollbodydiv.scrolltop(this.savetop); this.scrollbodydiv.scrollleft(this.saveleft); } scgridview.prototype = { super : gridview.prototype, hide : function() {this.maintab.setstyle("display", "none");}, show : function() {this.maintab.setstyle("display", "");}, colcount : function() {return this.viewdef.length - 1;}, getcolwidth : function(index) { return this.viewdef[index][0] }, setcolwidth : function(index, newwidth) { if (this.viewdef[index][0]==newwidth) { //sk.dlg.popmsg('宽度与原值相同'); return; } //sk.dlg.popmsg('设<'+ this.viewdef[index][2] + '>(列号:' + index + ')宽度为:' + newwidth); this.htitles[index].w(newwidth); this.htitles[index].dv.w(newwidth); var fn = this.viewdef[index][5]; for(var i=0; ithis.ftr.h()) this.ftr.h(this.str.h()); else this.str.h(this.ftr.h()); } }; sk.grid.scgridview = function( viewdef, datamodel, createfunc, maindiv, po ){ return new scgridview( viewdef, datamodel, createfunc, maindiv, po ); }; //==================================================================================================== // 对sk.dom.elagent进行一些扩展 // 创建一个表头格,有函数则创建可击的列头 function setthctitle(t) {this.title.html(t);} sk.dom.addmethod("newthc", function(cls, w, text, func) { var td = this.td({"w":w}); var dv = td.dv = td.div({"cls":'deffs ' + cls, "w":w}); if (func) { if (sk.isfunction(text)) // 可以通过外部函数来构造复杂表头 text.call(dv, func); else { td.title = dv.abutton(text, func); } } else { if (sk.isfunction(text)) // 可以通过外部函数来构造复杂表头 text.call(dv); else { dv.html(text); } td.title = dv; } td.settitle = setthctitle; return td; }); function defaultshow(rd, colname) { var v = rd[colname]; v = (!v)?' ':v; this.settext(v); } function noneditclear() { // this.sethtml(''); this.clearchilden(); } function noneditcellupdate() { var r = this.datamodel.getdata()[this.rownumb]; if (r) this.show.call(this, r, this.colname); else this.settext(''); } function optclear() {this.setvisible(false);} function optupdate() {this.show.call(this);} function optshow() {this.setvisible(true);} sk.dom.addmethod("newopt", function(cls, w, h, text, view, rownumb, func, clipf){ var td = this.el('td', {"w":w, "h":h}); if (clipf) { var ep = td.div({"cls":'deffs ' + cls, "w":w}); var el = ep.div({css:{height:h+'px',lineheight:h+'px'}}); el.prev = ep; } else el = td.div({"cls":'deffs ' + cls, "w":w}); el.td = td; el.rownumb = rownumb; el.view = view; el.clear = optclear; el.update = optupdate; el.show = optshow; el.view = view; el.con = el.div(); if (func !== sk.nop) { el.clkfunc = func; td.setattr('onclick', function(){ this.clkfunc.call(this, this.view.datamodel.getdata()[this.rownumb], this.view.urow[this.rownumb]); }.bind(el)); td.setattr('onmouseover', function(){this.con.addclass('optmover');}.bind(el)); td.setattr('onmouseout' , function(){this.con.removeclass('optmover');}.bind(el)); } el.hand = el.con.el('span', {}).settext(text); return el; }); // tr上创建一个表格 // datamodel,rownumb,colname只在需要使用update方法自动更新时有用,如果使用自定义视图输出方式时可不用 // showfunc空则使用默认的方法,即原样输出 sk.dom.addmethod("newcell", function(cls, w, tdh, view, datamodel, rownumb, colname, showfunc, clipf) { var td = this.td({h:tdh, "w":w}); var cls = 'deffs ' + cls; if (clipf) { var ep = td.div({"cls":cls, "w":w}); var el = ep.div({css:{height:tdh+'px',lineheight:tdh+'px'}}); el.prev = ep; } else el = td.div({"cls":cls, "w":w});//.el("span", {}); if (datamodel) { el.td = td; el.view = view; el.datamodel = datamodel; el.rownumb = rownumb; el.colname = colname; el.update = noneditcellupdate; el.clear = noneditclear; if (showfunc) el.show = showfunc; else el.show = defaultshow; } //el.cls = cls; return el; }); // 创建一个不对应数据库字段的段,用于计算字段 sk.dom.addmethod("newncell", function(cls, w, tdh, view, datamodel, rownumb, colname, clipf) { var td = this.td({h:tdh, "w":w}); if (clipf) { var ep = td.div({"cls":'deffs ' + cls, "w":w}); var el = ep.div({css:{height:tdh+'px',lineheight:tdh+'px'}}); el.prev = ep; } else el = td.div({"cls":'deffs ' + cls, "w":w});//.el("span", {}); if (datamodel) { el.td = td; el.view = view; el.datamodel = datamodel; el.rownumb = rownumb; el.colname = colname; el.update = sk.nop; el.clear = noneditclear; el.show = sk.nop; } return el; }); //========================================================================================= // 创建可编辑的表格单元 // 所在的行号和列号由editctrol根据创建editcell的顺序进行编排 // 可编辑的单元格中的内容不能是html代码,只能是纯文本 function editdefaultcreater(parent, w, h) { var el = parent.input("text", {cls:'defaultedit', 'w':w, 'h':h}); if (this.op) { var op = this.op; if (op.size) el.len(op.size); if (op.sbc) el.sbc(op.size); if (op.trim) el.trim(op.size); if (op.int) el.integer(op.size); if (op.uint) el.uint(op.size); if (op.real) el.real(op.size); if (op.code) el.code(op.size); } return el; } function defaultget() {return this.val().trim().length == 0?null:this.val().trim();} function onblur(evt) { var edit = this.edit; if (!edit) return; if (edit.exttype == "dateinput"||edit.exttype == "inputwithlist") { if (edit.listbox && edit.inbox) return; } if (this.close()) { if (this.orgblur) this.orgblur.call(edit.em, evt); } else { settimeout(function(){this.focus();}.bind(edit), 100); } if (this.ctrol.view.isscgrid) { this.ctrol.view.urow.each(function(i){i.adjust()}); } } function editopen() { if (this.edit) return; if (!this.able()) return; if (!this.ctrol.setcurrentedit(this)) return; var w = this.td.getwidth()-(sk.browser.isie?0:2); var h = this.td.getheight()-2; var edit = this.edit = this.editcreater(this.td, w, h); // edit.addclass(this.dv.parent().getclass()); edit.addclass(this.cls); if (edit.tag()=="select") edit.w(w-(sk.browser.isie?2:0)); edit.get = this.op && this.op.get ? this.op.get : defaultget; edit.set = this.op && this.op.set ? this.op.set : edit.val; this.dv.setdisplay(false); edit.set(this.ctrol.celldata(this.rownumb, this.colname)); this.orgblur = edit.getattr("onblur"); edit.setattr("onblur", onblur.bind(this));//throttel // this.td.addclass('editing'); this.ctrol.view.markrow(this.rownumb, "editing", "+"); this.ctrol.view.editingrow = this.rownumb; if (this.ctrol.view.selectrownumb != this.rownumb) rowselect.call(this.ctrol.view.urow[this.rownumb]); if (sk.browser.isie) { settimeout(edit.focus.bind(edit), 100); //edit.focus(); } else { edit.focus(); } if (this.ctrol.openeditafter) this.ctrol.openeditafter.call(this.ctrol); this.orgkeydown = edit.getattr("onkeydown"); edit.setattr("onkeydown", onkeydown.bind(this)); if (this.ctrol.view.isscgrid) { this.ctrol.view.urow.each(function(i){i.adjust()}); } } function onkeydown(evt) { var e = evt||window.event; var keycode = e.keycode||e.which||e.charcode; switch (keycode) { case 13: if (this.edit.tag() == 'textarea') return true; //settimeout(function(){this.close();}.bind(this), 10); var ne = this.ctrol.getnext(); if (ne) { settimeout(function(){editopen.call(ne);},30); } else { this.close(); } return true; break; case 27: //esc this.close("cancel"); if (this.ctrol.view.isscgrid) { this.ctrol.view.urow.each(function(i){i.adjust()}); } return true; break; case 9: //tab if (e.shiftkey) ne = this.ctrol.getprev(); else ne = this.ctrol.getnext(); if (ne) { settimeout(function(){editopen.call(ne);},30); } return false; break; case 38: // up if (this.edit.tag() == 'textarea') return true; if (this.edit.tag() == 'select') return false; ne = this.ctrol.getup(); if (ne) { editopen.call(ne); return false; } break; case 40: // down if (this.edit.tag() == 'textarea') return true; if (this.edit.tag() == 'select') return false; ne = this.ctrol.getdown(); if (ne) { editopen.call(ne); return false; } break; case 37: // left if (this.edit.tag() == 'textarea') return true; if (this.edit.tag() == 'select') return false; if (this.edit) { var movf = true; if (!e.ctrlkey && this.edit.tag() == 'input' && (this.edit.type()=='text'||this.edit.type()=='password')) if (this.edit.getcurpos()!=0) movf = false; if (movf) { ne = this.ctrol.getprev(); if (ne) { editopen.call(ne); return false; } } } break; case 39: // right if (this.edit.tag() == 'textarea') return true; if (this.edit.tag() == 'select') return false; if (this.edit) { movf = true; if (!e.ctrlkey && this.edit.tag() == 'input' && (this.edit.type()=='text'||this.edit.type()=='password')) if (this.edit.getcurpos()!=this.edit.val().length) movf = false; if (movf) { ne = this.ctrol.getnext(); if (ne) { editopen.call(ne); return false; } } } break; default: break; } if (this.orgkeydown) return this.orgkeydown.call(this.edit.em, evt); return true; } function editablecell(tr, cls, w, tdh, colname, editctrol, datasaver, op, clipf) { this.td = tr.el('td', {h:tdh, "w":w, attr:{"ondblclick":editopen.bind(this)}}); var cls = 'deffs ' + cls; if (clipf) { var ep = this.td.div({"cls":cls, "w":w}); this.dv = ep.div({css:{height:tdh+'px',lineheight:tdh+'px'}}); this.dv.prev = ep; } else this.dv = this.td.el('div', {"cls":cls, "w":w});//.el("span", {}); this.op = op; this.edit = null; this.colname = colname, this.ctrol = editctrol; this.view = editctrol.view; this.dv.view = this.view; this.cls = cls; editctrol.addcell(this); this.editcreater = (op && op.editcreater?op.editcreater:editdefaultcreater); if (op && op.show) this.show = op.show; else this.show = defaultshow; this.datasaver = datasaver; } // gridview的可编辑列的定义对象---------------------------------------------------------------------------------------------------------------------------------------------- // op { // size : 指定可输入的最大字符数,只在使用缺省编辑框时有效,当制定时,则这个参数不起作用 // notnull:是否为非空字段 // check : 保存数据前的检查函数,如果返回true则进行保存并关闭编辑,不指定则不检查 // editctrol : 定制编辑框的函数,不指定则使用editdefaultcreater // set : 定制从数据源向编辑框设置数据时的过滤函数,默认为val() // get : 定制在从编辑框取数据的到数据源进行保存时的过滤函数,可以在此进行数据检查和一些其他转换等,默认为val() * 当需要对输入的空值给缺省值时可在此进行 // show : 定制将数据源中的内容显示在非编辑模式下时的单元格中时的文本过滤函数,默认为直接赋值 // 以上所指数据源为sk.ctrl.gridpagecontrol中的数据,即从服务器返回的对象数组 // sbc : 有自动转半角功能 // trim : 去头尾空格 // int : 整数录入 // uint : 正整数录入 // real : 小数录入 // code : 大写代码 // } sk.dom.addmethod("neweditcell", function(cls, w, tdh, colname, editctrol, datasaver, op, clipf) { return new editablecell(this, cls, w, tdh, colname, editctrol, datasaver, op, clipf); }); editablecell.prototype = { super : editablecell.prototype, clear : function() {/* this.sethtml(''); */this.dv.clearchilden();}, close : function(fm) { if (!this.edit) return true; var equ = true; if (fm!="cancel") { var v = this.edit.get(); if (typeof(v)=="string") { equ = v.trim().equ(this.ctrol.celldata(this.rownumb, this.colname)); } else { equ = (v == this.ctrol.celldata(this.rownumb, this.colname)); } if (!equ) { var edit = this.edit; // 防止在弹出窗口时onblur引发close二次重入 this.edit = null; if (this.op.notnull && (v==null||v.length==0)) { this.edit = edit; //alert("此项目不能为空"); sk.dlg.popmsg('

此项不能为空,请按esc键恢复原先内容。

点击关闭提示
', -2, -2); return false; } if (this.op && this.op.check) if (!this.op.check(v)) { this.edit = edit; return false; } if (!this.datasaver(this.rownumb, this.colname, v)) { this.edit = edit; return false; } this.edit = edit; this.ctrol.celldata(this.rownumb, this.colname, v); } } // this.td.removeclass('editing'); if (this.edit.exttype == "dateinput") { if (this.edit.listbox) { this.edit.listbox.close(); this.edit.listbox = null; } } this.ctrol.view.markrow(this.rownumb, "editing", "-"); this.ctrol.view.editingrow = -1; this.edit.setattr("onblur", null); this.td.removechild(this.edit); this.edit = null; this.dv.setdisplay(true); this.ctrol.currentopen = null; if (!equ) this.ctrol.datamodel.updateview(); return true; }, update : function() { var r = this.ctrol.rowdata(this.rownumb); if (r) this.show.call(this.dv, r, this.colname); else this.dv.settext(''); }, able : function() { if (this.op.able) return this.op.able.call(this, this.rownumb, this.colnumb); else return this.ctrol.celleditable(this.rownumb, this.colnumb); } }; // 编辑控制器,主要实现可编辑的单元格输入焦点在表格上的移动,单元格状态控制,数据的提取和保存 function editctrol(op) { this.list = []; this.grid = []; this.enablerow = []; this.enablecol = []; this.currentopen = null; this.datamodel = null; if (op) { if (op.openeditafter) this.openeditafter = op.openeditafter; } } sk.grid.editctrol = function(op) { return new editctrol(op); }; editctrol.prototype = { // 当表格因参数调整被重构时,应先调用这个函数清空之前的单元格对象 clear : function() { this.list = []; this.grid = []; this.enablerow = []; this.enablecol = []; this.currentopen = null; }, setcurrentedit : function(edit) { if (this.closecurrentedit()) { this.currentopen = edit; return true; } else return false; }, closecurrentedit : function() { if (this.currentopen) { if (this.currentopen.close()) { this.currentopen = null; return true; } return false; } return true; }, getup : function() { // 取当前单元的上一行同列单元 if (!this.currentopen) return null; var col = this.currentopen.colnumb; var row = this.currentopen.rownumb - 1; while (row >= 0) { var ne = this.grid[row][col]; if (ne.able()) return ne; row --; } return null; }, getdown : function() { if (!this.currentopen) return null; var col = this.currentopen.colnumb; var row = this.currentopen.rownumb + 1; while (row < this.grid.length) { var ne = this.grid[row][col]; if (ne.able()) return ne; row ++; } return null; }, getnext : function() { // 取当前单元的下一单元,跳过不可编辑的部分 if (!this.currentopen) return null; var index = this.currentopen.index + 1; while (index < this.list.length) { var ne = this.list[index]; if (ne.able()) return ne; index ++; } return null; }, getprev : function() { // 取当前单元的上一单元,跳过不可编辑的部分 if (!this.currentopen) return null; var index = this.currentopen.index - 1; while (index >= 0) { var ne = this.list[index]; if (ne.able()) return ne; index --; } return null; }, getcnext : function() { // 按循环方式取当前单元的下一单元,跳过不可编辑的部分 if (!this.currentopen) return null; var ne = this.list[(this.currentopen.index + 1) % (this.list.length)]; while (ne.index != this.currentopen.index) { if (ne.able()) return ne; ne = this.list[(ne.index + 1) % (this.list.length)]; } return null; }, getcprev : function() { // 按循环方式取当前单元的上一单元,跳过不可编辑的部分 if (!this.currentopen) return null; var ne = this.list[(this.currentopen.index - 1 < 0)?this.list.length-1:this.currentopen.index - 1]; while (ne.index != this.currentopen.index) { if (ne.able()) return ne; ne = this.list[(ne.index - 1 < 0)?this.list.length:ne.index - 1]; } return null; }, // 增加一行,增加后,新加入的单元格将排列在新的行中,目前不支持加列 // 增加前,将比较当前的行是否和第一行的个数一致,如不一致将报错 addrow : function() { if (this.grid.length >= 2) { // 如果要增加第三行及之后的行,将比较当前的最后一行的个数是否和第一行一致 var lcc = this.grid[this.grid.length - 1].length; var fcc = this.grid[0].length; if (lcc != fcc) throw 'first row colcount <> last row colcount'; } this.grid[this.grid.length] = []; this.enablerow[this.enablerow.length] = false; }, addcell : function(cell) { // 增加一个单元格到最近增加的行中,如果在第一行以后的行中加入,则增加的单元个数不应多于第一行中的单元个数 var row = this.rowcount() - 1; if (row < 0) // 目前没有加入过行 throw 'addcell call rowcount=0-a'; var col = this.grid[row].length; if (row == 0) { this.enablecol[this.enablecol.length] = true; } else { var maxcol = this.grid[0].length; if (col >= maxcol) throw 'colcount > first row colcount-addcell'; } cell.dv.rownumb = row; cell.rownumb = row; cell.colnumb = col; this.grid[row][col] = cell; cell.index = this.list.length; this.list[this.list.length] = cell; }, roweditable : function(rn, f) { // 存、取行可编辑状态 if (arguments.length > 1) { if (rn >= this.rowcount()) throw 'rownumb > rowcount-a'; this.enablerow[rn] = f; } return this.enablerow[rn]; }, coleditable : function(cn, f) { // 存、取列可编辑状态 if (arguments.length > 1) { if (cn >= this.colcount()) throw 'colnumb > colcount-1'; this.enablecol[cn] = f; } return this.enablecol[cn]; }, celleditable : function(rn, cn) { // 取单元可编辑状态,要单元所在的行和列同进可编辑时单元格才可编辑 if (cn >= this.colcount()) throw 'colnumb > colcount-2'; if (cn >= this.colcount()) throw 'colnumb > colcount-2'; return this.coleditable(cn) && this.roweditable(rn); }, getcell : function(rn, cn) { if (cn >= this.colcount()) throw 'colnumb > colcount-3'; if (cn >= this.colcount()) throw 'colnumb > colcount-3'; return this.grid[rn][cn]; }, rowcount : function() { // 取行数 return this.grid.length; }, colcount : function() { // 取列数 var l = this.grid[0]; return (l?l.length:0); }, celldata : function(row, colname, data) { if (!this.datamodel.data || this.datamodel.data.length <= row) return null; if (arguments.length > 2) { this.datamodel.data[row][colname] = data; } return this.datamodel.data[row][colname]; }, rowdata : function(row) { if (this.datamodel.data.length <= row) return null; return this.datamodel.data[row]; }, // 数据翻页前的处理过程,主要是处理已打开的单元格的状态,为保存数据提供最后机会,同时提供了阻止翻页的最后机会 // 返回false则可阻止翻页 pagechange : function() { return this.closecurrentedit(); } }; })(); // 各类对话框类============================================================================================================================ (function() { var dlgbkg = null; var mox = -1; var moy = -1; var sender = null; var body = null; var closebefore = null; // 由外部应用定义的对话框关闭前的检查函数,返回false则阻止关闭动作,空则不进行这个检查 // dialog的移动函数 function dlgmousedown(evt) { var e = evt||window.event; body = sk.dom.root().em; try { mox = e.clientx; moy = e.clienty; dlgbkg.setattr('onmousemove', bkgmousemove); dlgbkg.setattr('onmouseup', bkgmouseup); sender = this; sender.win.setstyle('cursor', 'move'); } catch(e) { } } function bkgmousemove(evt) { var e = evt||window.event; try { if (sk._browser != 'sa') { var x = e.clientx - mox; var y = e.clienty - moy; } else { x = e.clientx - mox;// + sk.dlg.body.scrollleft; y = e.clienty - moy;// + sk.dlg.body.scrolltop; } mox = e.clientx; moy = e.clienty; var dlg = sender.win; y = dlg.gettop() + y; dlg.settop(y>=0?y:0); dlg.setleft(dlg.getleft() + x); sender.setstyle('cursor', 'move'); } catch(e) { } } function bkgmouseup(evt) { try { sender.win.setstyle('cursor', 'default'); dlgbkg.setattr('onmousemove', sk.nop); dlgbkg.setattr('onmouseup', sk.nop); mox = -1; moy = -1; if (sender.moveafter) sender.moveafter.call(sender); sender = null; body = null; } catch(e) {} } function ifmbb() { var body = sk.dom.root(); var bkg = sk.dom.create("div"); bkg.setclass("ddgl_dialog_bkg onlyscreen show"); bkg.setstyle("zindex", 1); bkg.setwidth(body.em.clientwidth); bkg.setheight(math.max(body.em.scrollheight, body.em.clientheight)); bkg.em.innerhtml = ""; var bb = sk.dom.create('iframe'); bb.em.style.position = 'absolute'; bb.em.style.width = '100%'; bb.em.style.height= '100%'; bb.em.style.zindex = '-1'; bb.em.style.filter = "alpha(opacity=0)"; bb.em.style.border = "0px"; bkg.appendchild(bb); return bkg; } function poscenter(dlg, offset, y, x) { if (!offset) offset = 0; var body = sk.dom.root().em; if (x == 'left') var x = 0; else if (x == 'right') x = body.clientwidth - dlg.getwidth(); else if (typeof x === "number") x =x; else x = (body.clientwidth - dlg.getwidth())/2; dlg.setleft(x); if (typeof y === "number") var y =y; else { y = (sk.bwc.getheight() - dlg.getheight())/3 + sk.bwc.getscrolltop() + offset; } dlg.settop(y>0?y:0); } /* function poscenter(dlg, offset, y, x) { if (!offset) offset = 0; var body = sk.dom.root().em; if (x) { if (x == 'left') var x = 0; else if (x == 'right') x = body.clientwidth - dlg.getwidth(); else // x = (body.clientwidth - dlg.getwidth())/2; x = x; } else x = (body.clientwidth - dlg.getwidth())/2; dlg.setleft(x); if (y) var y =y; else { y = (sk.bwc.getheight() - dlg.getheight())/3 + sk.bwc.getscrolltop() + offset; } dlg.settop(y>0?y:0); } */ function showdlg(dlg) { dlg.setstyle('display', ''); dlg.removeclass('hide'); dlg.addclass('show'); if (dlg._sox || dlg._soy) { dlg.setleft(dlg._sox); dlg.settop(dlg._soy); dlg._sox = dlg._soy = false; } } function hidedlg(dlg) { dlg._sox = dlg.getleft(); dlg._soy = dlg.gettop(); dlg.setstyle('display', 'none'); dlg.removeclass('show'); dlg.addclass('hide'); } function closedlg() { if (closebefore) if (!closebefore()) return; closebefore = null; dlgbkg.innerhtml = ""; var body = sk.dom.root(); body.removechild(dlgbkg); dlgbkg = null; } // winmgr窗口列表 // 非模式窗口管理器=================================================================== var winmgr = { wmlist : [], add : function(w) {}, remove : function(w) { this.unactive(w); }, active : function(w) { var l = this.wmlist.last(); if (l && l != w) this.wmlist.remove(w); this.wmlist.append(w); this.wmlist.each(function(o, c){ o.activecolor(false); o.setzindex(1001 + c); }); w.setzindex(10000); w.activecolor(true); }, unactive : function(w) { this.wmlist.remove(w); w.activecolor(false); var l = this.wmlist.last(); if (!l) return; this.wmlist.each(function(o, c){ o.activecolor(false); o.setzindex(1001 + c); }); l.setzindex(10000); l.activecolor(true); } }; // 基于table的弹出窗口布局工具 function layout(client, csv, lpa, ba) { if (!csv) csv = 4; if (!lpa) lpa = 2 + 'px'; if (!ba && !sk.isstring(ba)) ba = 'center'; this.lpa = lpa; this.tab = client.tbody({cs:csv, attr:{align:ba}}); } function layouttd(op) { if (!op) op = {}; if (!op.cls) var cls = "layout_line_m al"; else cls = "layout_line_m " + op.cls; var attr = {}; if (op.cs) attr.colspan = op.cs; if (op.rs) attr.rowspan = op.rs; return this.el('td', {'cls':cls, 'attr':attr, css:{pab:this.lpa, pat:this.lpa}}); } layout.prototype = { line : function(cls, va, w) { if (!va) va = 'center'; if (!cls) cls = "layout_line_m al"; else cls = "layout_line_m " + cls; return this.tab.tr({attr:{valign:va}}).td({'cls':cls, w:w, css:{pab:this.lpa, pat:this.lpa}}); }, tr : function(va) { if (!va) va = 'center'; var tr = this.tab.tr({attr:{valign:va}}); tr.lpa = this.lpa; tr.td = layouttd; return tr; }, setwidth : function(w) { this.tab.parent().setwidth(w); return this; }, // 创建一个td宽度依次为tdws数组中的值的布局。如果指定了第二参数w则还会设置布局总宽度为w。 tda : function(tdws, w, va) { if (!va) va = 'center'; if (w==0) { var tr = this.tab.tr().td({css:{pab:this.lpa, pat:this.lpa}}).tbody({cs:'0',cp:'0', css:{w:'100%'}}).tr({attr:{valign:va}}); } else { tr = this.tab.tr().td({css:{pab:this.lpa, pat:this.lpa}}).tbody({w:w, cs:'0',cp:'0'}).tr({attr:{valign:va}}); } var ra = []; var pa = this.lpa; tdws.each(function(w){ ra.add(tr.td({w:w, cls:'layout_line_m', css:{pab:pa, pat:pa}})); }); return ra; } }; function getlayout(csv, lpa, ba) { if (!this.m_layout) this.m_layout = new layout(this.client, csv, lpa, ba); return this.m_layout; } var menucdelay = 5; // 菜单显示延时 var popmsgbpos = 0; function getpopyoffset() { popmsgbpos = (popmsgbpos + 4)%30; return popmsgbpos; } // =showprocbox使用的全局变量==== 2005年邮箱试验项目中的一个状态提示框,暂时无需重写. var _current_proc_dlg_ = null; sk.dlg = { ifmbb : ifmbb, getlayout : getlayout, // 一般不直接用这个取得布局器,除非要设置非默认的布局参数,此时就不应调用窗口对象自身的layout方法 layout : function(client, csv, lpa, ba) {return new layout(client, csv, lpa, ba);}, // 单实例模式对话框 dialog : function(classname, text, cbf) { closebefore = cbf; body = sk.dom.root(); if (dlgbkg == null) { var bkg = sk.dom.create("div"); dlgbkg = bkg; } else bkg = dlgbkg; bkg.setclass("ddgl_dialog_bkg onlyscreen show"); bkg.setwidth(body.em.clientwidth); // bkg.setheight(math.max(body.em.scrollheight, body.em.clientheight)); bkg.setheight(math.max(body.em.scrollheight, sk.bwc.getheight())); body.appendchild(bkg); bkg.settext(""); var dobj = {}; var dlg = sk.dom.create("div"); dobj.win = dlg; if (!isnan(parseint(classname))) { dlg.setwidth(classname); dlg.setclass("ddgl_dialog"); } else dlg.setclass("ddgl_dialog " + classname); bkg.appendchild(dlg); if (parseint(sk.browser.ieversion) <= 6) { bkg.appendchild(ifmbb()); } dlg.el('div', {cls:"ddgl_dialog_l1"}); dlg.el('div', {cls:"ddgl_dialog_l2"}); dlg.el('div', {cls:"ddgl_dialog_l3"}); var el = dlg.el('div', {cls:'ddgl_dialog_title', attr:{onmousedown:dlgmousedown.bind(dobj)}}); var title = el.el('span', {css:{stylefloat:'left', cssfloat:'left'}}); dobj.titlespan = dobj.title = title; title.settext(text); el.el('span', {html:'[关闭]', css:{stylefloat:'right', cssfloat:'right', cursor:'pointer'}, attr:{onclick:closedlg}}); el = dlg.el('div', {cls:"ddgl_dialog_cc"}); dobj.client = el.el('div', {cls:"ddgl_dialog_client "}); dlg.el('div', {cls:"ddgl_dialog_l3"}); dlg.el('div', {cls:"ddgl_dialog_l2"}); dlg.el('div', {cls:"ddgl_dialog_l1"}); // sk.dlg.dlgposcenter(dlg, 60); // var sa = document.getelementsbytagname('select'); // for (var i = 0; i < sa.length; i++) // sa[i].style.visibility = 'hidden'; dobj.settitle = function(text) { this.titlespan.settext(text); }; dobj.close = function() { closedlg(); }; dobj.center = function(offset, y, x) { poscenter(this.win, offset, y, x); }; dobj.layout = getlayout; return dobj; }, // == 一些常用的框=================================================================================== messagedlg : function(title, message, classname, cbf) { var dlg = sk.dlg.dialog(classname?classname:"msgdlg", title, cbf); function msgclose() {dlg.close();} dlg.client.el('div', {cls:'win_cline', html:message}); var pl = dlg.client.el('div', {cls:'am'}); var bt = pl.input('button', {value:'确定', attr:{onclick:msgclose}}); dlg.client.spaceline(6); settimeout(function(){bt.focus(1);}, 10); dlg.center(60); }, message : function(title, msg, focus) { sk.dlg.messagedlg(title, msg, 300, function(){ if (focus) settimeout(function(){focus.focus(1);}); return true; }); }, // func是回调函数,函数可有一个参数po // po给回调函数的参数 // obj是给回调函数的this; confirmdlg : function(title, message, func, classname, cbf) { var dlg = sk.dlg.dialog(classname?classname:"msgdlg", title, cbf); function msgclose() { dlg.close(); } function ok() { if (func) if (!func()) return; dlg.close(); } dlg.client.el('div', {cls:'win_cline', html:message}); var pl = dlg.client.el('div', {cls:'am'}); pl.input('button', {value:'确定', attr:{onclick:ok}}); pl.el('span', {html:'   '}); pl.input('button', {value:'取消', attr:{onclick:msgclose}}); pl.spaceline(6); dlg.center(60); return dlg; }, messagewin : function(title, message, classname) { var dlg = new sk.dlg.window(classname?classname:"msgdlg", title, true); //var dlg = new sk.dlg.box(200, title, true, true); function msgclose() {dlg.close();} dlg.win.setstyle('zindex', 11200); dlg.client.el('div', {cls:'win_cline', html:message}); var pl = dlg.client.el('div', {cls:'am'}); var bt = pl.input('button', {value:'确定', attr:{onclick:msgclose}}); dlg.client.spaceline(6); dlg.center(60); settimeout(function(){bt.focus(1);}, 10); }, showprocbox : function (msg) { if (_current_proc_dlg_ != null) { return false; } var body = sk.dom.root(); var div = sk.dom.create('div'); div.em.style.position = 'absolute'; div.em.classname = 'onlyscreen'; div.em.style.zindex = '30000'; div.em.innerhtml = ''; body.appendchild(div); _current_proc_dlg_ = div; poscenter(div, 100); var con = document.getelementbyid('_comm_procbox_if_').contentdocument || document.frames('_comm_procbox_if_').document; con.open(); con.write('' +'' +'
' +'' +'' +'' +'' +'' +'
 '+ msg +'
' +'' +'
' +''); con.close(); return true; }, closeprocbox : function () { if (_current_proc_dlg_ != null) { var body = sk.dom.root(); body.removechild(_current_proc_dlg_); _current_proc_dlg_ = null; } }, // 弹出框,不同于dialog,window,box.popbox是不可被鼠标拖动的,位置也不是严格按参数定位的,实际位置将自动调整到刚好在窗口内不被裁剪的位置. popbox : function(x, y, w, h) { var box = sk.dom.root().el('div', {cls:'onlyscreen', css:sk.config.css.popbox}); box.dx = x, box.dy = y, box.dw = w, box.dh = h; // box.onclick = function(e) {stopbubble(e);}; box.adjustpos = function(op) { this.setwidth(this.dw); var sh = sk.bwc.getheight() + sk.bwc.getscrolltop(); var sw = sk.bwc.getwidth(); if (op&&op.ymod > 0) // 2013.12.2 this.dh = this.getheight(); // 2013.12.2 else this.dh = this.dh?this.dh:this.getheight(); if (this.dy + this.dh + 4 > sh) { if (op&&op.ymod > 0) { // 2013.12.2 this.dy = this.dy - this.dh + op.ymod; // 2013.12.2 } else { this.dy = this.dy - this.dh - 1; if (this.dy + this.dh + 4 > sh) this.dy = sh - this.dh - 2; } this.vdir = -1; } else this.vdir = 1; if (this.dx + this.dw > sw) { this.dx = this.dx - this.dw - 1; if (this.dx + this.dw > sw) this.dx = sw - this.dw - 2; this.hdir = -1; } else this.hdir = 1; this.setleft(this.dx + ((op&&op.x)?op.x:0)); this.settop(this.dy + ((op&&op.y)?op.y:0)); return this; // setobjheight(this, this.dh); }; // 将box转化为菜单closeafter是菜单关闭时的附加后继动作 box.tomenu = function(closeafter) { var body = sk.dom.root(); settimeout(function() { this.funcid = body.addlister("onmousedown", function() { this.close(); }.bind(this)); }.bind(this), menucdelay); this.close = function(){ if (this.submenu) { this.submenu.close(); this.submenu = null; } body.removelister("onmousedown", this.funcid); body.removechild(this); if (this.ctimer) cleartimeout(this.ctimer); this.parentmenuitem = null; this.parentmenu = null; if (closeafter) closeafter(); }; this.menucontact = this.el('div', {cls:'popmenu'}); // 增加一个菜单项目 this.addmenuitem = function(text, fc) { return this.menucontact.el('div', {cls:'item', html:text, attr:{onmouseover:sk.evt.mover, onmouseout:sk.evt.mout, onmousedown:fc?fc:sk.nop}}); }; this.addmenuref = function(text, url, target) { return this.menucontact.el('div', {cls:'item', attr:{onmouseover:sk.evt.mover, onmouseout:sk.evt.mout, onmousedown:sk.evt.stop}}).el( 'a', {html:text, attr:{href:url, "target":target?target:"_blank", onmousedown:function(evt){ sk.evt.stop(evt);settimeout(function(){this.close();}.bind(this),200); }.bind(this)}} ); }; this.addmenuline = function() { return this.menucontact.el('div', {cls:'line'}); }; this.addsubmenu = function(text, func) { var sub = this.menucontact.el('div', {cls:'item', html:text, attr:{onmousedown:sk.evt.stop}}); sub.setattr('onmouseover' ,function() { sk.evt.mover.call(this.em); if (this.submenu) { if (this.submenu.ctimer) { cleartimeout(this.submenu.ctimer); this.submenu.ctimer = false; this.pmenu.submenu = this.submenu; } return; } var sm = this.submenu = func(); var dx = this.getleft(); var dy = this.gettop(); sm.dx = dx + this.pmenu.dw - 8; sm.dy = dy; sm.adjustpos(); if (sm.hdir < 0) sm.dx = dx - sm.dw; if (sm.vdir < 0) { sm.dy = dy + this.getheight(); } if (sm.hdir < 0 || sm.vdir < 0) sm.adjustpos(); sm.parentmenuitem = this; sm.parentmenu = this.pmenu; sm.setattr('onmouseover', function() { if (this.ctimer) { cleartimeout(this.ctimer); this.ctimer = false; } }.bind(sm)); sm.setattr('onmouseout', function() { this.ctimer = settimeout(function(){ if (!this.parentmenuitem.submenu) return; sk.evt.mout.call(this.parentmenuitem.em); this.parentmenuitem.submenu = null; this.parentmenu.submenu = null; this.ctimer = false; this.close(); }.bind(this), menucdelay); }.bind(sm)); settimeout(function(){ this.pmenu.submenu = this.submenu; }.bind(this), menucdelay); }.bind(sub)); sub.setattr('onmouseout', function() { if (!this.submenu) return; var self = this; this.submenu.ctimer = settimeout(function(){ if (!self.submenu) return; self.submenu.ctimer = false; self.submenu.close(); self.submenu = null; self.pmenu.submenu = null; sk.evt.mout.call(self.em); }, menucdelay); }.bind(sub)); sub.pmenu = this; return sub; }; // addsubmenu }; // tomenu box.close = function() { sk.dom.root().removechild(this); }; box.show = function() { this.setstyle('display', ''); this.removeclass('hide'); this.addclass('show'); return this; }; box.hide = function() { this.setstyle('display', 'none'); this.removeclass('show'); this.addclass('hide'); return this; }; box.center = function(offset, y, x) { poscenter(this, offset, y, x); return this; }; return box; }, // 弹出一个非模式的消息框,可以设定自动关闭时间,单位:秒 popmessage : function(x, y, w, msg, time) { switch (x) { case -1:x = 30;break; case -2:x = (sk.bwc.getwidth() - w)/2;break; case -3:x = sk.bwc.getwidth() - 30;break; default:break; } var b = sk.dlg.popbox(x, y, w); b.setleft(w); var alpha = 100; var tid = false; b.setstyle('backgroundcolor', '#ffeb97'); b.setstyle('border', '1px solid #999'); b.setstyle('cursor' ,'default'); b.el('div', {html:msg, css:{color:'#000', padding:'2px'}}); //var tsp = b.el('div', {css:{textalign:'center', fontsize:'9pt', color:'#eeeeee'}}); //tsp.settext('点击关闭'+ (time?(','+ time+'秒后自动关闭'):'')); function closemsg() { if (!b.valid()) // 延时关闭过程中box有可能被程序直接关闭,所以要先检查一下. return; if (alpha <= 0) { b.close(); return; } alpha -= 10; b.setstyle('filter', "alpha(opacity=" + alpha + ')'); b.setstyle('opacity', (alpha/100) + ''); // b.adjustpos(); tid = settimeout(closemsg, 50); } function closebefore() { if (time) { tid = settimeout(function() { time --; //tsp.settext('点击关闭'+ (time?(','+ time+'秒后自动关闭'):'')); closebefore(); }, 1000); } else if (tid) { //tsp.settext('正在关闭'); closemsg(); } } b.adjustpos(); if (y < 0) { switch (y) { case -1:b.dy = 0;break; case -2:b.dy = (sk.bwc.getheight() - b.dh)/2 + sk.bwc.getscrolltop();break; case -3:b.dy = sk.bwc.getheight() - 30 - getpopyoffset() + sk.bwc.getscrolltop();break; case -4:b.dy = sk.bwc.getheight() - 30 + sk.bwc.getscrolltop();break; default:b.dy = y; } b.adjustpos(); } b.setattr('onclick', function() { if (tid) cleartimeout(tid); b.setattr('onclick', sk.nop); closemsg(); }); if (time) closebefore(); return b; }, popmsg : function(text, x, y, w, t){ if (currentpopmsgbox) { currentpopmsgbox.close(); } if (!x) x = -3; if (!y) y = -4; if (!w) w = 300; if (!t) t = 15; currentpopmsgbox = sk.dlg.popmessage(x, y, w, text, t); } }; var currentpopmsgbox = null; // rswindow, window, box的移动函数 var agentbk= null; var wagent = null; function agenton(sender, cur) { var body = sk.dom.root(); if (!agentbk) { agentbk = body.div({cls:"ddgl_agent_bkg onlyscreen show"}).attr("onmousedown",function(e) { if (sender.stopbubble) sk.evt.stop(e); }); wagent = agentbk.div({cls:'ddgl_agent_div'}); } agentbk.show(); wagent.show(); agentbk.w(body.em.clientwidth).h(math.max(body.em.scrollheight, sk.bwc.getheight())); wagent.x(sender.win.x()); wagent.y(sender.win.y()); wagent.w(sender.win.w()); wagent.h(sender.win.h()); agentbk.css("zindex",11001); wagent.css("zindex",12001); switch(cur) { case 1: case 4: wagent.css("cursor","n-resize "); break; case 2: case 3: wagent.css("cursor","e-resize"); break; default: wagent.css("cursor","move"); break; } } function agentoff() { wagent.css("cursor","default"); agentbk.hide(); wagent.hide(); } var moving = false; function mdown(evt) { if (this.maxed) return; sender = this; var e = evt||window.event; body = sk.dom.root(); mox = e.clientx; moy = e.clienty; body.setattr('onmousemove', mmove); body.setattr('onmouseup', mup); sender.win.css("cursor", "move"); if (sender.stopbubble) sk.evt.stop(evt); } function mmove(evt) { if (!moving) { sender.moveing = true; moving = true; agenton(sender); sender.win.hide(); } var e = evt||window.event; agentbk.css("zindex",11001); wagent.css("zindex",12001); var dx = e.clientx - mox; var dy = e.clienty - moy; mox = e.clientx; moy = e.clienty; var dlg = wagent; dy = dlg.gettop() + dy; wagent.settop(dy>=0?dy:0); wagent.setleft(wagent.getleft() + dx); } function mup() { if (!sender) return; // sender==null时为多余的调用,直接返回即可:2013.11.04 sender.moveing = false; sender.totop(); body.setattr('onmousemove', null); body.setattr('onmouseup', null); mox = -1; moy = -1; if (moving) { sender.win.x(wagent.x()).y(wagent.y()); agentoff(); moving = false; if (sender.moveafter) sender.moveafter.call(sender); } sender.win.css("cursor", "default"); sender = null; body = null; sk.dom.clearselectarea(); // 取消选中标记,当鼠标移动时可能会使窗口中的文本被意外选中,所以在此清除。 } //============================================================================= var resizedirect = -1; function winwidth(w, minv) { if (!minv) minv=200; return (w > minv?w:minv); } function winheight(h, minv) { if (!minv) minv=60; return (h > minv?h:minv); } // rswindow 的resize函数 function rswdown(evt) { sender = this.owner; if (sender.maxed) return; resizedirect = this.code; body = sk.dom.root(); body = sk.dom.root(); var e = evt||window.event; mox = e.clientx; moy = e.clienty; body.setattr('onmousemove', rswmove); body.setattr('onmouseup', rswup); sender.moveing = true; agenton(sender, resizedirect); sender.win.hide(); if (sender.stopbubble) sk.evt.stop(evt); } function rswmove(evt) { var e = evt||window.event; if (sk._browser != 'sa') { var dx = e.clientx - mox; var dy = e.clienty - moy; } else { dx = e.clientx - mox; dy = e.clienty - moy; } mox = e.clientx; moy = e.clienty; var dlg = wagent; switch(resizedirect) { case 1: if (sender.lockheight) return; var y = dlg.gettop(); var h = winheight(dlg.getheight() - dy, sender.minheight); dy = h - dlg.getheight(); var oy = y - dy; if (oy < 0) { h = h + oy; oy = 0; } dlg.settop(oy); dlg.setheight(h); break; case 2: if (sender.lockwidth) return; var x = dlg.getleft(); var w = winwidth(dlg.getwidth() - dx, sender.minwidth); dx = w - dlg.getwidth(); var ox = x - dx; if (ox < 0) {w = w + ox;ox = 0;} dlg.setleft(ox); dlg.setwidth(w); break; case 3: if (sender.lockwidth) return; w = winwidth(dlg.getwidth() + dx, sender.minwidth); dlg.setwidth(w); break; case 4: if (sender.lockheight) return; h = winheight(dlg.h() + dy, sender.minheight); dlg.setheight(h); break; } } function rswup() { sender.moveing = false; sender.totop(); sender.win.show(); body.setattr('onmousemove', null); body.setattr('onmouseup', null); sender.win.x(wagent.x()).y(wagent.y()); var dw = wagent.w() - sender.win.w(); var dh = wagent.h() - sender.win.h(); sender.client.w(sender.client.w()+dw); sender.client.h(sender.client.h()+dh); if (sender.client.resizeafter) sender.client.resizeafter.call(sender.client); if (sender.moveafter) sender.moveafter.call(sender); mox = -1; moy = -1; sender = null; body = null; agentoff(); } function rswmax() { var win = this.owner; if (win.maxed) { win.maxed = false; this.settext('[最大]'); win.win.setleft(this.orgx); win.win.settop(this.orgy); win.client.setwidth(this.orgw); win.client.setheight(this.orgh); if (win.client.resizeafter) win.client.resizeafter.call(win.client); } else { win.maxed = true; this.orgx = win.win.getleft(); this.orgy = win.win.gettop(); this.orgw = win.client.getwidth(); this.orgh = win.client.getheight(); win.win.setleft(0); win.win.settop(0); win.client.setwidth(sk.bwc.getwidth()- 10); win.client.setheight(sk.bwc.getheight()-30); if (win.client.resizeafter) win.client.resizeafter.call(win.client); this.settext('[还原]'); } } // 多实例窗口对象================================================ // 可通过在实例上定义whenclose函数就关闭前的动作进行检查并通过返回false中止关闭动作 // 可通过在实例上定义whenshowe函数就显示前的动作进行检查并通过返回false中止显示动作 // 注意:width,height是指客户区client的尺寸,而非窗口即包括边框和标题栏的尺寸 function rswindow(width, height, title, closemode, noclose) { width = winwidth(width); height= winheight(height); var body = sk.dom.root(); var dlg = body.div({cls:'kmhr_window onlyscreen', css:{zindex:'2000', top:'0px'}}); // dlg.setclass("kmhr_window onlyscreen"); // dlg.setstyle("zindex", 2000); // body.appendchild(dlg); dlg.setattr("onmousedown", function(){this.totop();}.bind(this)); var tb = dlg.tbody({}); this.cps = []; this.con = dlg; var td = tb.el("tr",{}).el("td",{cls:"ddgl_dialog_tbl", attr:{colspan:3}}); // 上边框 this.cps[0] = td.el('div', {cls:"ddgl_dialog_l1"}); this.cps[1] = td.el('div', {cls:"ddgl_dialog_l2"}); this.cps[2] = td.el('div', {cls:"ddgl_dialog_l3"}); td.code = 1;td.owner = this;td.setattr('onmousedown', rswdown.bind(td)); var tr = tb.el("tr", {}); var tdspc = sk.browser.issafari?'':' '; this.cps[7] = td = tr.el("td", {cls:'ddgl_dialog_ll', attr:{rowspan:2}}); // 左边框 td.div({w:4}); // 顶住宽度 td.code = 2;td.owner = this;td.setattr('onmousedown', rswdown.bind(td)); td = tr.el("td", {h:16}); var el = this.cps[3] = td.el('div', {w:width-16, cls:'ddgl_rswin_title', attr:{onmousedown:mdown.bind(this)}}); this.title = el.el('span', {html:title, css:{stylefloat:'left', cssfloat:'left'}}); if (!noclose) { this.closebutton = el.el('span', {css:{stylefloat:'right', cssfloat:'right', cursor:'pointer'}, attr:{onmousedown:function(evt){this.close(); sk.evt.stop(evt);}.bind(this)}}).settext('[关闭]'); } var maxbt = this.maxbutton = el.el('span', {css:{stylefloat:'right', cssfloat:'right', cursor:'pointer'}}).settext('[最大]'); maxbt.owner = this; maxbt.attr('onmousedown', rswmax.bind(maxbt)); this.maxed = false; this.max = rswmax.bind(maxbt); this.cps[6] = td = tr.el("td", {cls:'ddgl_dialog_rl', attr:{rowspan:2}}); // 右边框 td.div({w:4}); // 顶住宽度 td.code = 3;td.owner = this;td.setattr('onmousedown', rswdown.bind(td)); var cv = tb.el("tr",{}).el("td", {}).el("div", {w:width, h:height, cls:"ddgl_rswin_client"}); td = tb.el("tr", {}).el("td", {cls:"ddgl_dialog_tbl", attr:{colspan:3}}); // 下边框 this.cps[4] = td.el('div', {cls:"ddgl_dialog_l3"}); this.cps[5] = td.el('div', {cls:"ddgl_dialog_l2"}); this.cps[8] = td.el('div', {cls:"ddgl_dialog_l1"}); td.code = 4;td.owner = this;td.setattr('onmousedown', rswdown.bind(td)); this.closemode = closemode; this.win = dlg; this.client = cv; cv.title = this.cps[3]; cv.setwidth = function(w){ try { // wpatch是ie浏览器中对input.text的尺寸补偿值,其情况时为0或不存在这个属性 this.em.style.width = (w + (this.wpatch?this.wpatch:0)) + "px"; }catch(e){} cv.title.setwidth(w-16); return this; }; this.visible = true; winmgr.add(this); this.lifeflag = true; this.show(); } function window(classname, title, closemode, noclose) { var body = sk.dom.root(); var dlg = sk.dom.create("div"); if (!isnan(parseint(classname))) { dlg.setwidth(classname); dlg.setclass("kmhr_window onlyscreen"); } else dlg.setclass("kmhr_window onlyscreen " + classname); dlg.setstyle("zindex", 2000); dlg.setstyle("top", '0px'); dlg.setattr("onmousedown", function(){this.totop();}.bind(this)); body.appendchild(dlg); this.cps = []; this.con = dlg; this.cps[0] = dlg.el('div', {cls:"ddgl_dialog_l1"}); this.cps[1] = dlg.el('div', {cls:"ddgl_dialog_l2"}); this.cps[2] = dlg.el('div', {cls:"ddgl_dialog_l3"}); var el = this.cps[3] = dlg.el('div', {cls:'ddgl_dialog_title', attr:{onmousedown:mdown.bind(this)}}); this.title = el.el('span', {html:title, css:{stylefloat:'left', cssfloat:'left'}}); if (!noclose) { this.closebutton = el.el('span', {html:'[关闭]', css:{stylefloat:'right', cssfloat:'right', cursor:'pointer'}, attr:{onmousedown:function(evt){this.close(); sk.evt.stop(evt);}.bind(this)}}); } el = this.cps[4] = dlg.el('div', {cls:"ddgl_dialog_cc"}); var cv = el.el('div', {cls:"ddgl_dialog_client "}); this.cps[5] = dlg.el('div', {cls:"ddgl_dialog_l3"}); this.cps[6] = dlg.el('div', {cls:"ddgl_dialog_l2"}); this.cps[7] = dlg.el('div', {cls:"ddgl_dialog_l1"}); this.closemode = closemode; this.win = dlg; this.client = cv; this.visible = true; winmgr.add(this); this.lifeflag = true; this.show(); } function box(w, title, closemode, sbubble, noclosebtn) { var body = sk.dom.root(); var dlg = body.el('div', {'w':w, cls:"box_box onlyscreen ", css:{zindex:2000, top:'0px'}}); this.stopbubble = sbubble; if (sbubble) { dlg.setattr('onclick', function(e){sk.evt.stop(e);}); // 停止消息向上冒 dlg.setattr("onmousedown", function(e){this.totop();sk.evt.stop(e);}.bind(this)); } else dlg.setattr("onmousedown", function(){this.totop();}.bind(this)); this.cps = []; this.con = dlg; var el = this.cps[0] = dlg.el('div', {cls:'box_title', attr:{onmousedown:mdown.bind(this)}}); this.title = el.el('span', {html:title, css:{stylefloat:'left', cssfloat:'left'}}); if (!noclosebtn) this.closebutton = el.el('span', {html:'[关闭]', css:{stylefloat:'right', cssfloat:'right', cursor:'pointer'}, attr:{onmousedown:function(evt){this.close(); sk.evt.stop(evt);}.bind(this)}}); el = dlg.el('div', {cls:"box_cc", 'w':w}); var cv = this.cps[1] = el.el('div', {cls:"box_client "}); // dialog.dlgposcenter(dlg); this.closemode = closemode; this.win = dlg; this.client = cv.el('div', {css:{backgroundcolor:'#ffffff'}}); this.visible = true; winmgr.add(this); this.lifeflag = true; this.show(); } function destory() { winmgr.remove(this); this.visible = false; var body = sk.dom.root(); body.removechild(this.win); this.lifeflag = false; } function hide() { winmgr.unactive(this); this.visible = false; hidedlg(this.win); } function wclose() { if (!this.lifeflag) throw new error('重复关闭同一窗口'); if (this.whenclose) { if (!this.whenclose.call(this)) { mup(); // 如果是点击放弃关闭则有一个对mup的调用以清除agent_bkg return; } mup(); // 当弹出过确认框并确认关闭时也要调用mup以清除agent_bkg,如果没有弹出过框则此调用为多余,但mup中已对多余的调用进行了处理:2013.11.04 } if (this.closemode) destory.call(this); else hide.call(this); sk.dom.clearselectarea(); } rswindow.prototype = box.prototype = window.prototype = { super : box.prototype, layout : getlayout, clientreset : function() { this.m_layout = null; this.client.html(""); }, activecolor : function(flag) { if (this.whenactive) { if (!this.whenactive.call(this, flag)) return; } if (!this.cps) { } else if (this.cps.length < 3) { // box if (flag) { this.con.removeclass(sk.config.css.wingrap1); for (var i = 0; i < this.cps.length; i++) this.cps[i].removeclass(sk.config.css.wingrap1); } else { this.con.addclass(sk.config.css.wingrap1); for (i = 0; i < this.cps.length; i++) this.cps[i].addclass(sk.config.css.wingrap1); } } else { // windows if (flag) { this.con.removeclass(sk.config.css.wingrap); for (i = 1; i < this.cps.length - 1; i++) this.cps[i].removeclass(sk.config.css.wingrap); this.cps[0].removeclass(sk.config.css.wingrap); this.cps[this.cps.length - 1].removeclass(sk.config.css.wingrap); } else { this.con.addclass(sk.config.css.wingrap); for (i = 1; i < this.cps.length - 1; i++) this.cps[i].addclass(sk.config.css.wingrap); this.cps[0].addclass(sk.config.css.wingrap); this.cps[this.cps.length - 1].addclass(sk.config.css.wingrap); } } }, totop : function() { if (this.moveing) return; if (this.visible) this.show(); }, settitle : function(t) { this.title.settext(t); }, center : function(offset, y, x) { poscenter(this.win, offset, y, x); }, close : function(just) { if (just||this.justclose) // 立即关闭,设置justclose可以使点击窗口上的关闭按扭也是立即关闭,just则只是程序中调用close关闭时为立即关闭. wclose.call(this); else // 必须进行延迟调用以使关闭被whenclose阻塞时消息能以正确顺序进行 settimeout(wclose.bind(this),10); }, destory : destory, hide : hide, show : function() { if (!this.lifeflag) throw new error('试图打开已被消毁的窗口.'); if (this.whenshow) { if (!this.whenshow.call(this)) return; } this.visible = true; // this.win.style.display = "block"; showdlg(this.win); winmgr.active(this); }, setpos : function(x, y) { this.win.settop(y); this.win.setleft(x); }, setzindex : function(z) { this.win.setstyle('zindex', z); } }; sk.dlg.rswindow = function(width, height, title, closemode, noclose) {return new rswindow(width, height, title, closemode, noclose);}; sk.dlg.window = function(classname, title, closemode, noclose) {return new window(classname, title, closemode, noclose);}; sk.dlg.box = function(w, title, closemode, sbubble, noclose) {return new box(w, title, closemode, sbubble, noclose);}; })(); // 各类对话框类====end======================================================================================================================== // 可选的静态字典管理模块,字典内容由具体应用动态或静态装入,这里只是初始化一些操作功能------------------------------------------- sk.initstaticdict = function(){ // 静态字典管理 if (!window.sdict) window.sdict={}; if (window.sdict.findbyid) return; function findbyid(list, id) { for (var i = 0; i < list.length; i ++) { var d = list[i]; if (d.v == id) return d; else if (d.child) { var v = findbyid(d.child, id); if (v) return v; } } return null; } function tranarray(list, rev) { for (var i = 0; i < list.length; i ++) { var d = list[i]; rev[rev.length] = d; if (d.child) { tranarray(d.child, rev); } } } // // 在整个字典中查找指定id对应的字典项目,速度较慢,如果知道类型应用sdict.findbyid(type, id)。 sdict.findatall = function(id) { for (var p in sdict) { if (typeof sdict[p] === 'function') continue; var v = findbyid(sdict[p], id); if (v) return v; } return null; }; // 在整个字典中查找指定id对应的字典项目的字面值,速度较慢,如果知道类型应用sdict.findbyid(type, id)。 sdict.dta = function(id) { for (var p in sdict) { if (typeof sdict[p] === 'function') continue; var v = findbyid(sdict[p], id); if (v) return v.t; } return null; }; // 在指定的字典层级上进行线性查找(不深入子元素)指定id对应的字典项目 sdict.findlinebyid = function(list, id) { for (var i = 0; i < list.length; i ++) { var d = list[i]; if (d.v == id) return d; } return null; }; // 在指定的类型中查找指定id对应的字典项目 sdict.findbyid = function(type, id) { var list = sdict[type]; if (!list) return null; return findbyid(list, id); }; // 在指定的类型中查找字典的字面值 sdict.dt = function(type, id) { var list = sdict[type]; if (!list) return null; var v = findbyid(list, id); return v?v.t:null; }; // 将类型为type的多级(有的项目pid!=0)字典由线性结构(数组)转换为树型结构(加入child字段) // dict为要进行树型梳理的字典,默认为系统字典sdict // json_decode:是否对pc进行解码,对于静态文件字典不需要也不能再解码,但从远程读取的字典文本需要解码。 sdict.totree = function(type, dict, json_decode) { if (!dict) dict = sdict; var list = dict[type]; if (!list) return null; var da = []; var p = null; for (var i = 0; i < list.length; i++) { var ld = list[i]; if (json_decode && ld.pc) ld.pc = ld.pc.json_parse(); if (ld.p==0) { da[da.length] = ld; } else { if (!p || p.v != ld.p) { // 父元素与上一个元素的不同则要进行查找 p = findbyid(list, ld.p); if (!p) throw new error("fail:[" + ld.t + ']id:' + ld.v + ',pid:' + ld.p + '.找不到。'); if (!p.child) p.child = []; } p.child.add(ld); } } dict[type] = da; return da; }; sdict.getarray = function(type) { var list = sdict[type]; if (!list) throw new error('getarray at:' + type + ' not exist!'); var r = []; tranarray(list, r); return r; }; // 从数据库装载指定的字典,f=false则如果这个字典被装载过则不再装载而是直接返回,f=true则强制装载。 sdict.loadfromdb = function(type, f) { if (!f && sdict[type]) return; var ret = sk.rc.sget("sk.dict.loadsdictdata", {type:type}); sdict[type] = ret.list; sdict.totree(type, true); }; // 基于sdict字典的select式gridview列显示器 sdict.orcell = function(type) { return function(rd, colname) { var v = parseint(rd[colname], 10); if (isnan(v)) this.settext(''); else this.settext(sdict.dt(type, v)); }; }; // 基于sdict字典的select式gridview列编辑器 sdict.edcell = function(type, fs) { return { show : sdict.orcell(type), editcreater : function(parent, w, h) { var el = parent.selectmapvt({w:w, h:h}); el.setstyle("fs", fs?fs:"11pt"); el.append(-1, '  '); sdict.getarray(type).each(function(o){el.append(o.v, o.t);}); return el; } }; }; }; // 可选的静态字典管理模块,字典内容由具体应用动态或静态装入,这里只是初始化一些操作功能------------end------------------------------- (function(){ // 二级字典编辑器框架,用于编辑分为两个(或更多)层级的列表元素 // op包含的项目定义 // w:宽度,单位px,默认为不指定, // handw:头宽度,单位px,默认30 // fz:字体大小,默认为fz9 // clsel:项目盒的附加样式类类名,用于引入覆盖默认样式的定义。 // vsp :项目间的垂直间距,默认没有 // type : 要编辑的字典类目名,也可以是sdict中的本地数据,但此时不可进行编辑,只能显示 // rccallparam : 如果type是一个字典类目名,则这里指定从远程取字典数据的调用名和调用参数,默认是defaultrccallparam,调用远程的sk.dict.loaddict2data // selected : 被选中时的回调,如果返回false则选中失败,默认不可被选中,接受一个参数item包含被选中的dict2editoritem对象 // unselected : 被取消选中时的回调,无条件的取消,不可中止,接受一个参数item包含被取消选中的dict2editoritem对象 // dblclick : 双击时的回调函数,接受一个参数item包含被双击中的dict2editoritem对象 // createitemview : 结构项目的显示视图的方法,接受两个参数(con, item)即字典项目所在的元素,字典项目对象,默认方法是显示字典的v,t两个指标,这个可能没什么实用价值 // 所以一般都应从外部指定 // createsp0line : 一级类别分隔线创建函数,不指定则不画分隔线 // sidmask : 各层的sid创建倍率数组,以使sid的顺序在普通字典中也排列为树型,如果不指定这个指标,则不能在编辑器中创建新元素, // sidmask[0]中为创建顶级(一级)元素(layer=1)的倍率,这个可以理解为0级元素即编辑器创建子元素时用的倍率。倍率逐级减小 // 这个编辑器实际上只是一个框架,具体的界面和后台通讯由应用程序完成,这里只提供了一个生成新项目sid值的方法,以保证他们在字典维护模块中按sid排列时可以象一个树。 // 如果不要求在字典表中呈树型排列的话也可以用自定的方法来生成sid,即不指定sidmask(此时gensid方法不可用)。 // wc:显示树的基板div,一般是一个可以带滚动条的; type:字典的类型名或字典的本地数据结构。 function dict2editor(wc, type, op) { if (!op.fz) op.fz = 'fz9'; if (!op.clsel) op.clsel = ''; if (!op.handw) op.handw = 30; if (!op.selected) op.selected = rfalse; if (!op.unselected) op.unselected = rfalse; if (!op.dblclick) op.dblclick = sk.nop; if (!op.createitemview) op.createitemview = defaultcreateitemview; if (!op.rccallparam) op.rccallparam = defaultrccallparam; op.vspint = 0; if (op.vsp) { op.vspint = int(op.vsp); op.vsp += 'px'; } this.wc = wc; this.con = wc.div({css:{pa:'4px'}}); this.type = type; this.op = op; this.needadjustlist = []; // 需要进行尺寸协调的元素集 this.selected = null; // 选中的项目 this.child = []; // 顶层元素数组 this.layer = 0; // 本层层数 } function defaultrccallparam(v) { v.show = 'act'; return "sk.dict.loaddict2data"; } function rfalse() {return false;} function rtrue() {return true;} // dict2editor和dict2editoritem共用的一个内部函数,用于在本层元素(this)下建立新的子项目(下层新元素时指定适当的sid) // 字典的顶层(一级)元素是编辑器的子元素所以由编辑器建立,二级元素则由一级元素建立,以此类推。 function gensid() { var mask = this.op.sidmask; if (mask.length <= this.layer) throw new error('树型字典层数多于sidmask长度'); if (!this.child || this.child.length == 0) { // 本层无子元素,则新指定一个起始值 // 使用本层元素的sid,整除下层生成子元素的倍率r=sidmask[本层layer],加一后再乘以r.即(floor(上层sid/r)+1)*r。 // 如果本层为编辑器时,直接用sidmask[0]作为返回值即可。 if (this.layer == 0) { // 本层为编辑器,创建第一个顶层元素项,layer=0时 return mask[0]; } else { // 本层为顶层或更深,创建第一个二级以上元素项,layer>=1时 var r = mask[this.layer]; return (math.floor(int(this.data.sid) / r) + 1) * r; } } else { //已有子元素,则找到本层子元素的sid最大值max,用max整除本层生成子元素的倍率r=sidmul[layer],加一后再乘以r.即(floor(max/r)+1)*r var max = -1; var child = this.child; for (var i = 0;i < child.length; i++) { var sid = int(child[i].data.sid); if (sid > max) max = sid; } r = mask[this.layer]; return (math.floor(max / r) + 1) * r; } } // dict2editor的内部私有函数 function bulidview() { if (this.selected) { var sv = this.selected.data.v; this.selected.unselect(); } else sv = 0; this.needadjustlist = []; this.selected = null; // 选中的项目 this.child = []; if (!this.data.length) { this.con.html("目前还没有数据可编辑。"); return; } var con = this.con; var data = this.data; con.html(""); if (this.op.createsp0line) this.op.createsp0line.call(con, 0); this.needadjustlist = []; for (var i=0; i0) { var tab = con.tbody({cs:"0", cp:"0", w:op.w, css:{}}); var tr = tab.tr(); this.handtd = tr.td({w:op.handw, cls:"item piteml hand", attr:{onmouseover:handme, onmouseout:handmo, onclick:itemhandclick.bind(this)}}); var td1 = this.handel = this.handtd.div({cls:'am ' + op.fz, w:op.handw}).text("-"); var td2 = itemcon = tr.td({cls:"item pitemr " + op.fz}); this.child = []; if (op.w) op.w -= (op.handw + 1); for (var i=0; i=ch.length) order = ch.length - 1; var oi = this.index; if (order == oi) return; // 目标位置就是当前位置 var ida = []; var sda = []; var step = this.op.sidmask[this.parent.layer]; var s, e; if (order > oi) { step = -1 * step; s = oi + 1; e = order; } else { s = order; e = oi - 1; } for (var i = s; i <= e; i++) itemsidadd(ch[i], step); itemsidadd(this, int(ch[order].data.sid) - int(this.data.sid)); var edit = this.editor; var id = this.data.v; sk.rc.apost(this.moveproc?this.moveproc:"sk.dict.movedict2item", {ida:ida, sda:sda}, '调整显示顺序...', function(ret){ if (func) func(ret); else edit.load(function(){edit.scrolltoid(id, 2);}); }); // 生成将指定的元素及其所有子元素的sid值加d的作业值对 function itemsidadd(item, d) { ida.add(int(item.data.v)); sda.add(int(item.data.sid) + d); if (item.child) { for (var i = 0; i < item.child.length; i++) itemsidadd(item.child[i], d) } } }, // 通过自带的gui界面进行元素位置调整,本方法将调用moveto,func是调整成功后的回调函数,如不指定则默认动作是edit.load(func(滚动目标元素到屏幕中间)); movegui : function(ws, title, mh, mr, func) { var dlg = sk.dlg.dialog(ws, title); var lay = dlg.layout(); var cl = lay.line().h(36); if (mh) cl.span().html(mh) var od = cl.edit({w:30}).uint(2).keydown(function(key){if (key==13) run();}); if (mr) cl.span().html(mr) var self = this; lay.line("am").button("确定").click(run); od.focus(); dlg.center(); function run() { if (od.val().empty()) return; self.moveto(int(od.val())-1, func); dlg.close(); } }, scrolltome : function(mod) { if (mod == 1) var s = this.itemel.getoffsety(this.editor.wc) - 10 - this.itemel.h(); else if (mod == 2) s = this.itemel.getoffsety(this.editor.wc) - (this.editor.wc.h() - this.itemel.h())/2; else s = this.itemel.getoffsety(this.editor.wc) + this.itemel.h() + 10 - this.editor.wc.h(); this.editor.wc.scrolltop(s>0?s:0); }, show : function() {this.selfel.show(); this.adjust();}, hide : function() {this.selfel.hide();} }; dict2editor.prototype = { gensid:gensid, rebulidview : bulidview, // 装入数据并构建视图 //editor上有loadbefore, getdataafter, loadafter三个动作挂接点 //exit是一个临时的退出前附加动作,这个动作只在本次调用时运行一次,上面三个则是长期的,一旦设定一直有效。 load : function(exit) { // 记录未展开的项目,因为默认是全开,所以只需要记录那些收缩的就可以了 if (this.loadbefore) this.loadbefore(); var s = this.wc.scrolltop(); var unexp = []; this.each(function(itr) {if (!itr.expanded) unexp.add(itr.data.v);}); if (this.finda) { this.prevskey = null; this.finda.length = 0; this.findindex = 0; } if (sk.isarray(this.type)) { this.data = this.type; if (this.getdataafter) this.getdataafter(this.data); bulidview.call(this); unexp.each(function(id){ var e = this.find(id); if (e) e.expand(false); }.bind(this)); this.wc.scrolltop(s); if (this.loadafter) this.loadafter(); if (sk.isfunction(exit)) exit(); } else { if (!sk.isstring(this.type)) throw new error('dict2editor type 类型错误.'); var d = {type:this.type}; var rc = this.op.rccallparam.call(this, d); sk.rc.aget(rc, d, "正在装入字典数据...", function(ret){ if (this.rcafter) this.rcafter(ret); if (!ret.list) { this.data = []; } else { // 将返回的线性列表转化为树型结构 var list = ret.list; var da = []; var p = null; for (var i = 0; i < list.length; i++) { var ld = list[i]; if (ld.pc) ld.pc = ld.pc.json_parse(); if (ld.p==0) { da[da.length] = ld; } else { if (!p || p.v != ld.p) { // 父元素与上一个元素的不同则要进行查找 p = findbyid(list, ld.p); if (!p) throw "fail:[" + ld.v + ']id:' + ld.t + ',pid:' + ld.p + '. not find。'; if (!p.child) p.child = []; } p.child.add(ld); } } this.data = da; } if (this.getdataafter) this.getdataafter(this.data); bulidview.call(this); unexp.each(function(id){ var e = this.find(id); if (e) e.expand(false); }.bind(this)); this.wc.scrolltop(s); if (this.loadafter) this.loadafter(); if (sk.isfunction(exit)) exit(); }.bind(this)); } function findbyid(list, id) { for (var i = 0; i < list.length; i ++) { var d = list[i]; if (d.v == id) return d; // list是远程返回的线性表,只需线性扫描就可以了 /* else if (d.child) { var v = findbyid(d.child, id); if (v) return v; }  */ } return null; } }, // load() end-------------------- adjust : function() { this.needadjustlist.each(function(o){o.adjust();}); }, // 按keyname指定的key值,在编辑器中找到对应的项目对象,keyname默认为v, // 如果指定的keyname不是在这个字典类中唯一的则只返回第一个被找到的元素 // 如果输入的key是一个函数则按key(itr)函数返回true来进行判定 find : function(key, keyname) { if (!keyname) keyname = 'v'; var fn = (sk.isfunction(key)?key:function(itr){return itr.data[keyname]==key;}); function findbyid(list) { for (var i = 0; i < list.length; i ++) { var d = list[i]; if (fn(d)) return d; else if (d.child) { var v = findbyid(d.child); if (v) return v; } } return null; } return findbyid(this.child); }, expand : function(f) {this.each(function(itr){itr.expand(f);});}, // 树遍历每个数据元素 eachdata : function(func) { treeeach(this.data, func); }, // 树遍历每个元素对象 each : function(func) { treeeach(this.child, func); }, // 选中树界面上指定id的对象,并使窗口滑动到使这个对象可见的位置, // mod选择滚动后的垂直定位,默认在底部,1:顶部,2:中部,3或其他底部。 scrolltoid : function(id, mod) { var el = this.find(id); if (!el) return; el.select(); if (mod == 1) var s = el.itemel.getoffsety(this.wc) - 10 - el.itemel.h(); else if (mod == 2) s = el.itemel.getoffsety(this.wc) - (this.wc.h() - el.itemel.h())/2; else s = el.itemel.getoffsety(this.wc) + el.itemel.h() + 10 - this.wc.h(); this.wc.scrolltop(s>0?s:0); }, // 在树界面上进行搜索并定位元素,使窗口滑动到使元素可见位置 location : function( skey, // 搜索关键字,当skey是一个input对象时,则使用skey.val()作为关键值,同时在弹出的提示框中进行焦点接续。 // 当skey的值和上次调用时不同则重新搜索,相同则在上次的结果集中顺序跳转。 layer, // 指定在哪个层级的元素中进行匹配,如果为0或不指定则在所有元素中匹配 prev, // true表示在多个结果中逆向扫描(从下到上),默认认为正向(从上到下) matchfunc // 匹配方法,不指定则使用<默认匹配方法>进行匹配,默认算法为<元素>.data.t.match(skey或skey.val())返回true表示符合条件 // 函数通过matchfunc(树元素对象, skey)返回true来表示符合条件. ){ if (!this.finda) { this.prevskey = null; this.finda = []; this.findindex = 0; } var k; if (!matchfunc) matchfunc = defaultlocationmatch; if (sk.isobject(skey)) k = skey.val().trim(); else k = skey; if (k == '') return; if (k != this.prevskey) { this.finda.length = 0; var self = this; this.each(function(itr){ if (layer && itr.layer != layer) return; // 只在指定的层次中查找元素,不指定则全树查找 if (matchfunc(itr, k)) { self.finda.add(itr); } }); if (this.finda.length == 0) { sk.dlg.message("提示", "没有找到匹配的项目。", sk.isobject(skey)?skey:null); if (this.selected) this.selected.unselect(); this.prevskey = null; return; } this.findindex = prev?this.finda.length - 1:0; this.prevskey = k; } else { if (prev) { this.findindex --; if (this.findindex < 0) this.findindex = this.finda.length-1; } else this.findindex = (this.findindex + 1) % this.finda.length; } this.expand(true); var fi = this.finda[this.findindex]; fi.select(); var s = fi.itemel.getoffsety(this.wc) - this.wc.h()/2; this.wc.scrolltop(s>0?s:0); } }; //dict2edit.prototype end. function defaultlocationmatch(itr, kv) {return itr.data.t.match(kv);} function treeeach(list, func) { for (var i = 0; i < list.length; i ++) { var d = list[i]; func(d); if (d.child) { treeeach(d.child, func); } } } // 将这个编辑器引入到sk的tree分类中 sk.tree = { editor : function(con, type, op) {return new dict2editor(con, type, op);} }; })(); // 二级字典编辑器框架,------------------------------------------------------end----------------------------------------------- (function(){ // 最后 // 注册一些常用的属性简写,应用程序可以继续注册以在后继程序中使用简写来访问dom属性 // 但这些简写只能在sk.dom.elagent.el、sk.dom.elagent.setattr、sk.dom.elagent.setstyle中使用,当直接访问dom对象时,这些简写实际是不存在的 sk.dom.regattrname('backgroundcolor', 'bgc'); sk.dom.regattrname('fontsize' , 'fs'); sk.dom.regattrname('fontfamily' , 'ff'); sk.dom.regattrname('width' , 'w'); sk.dom.regattrname('height' , 'h'); sk.dom.regattrname('top' , 'y'); sk.dom.regattrname('left' , 'x'); sk.dom.regattrname('lineheight' , 'lh'); sk.dom.regattrname('classname' , 'cls'); sk.dom.regattrname('classname' , 'csn'); sk.dom.regattrname('htmlfor' , 'for'); sk.dom.regattrname('textalign' , 'ta'); sk.dom.regattrname('padding' , 'pa'); sk.dom.regattrname('paddingtop' , 'pat'); sk.dom.regattrname('paddingbottom' , 'pab'); sk.dom.regattrname('paddingleft' , 'pal'); sk.dom.regattrname('paddingright' , 'par'); sk.dom.regattrname('margin' , 'ma'); sk.dom.regattrname('margintop' , 'mat'); sk.dom.regattrname('marginbottom' , 'mab'); sk.dom.regattrname('marginleft' , 'mal'); sk.dom.regattrname('marginright' , 'mar'); sk.dom.regattrname('innerhtml' , 'html'); // 增加一组创建常用dom元素的快捷方式 sk.dom.addmethod("text", function(t) {return this.settext(t);}); sk.dom.addmethod("html", function(t) {return this.sethtml(t);}); sk.dom.addmethod("div", function(op) {return this.el('div', op);}); sk.dom.addmethod("tr", function(op) {return this.el('tr', op);}); sk.dom.addmethod("td", function(op) {return this.el('td', op);}); sk.dom.addmethod("span", function(op) {return this.el('span', op);}); sk.dom.addmethod("p" , function(op) {return this.el('p' , op);}); sk.dom.addmethod("a", function(op) {return this.el('a', op);}); sk.dom.addmethod("b", function(op) {return this.el('b', op);}); sk.dom.addmethod("form", function(op) {return this.el('form', op);}); sk.dom.addmethod("img", function(op) {return this.el('img', op);}); // 从sk.dlg中引入layout,加到所有element上 sk.dom.addmethod("layout", function (csv, lpa, ba) { if (!this.m_layout) this.m_layout = new sk.dlg.layout(this, csv, lpa, ba); return this.m_layout; }); // 一组快捷样式操作函数 sk.dom.addmethod("display", function(f) { var fg = f?'':'none'; if (this.labelel) this.labelel.setstyle("display", fg); this.setstyle("display", fg); return this; }); sk.dom.addmethod("hide", function() { if (this.labelel) this.labelel.setstyle("display", "none"); this.setstyle("display", "none"); return this; }); sk.dom.addmethod("show", function() { if (this.labelel) this.labelel.setstyle("display", ""); this.setstyle("display", ""); return this; }); sk.dom.addmethod("visible", function(f) { if (this.labelel) this.labelel.setvisible(f); this.setvisible(f); return this; }); sk.dom.addmethod("cls", function(cls, arg) { if (arguments.length == 0) return this.getclass(cls); else if (arguments.length == 1) return this.setclass(cls); else { if (arg == "+") return this.addclass(cls); else if (arg == "-") return this.removeclass(cls); else return this.replaceclass(cls, arg); } }); // 当只输入一个参数时,当参数是字符串时,返回指定的属性值,如果是对象{"属性名1":"属性值1","属性名2":"属性值2",....}则设置一系列值 // 当输入两个参数时,用后一个参数设置前一个参数指定的属性名 sk.dom.addmethod("attr", function(attrname, value){ if (arguments.length == 1) { if (sk.isobject(attrname)) { for (var p in attrname) { this.setattr(p, attrname[p]); } return this; } else { return this.getattr(attrname); } } else return this.setattr(attrname, value); }); // 当只输入一个参数时,当参数是字符串时,返回指定的属性值,如果是对象{"属性名1":"属性值1","属性名2":"属性值2",....}则设置一系列值 // 当输入两个参数时,用后一个参数设置前一个参数指定的属性名 sk.dom.addmethod("css", function(stylename, value){ if (arguments.length == 1) { if (sk.isobject(stylename)) { for (var p in stylename) { if (typeof stylename[p] === 'function') continue; this.setstyle(p, stylename[p]); } return this; } else { return this.getstyle(stylename); } } else return this.setstyle(stylename, value); }); // 快捷控制创建 sk.dom.addmethod("button", function(title, op, notab) {if (!op) op={value:title}; else op.value=title;return this.input("button", op, notab);}); sk.dom.addmethod("checkbox", function(title, beforelabelflag){return this.input("checkbox", {lab:title, labelafter:!beforelabelflag});}); sk.dom.addmethod("radio", function(title, name){return this.input("radio", {lab:title, attr:{name:name}, labelafter:true});}); sk.dom.addmethod("textarea", function(op){ var el = this.el("textarea",op); el.empty = function() {return this.em.value.trim().length == 0;}; return el; }); sk.dom.addmethod("edit", function(op){return this.input("text", op);}); // span和text的组合,用于快速创建字符串。 sk.dom.addmethod("t", function(str, op) {return this.el("span", op).settext(str);}); // 创建弹出菜单 菜单文字,宽度,菜单柄abutton配置, 创建菜单的回调函数 sk.dom.addmethod("menu", function(text, w, op, createmenufunc){ var bt = this.abutton(text, sk.nop, op); bt.click(function(){ var x = this.getleft(); var y = this.gettop() + this.getheight() + 1; if (this.menupoped) return; var box = sk.dlg.popbox(x, y, w); this.addclass('menupoped'); this.menupoped = true; box.tomenu(function(){ this.removeclass('menupoped'); this.menupoped = false; }.bind(this)); createmenufunc.call(box); box.adjustpos(op&&op.op); }.bind(bt)); return bt; }); // 工具包全局变量初始化 sk.browser = { 'isie' : (navigator.useragent.indexof('msie') >= 0) && (navigator.useragent.indexof('opera') < 0), 'isfirefox' : navigator.useragent.indexof('firefox') >= 0, 'isopera' : navigator.useragent.indexof('opera') >= 0, 'issafari' : navigator.useragent.indexof('safari') >= 0, 'angent' : navigator.useragent, ieversion : 1000 }; if (sk.browser.isie) { // 如果是ie则进一步取版本号,因为ie各版本都有各种坑爹级bug. sk.browser.ieversion = navigator.useragent.substr(navigator.useragent.indexof('msie')+5,3); } sk.textnodename = 'innertext'; sk._browser = ''; if (sk.browser.isie) sk._browser = 'ie'; else if (sk.browser.isfirefox) { sk._browser = 'ff'; sk.textnodename = 'textcontent'; } else if (sk.browser.isopera) sk._browser = 'op'; else if (sk.browser.issafari) sk._browser = 'sa'; else sk._browser = 'na'; // 定义sk.dom.getel(getelementbyid返回元素的包裹对象)的简写$ if (!window.$) window.$ = function(id) {return sk.dom.getel(id);}; window.byid = function(id) {return sk.dom.getel(id);}; })();