1 /** 2 * 3 * utils方法 4 * @fileOverView core/utils 5 * @author <a href="mailto:zhang.gd@foxmail.com">Zhang Guangda</a> 6 * @date 2012-10-25 7 */ 8 define("core/utils", function() { 9 /** 10 * @class we utils方法 11 */ 12 $we.utils = { 13 14 /** 15 * 初始化命名空间 16 * @param {String} router 命名空间的名称 17 * @param {Object} root 命名空间的基准,默认是window 18 */ 19 initNameSpace: function(router, root) { 20 if(!router || router == '') { 21 return; 22 } 23 var p = root || window, 24 arrNS = router.split('.'); 25 for(var i = 0, len = arrNS.length; i < len; i++) { 26 if(!p[arrNS[i]]) { 27 p[arrNS[i]] = {}; 28 } 29 p = p[arrNS[i]]; 30 } 31 }, 32 33 /** 34 * ajax请求统一封装 35 * @param {string} url URL 36 * @param {object} data 数据 37 * @param {function} success 成功的回调 38 * @param {function} fail 失败的回调 39 * @param {string} method POST/GET 40 * @param {Boolean} isJsonp 是否是jsonp 41 * @return {object} jxhr 42 */ 43 request: function(url, data, success, fail, method, isJsonp) { 44 var loginTryMaxTimes = 1; 45 loginTryTimes = 0, // 初始化登录尝试次数 46 option = { 47 url: url, 48 headers: { 49 "X-Requested-With": "XMLHttpRequest" // 标识该请求为ajax请求 50 }, 51 data: data, 52 success: function(resp) { 53 var obj; 54 if(typeof resp == "object") { 55 // 如果jQuery能够正常解析,那么直接赋值 56 obj = resp; 57 } else { 58 // 如果jQuery不能够正常解析,那么eval 一下 59 try { 60 obj = eval("(" + resp + ")"); 61 } catch(e) { 62 alert($we.ERROR.AJAX_PARSE_FAIL); 63 } 64 } 65 66 // 判断返回结构是否合法 67 if(obj && typeof obj.errno != 'undefined' && typeof obj.msg != "undefined") { 68 // error no 为0,则说明请求是成功的 69 if(obj.errno == 0) { 70 success(obj); 71 } else { 72 // 如果返回的错误码是未登录 73 if(parseInt(obj.errno) == $we.ERRNO.NOT_LOGIN) { 74 // 在登录尝试达到最大次数之前,尝试去登录 75 if (++loginTryTimes <= loginTryMaxTimes) { 76 $we.setLogin(true, function() { 77 $.ajax(option); 78 }, function() { 79 fail(obj); 80 }); 81 } else { 82 // 超过登录尝试次数之后,触发失败 83 fail(obj); 84 } 85 86 return; 87 } 88 // 错误码小于0,则为业务错误 89 if(parseInt(obj.errno) < 0) { 90 fail(obj); 91 } else { 92 // 否则,为系统错误 93 fail({ 94 errno: obj.errno, 95 msg: '系统内部错误,请稍后再试!Error: '+obj.errno 96 }); 97 } 98 } 99 } 100 }, 101 error: function(resp) { 102 // 请求失败,返回系统错误 103 fail({ 104 errno: 502, 105 msg: '网络超时,请重试!' 106 }); 107 }, 108 type: method 109 }; 110 111 if ($we.conf.RUNTIME.__NOJSON) { 112 isJsonp = false; 113 option.type = "POST"; 114 } 115 116 // 如果是jsonp 117 if(isJsonp) { 118 option.dataType = "jsonp"; 119 option.jsonp = "_jsonp"; 120 option.type = "GET"; 121 } 122 123 // 如果存在流程,那么判断流程里的一些属性 124 if($we && $we.process) { 125 // 获取当前流程的id,和flow 126 var p_id = $we.process.getData("id"), 127 p_flow = $we.process.getData("flow"); 128 // 如果存在流程id,那么请求参数里面加入流程id 129 if(p_id) { 130 option.data["we_process_id"] = p_id; 131 option.data["_src"] = window.location.hostname; 132 } 133 // 如果存在流程名称,那么请求参数里面假如流程名称 134 if(p_flow) option.data["_flow"] = p_flow; 135 } 136 137 return $.ajax(option); 138 }, 139 140 /** 141 * script loader 142 * @param {mixed} file 需要加载的文件,string或者array 143 * @param {string} path 路径 144 * @return {function} 回调函数 145 */ 146 include: function(file, path, callback) { 147 var head = document.getElementsByTagName("head")[0] || document.documentElement, 148 path = path || "", 149 files = typeof file == "string" ? [file] : file, // 统一转成array 150 done = 0, // 已经加载完的数量 151 len = files.length; // 总共需要加载的文件数量 152 153 $(files).each(function(index) { 154 var name = this.toString().replace(/^\s|\s$/g, ""), // 去除前后空格 155 att = name.split('.'), 156 ext = att[att.length - 1].toLowerCase(), 157 isCSS = ext == "css", 158 tagName = isCSS ? "link" : "script", 159 tag = document.createElement(tagName); // 创建link 或者 script 160 161 if(isCSS) { 162 tag.href = path + name; 163 tag.rel = "stylesheet"; 164 tag.type = "text/css"; 165 } else { 166 tag.type = "text/javascript"; 167 tag.src = path + name; 168 } 169 170 // 如果不是css且存在callback,那么需要处理一下回调函数的问题 171 if(!isCSS && typeof callback == "function") { 172 // 处理每个script load完之后的事件 173 var _handleCb = function() { 174 // 增加一个完成数,如果全部都完成,处理回调 175 if(++done == len) setTimeout(callback, 1); 176 // 删除当前的script 177 if(head && tag.parentNode) { 178 head.removeChild(tag); 179 } 180 }; 181 182 if(tag.readyState) { // IE 183 tag.onreadystatechange = function() { 184 if(tag.readyState == "loaded" || tag.readyState == "complete") { 185 _handleCb(); 186 tag.onreadystatechange = null; // memory leak 187 } 188 }; 189 } else { //Others 190 tag.onload = _handleCb; 191 } 192 } 193 194 // 这句话一定一定要放在最后,否则在IE下会有各种诡异问题 195 head.appendChild(tag); 196 }); 197 }, 198 199 /** 200 * 让浏览器执行脚本 201 * @param {string} text 需要执行的脚本代码 202 * @param {bool} bTrans 是否需要转译 < > 特殊符号 203 */ 204 exec: function(text, bTrans) { 205 if(!text) return text; 206 if(bTrans) { 207 text = text.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&"); 208 } 209 210 if(window.execScript) { 211 window.execScript(text); 212 } else { 213 var script = document.createElement('script'); 214 script.setAttribute('type', 'text/javascript'); 215 script.text = text; 216 document.head.appendChild(script); 217 document.head.removeChild(script); 218 } 219 return text; 220 }, 221 222 /** 223 * 根据值是否undefined来设置默认值 224 * @param {mixed} v 要检测的值 225 * @param {mixed} d 默认值 226 */ 227 setValue: function(v, d) { 228 if(typeof v == "undefined") return d; 229 else return v; 230 }, 231 232 /** 233 * 增加一个stylesheet 234 * @param {string} css css的具体text 235 * @param {dom} doc document 236 */ 237 addStyleSheet: function(css, doc) { 238 doc = doc || document; 239 head = document.getElementsByTagName('head')[0], style = document.createElement('style'); 240 241 style.type = 'text/css'; 242 if(style.styleSheet) { 243 style.styleSheet.cssText = css; 244 } else { 245 style.appendChild(document.createTextNode(css)); 246 } 247 head.appendChild(style); 248 }, 249 250 /** 251 * 获取表单元素 252 * @param ele 表单容器 253 * @private 254 */ 255 getFormElements: function (ele) 256 { 257 var FORM_Tag = ['INPUT', 'SELECT', 'TEXTAREA']; 258 /** 259 * 是否是表单Tag 260 * @param tagName 261 * @private 262 */ 263 var _isFormTag = function (tagName) 264 { 265 var formTag = false; 266 $.each(FORM_Tag, function (i, t) 267 { 268 if (t == tagName) { 269 formTag = true; 270 } 271 }); 272 return formTag; 273 }; 274 var elements = []; 275 var isFormTag = _isFormTag(ele[0].tagName); 276 277 if (isFormTag) { 278 elements.push(ele); 279 } 280 else { 281 $.each(FORM_Tag, function (i, t) 282 { 283 var _t = ele.find(t); 284 if (_t && _t.length > 0) { 285 $.each(_t, function (i, e) 286 { 287 elements.push(e); 288 }) 289 } 290 }); 291 } 292 return elements; 293 }, 294 295 /** 296 * 验证表单 297 * @param ele 验证元素 298 */ 299 validForm:function (ele) 300 { 301 var v = true; 302 303 ele = $(ele); 304 305 /** 306 * 验证表单试 307 * @type {Object} 308 */ 309 var ValidExpression = { 310 "require":function (e, args) 311 { 312 var value = $.trim(e.val()); 313 if (value.length == 0) { 314 return {valid:false, error_msg:"不能为空!"}; 315 } 316 return {valid:true, error_msg:""}; 317 }, 318 319 "url":function (e, args) 320 { 321 var value = e.val(); 322 if (value.length > 0) { 323 if (!/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(value)) { 324 return {valid:false, error_msg:"输入的url格式不正确!"}; 325 } 326 } 327 return {valid:true, error_msg:""}; 328 }, 329 330 "email":function (e, args) 331 { 332 var value = e.val(); 333 if (value.length > 0) { 334 if (!/^(?:[a-z\d]+[_\-\+\.]?)*[a-z\d]+@(?:([a-z\d]+\-?)*[a-z\d]+\.)+([a-z]{2,})+$/i.test(value)) { 335 return {valid:false, error_msg:"输入的Email格式不正确!"}; 336 } 337 } 338 return {valid:true, error_msg:""}; 339 }, 340 341 "number":function (e, args) 342 { 343 var value = e.val(); 344 var ph = $(e).attr("PlaceHolder"); 345 if (ph && ph.length > 0 && value == ph) { 346 value = ""; 347 } 348 if (value.length > 0) { 349 if (!/(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/.test(value)) { 350 return {valid:false, error_msg:"必须输入数字!"}; 351 } 352 } 353 return {valid:true, error_msg:""}; 354 }, 355 356 "int":function (e, args) 357 { 358 var value = e.val(); 359 if (value.length > 0) { 360 if (!/(^-?\d\d*$)/.test(value)) { 361 return {valid:false, error_msg:"必须输入整数!"}; 362 } 363 } 364 return {valid:true, error_msg:""}; 365 }, 366 367 "float":function (e, args) 368 { 369 var value = e.val(); 370 if (value.length > 0) { 371 if (!/[\+-]*\d+\.?\d*/.test(value)) { 372 return {valid:false, error_msg:"必须输入小数!"}; 373 } 374 } 375 return {valid:true, error_msg:""}; 376 }, 377 378 "date":function (e, args) 379 { 380 //日期正则 hash 381 var regexp_date = { 382 d:{ 383 reg:/^(19[0-9]{2}|2[0-9]{3})-(0{0,1}[1-9]{1}|1[0-2]{1}){1}-(0{0,1}[1-9]|(1|2)[0-9]|3[0-1]){1}$/, //v-date-d 384 format:"2010-02-02" 385 } 386 // } 387 }; 388 389 var _reg = regexp_date[args[0]]; 390 var value = e.val(); 391 if (value.length > 0) { 392 if (!_reg.reg.test(value)) { 393 return {valid:false, error_msg:"必须输入合法的日期格式" + _reg.format + "!"}; 394 } 395 } 396 return {valid:true, error_msg:""}; 397 }, 398 399 "max":function (e, args) 400 { 401 var value = e.val(); 402 403 if (value.length > 0) { 404 if (!value || Number(value) > Number(args[0])) { 405 return {valid:false, error_msg:"不能为空且不超过最大值" + args[0] + "!"}; 406 } 407 } 408 return {valid:true, error_msg:""}; 409 }, 410 411 "min":function (e, args) 412 { 413 var value = e.val(); 414 if (value.length > 0) { 415 if (!value || Number(value) < Number(args[0])) { 416 return {valid:false, error_msg:"不能为空且不低于最小值" + args[0] + "!"}; 417 } 418 } 419 return {valid:true, error_msg:""}; 420 }, 421 422 "range":function (e, args) 423 { 424 var value = e.val(); 425 if (value.length > 0) { 426 if (!value || (Number(value) < Number(args[0])) || Number(value) > Number(args[1])) { 427 return {valid:false, error_msg:"不能为空且应在" + args[0] + "之间的" + args[1] + "值!"}; 428 } 429 } 430 return {valid:true, error_msg:""}; 431 }, 432 433 "phone":function (e, args) 434 { 435 /** 436 *手机号码 437 *中国移动134,135,136,137,138,139,150,151,157,158,159号码段 438 *中国联通的131,132,133,153,155,156号码段 439 *中国电信3G手机号码段188 440 *中国网通3G手机号码189号码段 441 *固定电话区号最小3位,最大4位 442 *固定电话号码段5位至8位不等 443 *有人或许不习惯写区号 444 *香港台湾澳门等地区号为0085x,因为香港手机和台湾号码为8位。故暂时不做单独考虑 445 */ 446 var reg_phone = new RegExp("(^1((3|5)[0-9]|8[8-9])[0-9]{8}$)|(^0[0-9]{2,3}-[0-9]{5,8}$)|(^[0-9]{5,8}$)"); 447 var value = e.val(); 448 if (value.length > 0) { 449 if (!reg_phone.test(value)) { 450 return {valid:false, error_msg:"请输入正确的电话号码!"}; 451 } 452 } 453 return {valid:true, error_msg:""}; 454 }, 455 456 "equal":function(e,args){ 457 var value = e.val(); 458 if (value.length > 0) { 459 var equalName = args[0]; 460 var container=$("div[containerid='"+e.attr('container')+"']"); 461 container = container || $(document.body); 462 var e2 = container.find('*').filter(function(){ 463 return $(this).attr('name')==equalName; 464 }); 465 e2=$(e2); 466 if(value!=e2.val()){ 467 return {valid:false, error_msg:e.attr('label')+"必须和"+e2.attr('label')+"一致"}; 468 } 469 } 470 return {valid:true, error_msg:""}; 471 }, 472 473 /** 474 * 身份证号 475 * @param e 476 * @param args 477 */ 478 "id_card":function(e,args){ 479 var card = e.val(); 480 if (card.length > 0) { 481 var errorMessage = "您输入的身份证号码不正确,请重新输入"; 482 var result= $we.string.validIdCard(card); 483 if(!result){ 484 return {valid:false, error_msg:errorMessage}; 485 } 486 } 487 return {valid:true, error_msg:""}; 488 }, 489 490 /** 491 * 自定义正则 492 * 493 * @param e 494 * @param args 495 */ 496 "custom":function(e,args){ 497 var value = e.val(); 498 if (value.length > 0) { 499 if (!args[0].test(value)) { 500 return {valid:false, error_msg:"格式不正确!"}; 501 } 502 } 503 return {valid:true, error_msg:""}; 504 } 505 }; 506 507 /** 508 * 显示Error 509 * 510 * @param eName 511 * @param message 512 */ 513 var showError = function(eName,message){ 514 $('.tip_' + eName).html('<p class="we_cell_error_tips"><i class="we_icon_error"></i>' + message + '</p>'); 515 }; 516 517 /** 518 * 显示成功信息 519 */ 520 var showSuccess = function(eName,message){ 521 $('.tip_' + eName).html('<p class="we_cell_suc_tips"><i class="we_icon_suc"></i>' + message + '</p>'); 522 }; 523 524 /** 525 * 显示警告信息 526 */ 527 var showInfo = function(eName,message){ 528 $('.tip_' + eName).html('<p class="we_cell_info_tips">' + message + '</p>'); 529 }; 530 531 /** 532 * 清楚Tip 533 * @param eName 534 */ 535 var clearTip = function(eName){ 536 $('.tip_' + eName).html(''); 537 }; 538 539 /** 540 * 验证表单组件 541 * @param e 542 * @private 543 */ 544 var _valid = function (e) 545 { 546 var eName = e.attr('name'); 547 var expression = e[0].expression || ''; 548 var require = e.attr('require') == 'true'; 549 550 var _vv = {valid:true, error_msg:"" ,error_notice_type:null}; 551 552 /** 553 * Build Result 554 * 555 * @param _result 556 * @private 557 */ 558 var _buildResult = function(_result){ 559 if (_result['valid']) { 560 var success = e.attr('success'); 561 if(success && success.length>0){ 562 showSuccess(eName,success); 563 }else{ 564 clearTip(eName); 565 } 566 e.removeClass("we_input_error"); 567 } 568 else { 569 if(_result['error_notice_type']=='info'){ 570 //TODO 为require所定制 571 showInfo(eName,"不能为空"); 572 e.removeClass("we_input_error"); 573 }else{ 574 var error = e.attr('error'); 575 if(!(error && error.length>0)){ 576 error = _result['error_msg']; 577 } 578 showError(eName,error); 579 e.addClass("we_input_error"); 580 } 581 v = _result['valid']; 582 } 583 }; 584 if(require){ 585 var _result = ValidExpression['require'](e); 586 if(!_result['valid'] && _vv['valid']){ 587 _vv = _result; 588 _vv['error_notice_type'] = 'info'; 589 } 590 } 591 592 if(typeof expression === "function"){ 593 var expressionResult = expression(e); 594 if(typeof expressionResult == 'string'){ 595 var _result = ValidExpression['custom'](e,[new RegExp(expressionResult)]); 596 if(!_result['valid'] && _vv['valid']){ 597 _vv = _result; 598 } 599 }else{ 600 var _result = expressionResult; 601 if(!_result['valid'] && _vv['valid']){ 602 _vv = _result; 603 } 604 } 605 }else{ 606 var _tmpList = expression.split(" "); 607 $.each(_tmpList, function (i, _parse) 608 { 609 _parse = _parse.split("-"); 610 var num = _parse.length; 611 var parseFunc = ValidExpression[_parse[0]]; 612 if (parseFunc) { 613 var args = []; 614 if (num > 1) { 615 for (var j = 1; j < num; j++) { 616 args.push(_parse[j]); 617 } 618 } 619 var _result = parseFunc(e, args); 620 if(!_result['valid'] && _vv['valid']){ 621 _vv = _result; 622 } 623 } 624 }); 625 } 626 _buildResult(_vv); 627 }; 628 629 var feList = $we.utils.getFormElements(ele); 630 if (feList && feList.length > 0) { 631 $.each(feList, function (i, e) 632 { 633 e = $(e); 634 _valid(e); 635 }); 636 } 637 return v; 638 } 639 }; 640 641 return $we.utils; 642 643 });