grid.common.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. /*jshint eqeqeq:false */
  2. /*global jQuery */
  3. (function($){
  4. /*
  5. * jqGrid common function
  6. * Tony Tomov tony@trirand.com
  7. * http://trirand.com/blog/
  8. * Dual licensed under the MIT and GPL licenses:
  9. * http://www.opensource.org/licenses/mit-license.php
  10. * http://www.gnu.org/licenses/gpl-2.0.html
  11. */
  12. "use strict";
  13. $.extend($.jgrid,{
  14. // Modal functions
  15. showModal : function(h) {
  16. h.w.show();
  17. },
  18. closeModal : function(h) {
  19. h.w.hide().attr("aria-hidden","true");
  20. if(h.o) {h.o.remove();}
  21. },
  22. hideModal : function (selector,o) {
  23. o = $.extend({jqm : true, gb :'', removemodal: false, formprop: false, form : ''}, o || {});
  24. var thisgrid = o.gb && typeof o.gb === "string" && o.gb.substr(0,6) === "#gbox_" ? $("#" + o.gb.substr(6))[0] : false;
  25. if(o.onClose) {
  26. var oncret = thisgrid ? o.onClose.call(thisgrid, selector) : o.onClose(selector);
  27. if (typeof oncret === 'boolean' && !oncret ) { return; }
  28. }
  29. if( o.formprop && thisgrid && o.form) {
  30. var fh = $(selector)[0].style.height;
  31. if(fh.indexOf("px") > -1 ) {
  32. fh = parseFloat(fh);
  33. }
  34. var frmgr, frmdata;
  35. if(o.form==='edit'){
  36. frmgr = '#' +$.jgrid.jqID("FrmGrid_"+ o.gb.substr(6));
  37. frmdata = "formProp";
  38. } else if( o.form === 'view') {
  39. frmgr = '#' +$.jgrid.jqID("ViewGrid_"+ o.gb.substr(6));
  40. frmdata = "viewProp";
  41. }
  42. $(thisgrid).data(frmdata, {
  43. top:parseFloat($(selector).css("top")),
  44. left : parseFloat($(selector).css("left")),
  45. width : $(selector).width(),
  46. height : fh,
  47. dataheight : $(frmgr).height(),
  48. datawidth: $(frmgr).width()
  49. });
  50. }
  51. if ($.fn.jqm && o.jqm === true) {
  52. $(selector).attr("aria-hidden","true").jqmHide();
  53. } else {
  54. if(o.gb !== '') {
  55. try {$(".jqgrid-overlay:first",o.gb).hide();} catch (e){}
  56. }
  57. $(selector).hide().attr("aria-hidden","true");
  58. }
  59. if( o.removemodal ) {
  60. $(selector).remove();
  61. }
  62. },
  63. //Helper functions
  64. findPos : function(obj) {
  65. var curleft = 0, curtop = 0;
  66. if (obj.offsetParent) {
  67. do {
  68. curleft += obj.offsetLeft;
  69. curtop += obj.offsetTop;
  70. } while (obj = obj.offsetParent);
  71. //do not change obj == obj.offsetParent
  72. }
  73. return [curleft,curtop];
  74. },
  75. createModal : function(aIDs, content, p, insertSelector, posSelector, appendsel, css) {
  76. p = $.extend(true, {}, $.jgrid.jqModal || {}, p);
  77. var mw = document.createElement('div'), rtlsup, self = this;
  78. css = $.extend({}, css || {});
  79. rtlsup = $(p.gbox).attr("dir") === "rtl" ? true : false;
  80. mw.className= "ui-widget ui-widget-content ui-corner-all ui-jqdialog";
  81. mw.id = aIDs.themodal;
  82. var mh = document.createElement('div');
  83. mh.className = "ui-jqdialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix";
  84. mh.id = aIDs.modalhead;
  85. $(mh).append("<span class='ui-jqdialog-title'>"+p.caption+"</span>");
  86. var ahr= $("<a class='ui-jqdialog-titlebar-close ui-corner-all'></a>")
  87. .hover(function(){ahr.addClass('ui-state-hover');},
  88. function(){ahr.removeClass('ui-state-hover');})
  89. .append("<span class='ui-icon ui-icon-closethick'></span>");
  90. $(mh).append(ahr);
  91. if(rtlsup) {
  92. mw.dir = "rtl";
  93. $(".ui-jqdialog-title",mh).css("float","right");
  94. $(".ui-jqdialog-titlebar-close",mh).css("left",0.3+"em");
  95. } else {
  96. mw.dir = "ltr";
  97. $(".ui-jqdialog-title",mh).css("float","left");
  98. $(".ui-jqdialog-titlebar-close",mh).css("right",0.3+"em");
  99. }
  100. var mc = document.createElement('div');
  101. $(mc).addClass("ui-jqdialog-content ui-widget-content").attr("id",aIDs.modalcontent);
  102. $(mc).append(content);
  103. mw.appendChild(mc);
  104. $(mw).prepend(mh);
  105. if(appendsel===true) { $('body').append(mw); } //append as first child in body -for alert dialog
  106. else if (typeof appendsel === "string") {
  107. $(appendsel).append(mw);
  108. } else {$(mw).insertBefore(insertSelector);}
  109. $(mw).css(css);
  110. if(p.jqModal === undefined) {p.jqModal = true;} // internal use
  111. var coord = {};
  112. if ( $.fn.jqm && p.jqModal === true) {
  113. if(p.left ===0 && p.top===0 && p.overlay) {
  114. var pos = [];
  115. pos = $.jgrid.findPos(posSelector);
  116. p.left = pos[0] + 4;
  117. p.top = pos[1] + 4;
  118. }
  119. coord.top = p.top+"px";
  120. coord.left = p.left;
  121. } else if(p.left !==0 || p.top!==0) {
  122. coord.left = p.left;
  123. coord.top = p.top+"px";
  124. }
  125. $("a.ui-jqdialog-titlebar-close",mh).click(function(){
  126. var oncm = $("#"+$.jgrid.jqID(aIDs.themodal)).data("onClose") || p.onClose;
  127. var gboxclose = $("#"+$.jgrid.jqID(aIDs.themodal)).data("gbox") || p.gbox;
  128. self.hideModal("#"+$.jgrid.jqID(aIDs.themodal),{gb:gboxclose,jqm:p.jqModal,onClose:oncm, removemodal: p.removemodal || false, formprop : !p.recreateForm || false, form: p.form || ''});
  129. return false;
  130. });
  131. if (p.width === 0 || !p.width) {p.width = 300;}
  132. if(p.height === 0 || !p.height) {p.height =200;}
  133. if(!p.zIndex) {
  134. var parentZ = $(insertSelector).parents("*[role=dialog]").filter(':first').css("z-index");
  135. if(parentZ) {
  136. p.zIndex = parseInt(parentZ,10)+2;
  137. } else {
  138. p.zIndex = 950;
  139. }
  140. }
  141. var rtlt = 0;
  142. if( rtlsup && coord.left && !appendsel) {
  143. rtlt = $(p.gbox).width()- (!isNaN(p.width) ? parseInt(p.width,10) :0) - 8; // to do
  144. // just in case
  145. coord.left = parseInt(coord.left,10) + parseInt(rtlt,10);
  146. }
  147. if(coord.left) { coord.left += "px"; }
  148. $(mw).css($.extend({
  149. width: isNaN(p.width) ? "auto": p.width+"px",
  150. height:isNaN(p.height) ? "auto" : p.height + "px",
  151. zIndex:p.zIndex,
  152. overflow: 'hidden'
  153. },coord))
  154. .attr({tabIndex: "-1","role":"dialog","aria-labelledby":aIDs.modalhead,"aria-hidden":"true"});
  155. if(p.drag === undefined) { p.drag=true;}
  156. if(p.resize === undefined) {p.resize=true;}
  157. if (p.drag) {
  158. $(mh).css('cursor','move');
  159. if($.fn.jqDrag) {
  160. $(mw).jqDrag(mh);
  161. } else {
  162. try {
  163. $(mw).draggable({handle: $("#"+$.jgrid.jqID(mh.id))});
  164. } catch (e) {}
  165. }
  166. }
  167. if(p.resize) {
  168. if($.fn.jqResize) {
  169. $(mw).append("<div class='jqResize ui-resizable-handle ui-resizable-se ui-icon ui-icon-gripsmall-diagonal-se'></div>");
  170. $("#"+$.jgrid.jqID(aIDs.themodal)).jqResize(".jqResize",aIDs.scrollelm ? "#"+$.jgrid.jqID(aIDs.scrollelm) : false);
  171. } else {
  172. try {
  173. $(mw).resizable({handles: 'se, sw',alsoResize: aIDs.scrollelm ? "#"+$.jgrid.jqID(aIDs.scrollelm) : false});
  174. } catch (r) {}
  175. }
  176. }
  177. if(p.closeOnEscape === true){
  178. $(mw).keydown( function( e ) {
  179. if( e.which === 27 ) {
  180. var cone = $("#"+$.jgrid.jqID(aIDs.themodal)).data("onClose") || p.onClose;
  181. self.hideModal("#"+$.jgrid.jqID(aIDs.themodal),{gb:p.gbox,jqm:p.jqModal,onClose: cone, removemodal: p.removemodal || false, formprop : !p.recreateForm || false, form: p.form || ''});
  182. }
  183. });
  184. }
  185. },
  186. viewModal : function (selector,o){
  187. o = $.extend({
  188. toTop: true,
  189. overlay: 10,
  190. modal: false,
  191. overlayClass : 'ui-widget-overlay',
  192. onShow: $.jgrid.showModal,
  193. onHide: $.jgrid.closeModal,
  194. gbox: '',
  195. jqm : true,
  196. jqM : true
  197. }, o || {});
  198. if ($.fn.jqm && o.jqm === true) {
  199. if(o.jqM) { $(selector).attr("aria-hidden","false").jqm(o).jqmShow(); }
  200. else {$(selector).attr("aria-hidden","false").jqmShow();}
  201. } else {
  202. if(o.gbox !== '') {
  203. $(".jqgrid-overlay:first",o.gbox).show();
  204. $(selector).data("gbox",o.gbox);
  205. }
  206. $(selector).show().attr("aria-hidden","false");
  207. try{$(':input:visible',selector)[0].focus();}catch(_){}
  208. }
  209. },
  210. info_dialog : function(caption, content,c_b, modalopt) {
  211. var mopt = {
  212. width:290,
  213. height:'auto',
  214. dataheight: 'auto',
  215. drag: true,
  216. resize: false,
  217. left:250,
  218. top:170,
  219. zIndex : 1000,
  220. jqModal : true,
  221. modal : false,
  222. closeOnEscape : true,
  223. align: 'center',
  224. buttonalign : 'center',
  225. buttons : []
  226. // {text:'textbutt', id:"buttid", onClick : function(){...}}
  227. // if the id is not provided we set it like info_button_+ the index in the array - i.e info_button_0,info_button_1...
  228. };
  229. $.extend(true, mopt, $.jgrid.jqModal || {}, {caption:"<b>"+caption+"</b>"}, modalopt || {});
  230. var jm = mopt.jqModal, self = this;
  231. if($.fn.jqm && !jm) { jm = false; }
  232. // in case there is no jqModal
  233. var buttstr ="", i;
  234. if(mopt.buttons.length > 0) {
  235. for(i=0;i<mopt.buttons.length;i++) {
  236. if(mopt.buttons[i].id === undefined) { mopt.buttons[i].id = "info_button_"+i; }
  237. buttstr += "<a id='"+mopt.buttons[i].id+"' class='fm-button ui-state-default ui-corner-all'>"+mopt.buttons[i].text+"</a>";
  238. }
  239. }
  240. var dh = isNaN(mopt.dataheight) ? mopt.dataheight : mopt.dataheight+"px",
  241. cn = "text-align:"+mopt.align+";";
  242. var cnt = "<div id='info_id'>";
  243. cnt += "<div id='infocnt' style='margin:0px;padding-bottom:1em;width:100%;overflow:auto;position:relative;height:"+dh+";"+cn+"'>"+content+"</div>";
  244. cnt += c_b ? "<div class='ui-widget-content ui-helper-clearfix' style='text-align:"+mopt.buttonalign+";padding-bottom:0.8em;padding-top:0.5em;background-image: none;border-width: 1px 0 0 0;'><a id='closedialog' class='fm-button ui-state-default ui-corner-all'>"+c_b+"</a>"+buttstr+"</div>" :
  245. buttstr !== "" ? "<div class='ui-widget-content ui-helper-clearfix' style='text-align:"+mopt.buttonalign+";padding-bottom:0.8em;padding-top:0.5em;background-image: none;border-width: 1px 0 0 0;'>"+buttstr+"</div>" : "";
  246. cnt += "</div>";
  247. try {
  248. if($("#info_dialog").attr("aria-hidden") === "false") {
  249. $.jgrid.hideModal("#info_dialog",{jqm:jm});
  250. }
  251. $("#info_dialog").remove();
  252. } catch (e){}
  253. $.jgrid.createModal({
  254. themodal:'info_dialog',
  255. modalhead:'info_head',
  256. modalcontent:'info_content',
  257. scrollelm: 'infocnt'},
  258. cnt,
  259. mopt,
  260. '','',true
  261. );
  262. // attach onclick after inserting into the dom
  263. if(buttstr) {
  264. $.each(mopt.buttons,function(i){
  265. $("#"+$.jgrid.jqID(this.id),"#info_id").bind('click',function(){mopt.buttons[i].onClick.call($("#info_dialog")); return false;});
  266. });
  267. }
  268. $("#closedialog", "#info_id").click(function(){
  269. self.hideModal("#info_dialog",{
  270. jqm:jm,
  271. onClose: $("#info_dialog").data("onClose") || mopt.onClose,
  272. gb: $("#info_dialog").data("gbox") || mopt.gbox
  273. });
  274. return false;
  275. });
  276. $(".fm-button","#info_dialog").hover(
  277. function(){$(this).addClass('ui-state-hover');},
  278. function(){$(this).removeClass('ui-state-hover');}
  279. );
  280. if($.isFunction(mopt.beforeOpen) ) { mopt.beforeOpen(); }
  281. $.jgrid.viewModal("#info_dialog",{
  282. onHide: function(h) {
  283. h.w.hide().remove();
  284. if(h.o) { h.o.remove(); }
  285. },
  286. modal :mopt.modal,
  287. jqm:jm
  288. });
  289. if($.isFunction(mopt.afterOpen) ) { mopt.afterOpen(); }
  290. try{ $("#info_dialog").focus();} catch (m){}
  291. },
  292. bindEv: function (el, opt) {
  293. var $t = this;
  294. if($.isFunction(opt.dataInit)) {
  295. opt.dataInit.call($t,el,opt);
  296. }
  297. if(opt.dataEvents) {
  298. $.each(opt.dataEvents, function() {
  299. if (this.data !== undefined) {
  300. $(el).bind(this.type, this.data, this.fn);
  301. } else {
  302. $(el).bind(this.type, this.fn);
  303. }
  304. });
  305. }
  306. },
  307. // Form Functions
  308. createEl : function(eltype,options,vl,autowidth, ajaxso) {
  309. var elem = "", $t = this;
  310. function setAttributes(elm, atr, exl ) {
  311. var exclude = ['dataInit','dataEvents','dataUrl', 'buildSelect','sopt', 'searchhidden', 'defaultValue', 'attr', 'custom_element', 'custom_value'];
  312. if(exl !== undefined && $.isArray(exl)) {
  313. $.merge(exclude, exl);
  314. }
  315. $.each(atr, function(key, value){
  316. if($.inArray(key, exclude) === -1) {
  317. $(elm).attr(key,value);
  318. }
  319. });
  320. if(!atr.hasOwnProperty('id')) {
  321. $(elm).attr('id', $.jgrid.randId());
  322. }
  323. }
  324. switch (eltype)
  325. {
  326. case "textarea" :
  327. elem = document.createElement("textarea");
  328. if(autowidth) {
  329. if(!options.cols) { $(elem).css({width:"98%"});}
  330. } else if (!options.cols) { options.cols = 20; }
  331. if(!options.rows) { options.rows = 2; }
  332. if(vl==='&nbsp;' || vl==='&#160;' || (vl.length===1 && vl.charCodeAt(0)===160)) {vl="";}
  333. elem.value = vl;
  334. setAttributes(elem, options);
  335. $(elem).attr({"role":"textbox","multiline":"true"});
  336. break;
  337. case "checkbox" : //what code for simple checkbox
  338. elem = document.createElement("input");
  339. elem.type = "checkbox";
  340. if( !options.value ) {
  341. var vl1 = (vl+"").toLowerCase();
  342. if(vl1.search(/(false|f|0|no|n|off|undefined)/i)<0 && vl1!=="") {
  343. elem.checked=true;
  344. elem.defaultChecked=true;
  345. elem.value = vl;
  346. } else {
  347. elem.value = "on";
  348. }
  349. $(elem).attr("offval","off");
  350. } else {
  351. var cbval = options.value.split(":");
  352. if(vl === cbval[0]) {
  353. elem.checked=true;
  354. elem.defaultChecked=true;
  355. }
  356. elem.value = cbval[0];
  357. $(elem).attr("offval",cbval[1]);
  358. }
  359. setAttributes(elem, options, ['value']);
  360. $(elem).attr("role","checkbox");
  361. break;
  362. case "select" :
  363. elem = document.createElement("select");
  364. elem.setAttribute("role","select");
  365. var msl, ovm = [];
  366. if(options.multiple===true) {
  367. msl = true;
  368. elem.multiple="multiple";
  369. $(elem).attr("aria-multiselectable","true");
  370. } else { msl = false; }
  371. if(options.dataUrl !== undefined) {
  372. var rowid = null, postData = options.postData || ajaxso.postData;
  373. try {
  374. rowid = options.rowId;
  375. } catch(e) {}
  376. if ($t.p && $t.p.idPrefix) {
  377. rowid = $.jgrid.stripPref($t.p.idPrefix, rowid);
  378. }
  379. $.ajax($.extend({
  380. url: $.isFunction(options.dataUrl) ? options.dataUrl.call($t, rowid, vl, String(options.name)) : options.dataUrl,
  381. type : "GET",
  382. dataType: "html",
  383. data: $.isFunction(postData) ? postData.call($t, rowid, vl, String(options.name)) : postData,
  384. context: {elem:elem, options:options, vl:vl},
  385. success: function(data){
  386. var ovm = [], elem = this.elem, vl = this.vl,
  387. options = $.extend({},this.options),
  388. msl = options.multiple===true,
  389. a = $.isFunction(options.buildSelect) ? options.buildSelect.call($t,data) : data;
  390. if(typeof a === 'string') {
  391. a = $( $.trim( a ) ).html();
  392. }
  393. if(a) {
  394. $(elem).append(a);
  395. setAttributes(elem, options, postData ? ['postData'] : undefined );
  396. if(options.size === undefined) { options.size = msl ? 3 : 1;}
  397. if(msl) {
  398. ovm = vl.split(",");
  399. ovm = $.map(ovm,function(n){return $.trim(n);});
  400. } else {
  401. ovm[0] = $.trim(vl);
  402. }
  403. //$(elem).attr(options);
  404. setTimeout(function(){
  405. $("option",elem).each(function(i){
  406. //if(i===0) { this.selected = ""; }
  407. // fix IE8/IE7 problem with selecting of the first item on multiple=true
  408. if (i === 0 && elem.multiple) { this.selected = false; }
  409. $(this).attr("role","option");
  410. if($.inArray($.trim($(this).text()),ovm) > -1 || $.inArray($.trim($(this).val()),ovm) > -1 ) {
  411. this.selected= "selected";
  412. }
  413. });
  414. },0);
  415. }
  416. }
  417. },ajaxso || {}));
  418. } else if(options.value) {
  419. var i;
  420. if(options.size === undefined) {
  421. options.size = msl ? 3 : 1;
  422. }
  423. if(msl) {
  424. ovm = vl.split(",");
  425. ovm = $.map(ovm,function(n){return $.trim(n);});
  426. }
  427. if(typeof options.value === 'function') { options.value = options.value(); }
  428. var so,sv, ov,
  429. sep = options.separator === undefined ? ":" : options.separator,
  430. delim = options.delimiter === undefined ? ";" : options.delimiter;
  431. if(typeof options.value === 'string') {
  432. so = options.value.split(delim);
  433. for(i=0; i<so.length;i++){
  434. sv = so[i].split(sep);
  435. if(sv.length > 2 ) {
  436. sv[1] = $.map(sv,function(n,ii){if(ii>0) { return n;} }).join(sep);
  437. }
  438. ov = document.createElement("option");
  439. ov.setAttribute("role","option");
  440. ov.value = sv[0]; ov.innerHTML = sv[1];
  441. elem.appendChild(ov);
  442. if (!msl && ($.trim(sv[0]) === $.trim(vl) || $.trim(sv[1]) === $.trim(vl))) { ov.selected ="selected"; }
  443. if (msl && ($.inArray($.trim(sv[1]), ovm)>-1 || $.inArray($.trim(sv[0]), ovm)>-1)) {ov.selected ="selected";}
  444. }
  445. } else if (typeof options.value === 'object') {
  446. var oSv = options.value, key;
  447. for (key in oSv) {
  448. if (oSv.hasOwnProperty(key ) ){
  449. ov = document.createElement("option");
  450. ov.setAttribute("role","option");
  451. ov.value = key; ov.innerHTML = oSv[key];
  452. elem.appendChild(ov);
  453. if (!msl && ( $.trim(key) === $.trim(vl) || $.trim(oSv[key]) === $.trim(vl)) ) { ov.selected ="selected"; }
  454. if (msl && ($.inArray($.trim(oSv[key]),ovm)>-1 || $.inArray($.trim(key),ovm)>-1)) { ov.selected ="selected"; }
  455. }
  456. }
  457. }
  458. setAttributes(elem, options, ['value']);
  459. }
  460. break;
  461. case "text" :
  462. case "password" :
  463. case "button" :
  464. var role;
  465. if(eltype==="button") { role = "button"; }
  466. else { role = "textbox"; }
  467. elem = document.createElement("input");
  468. elem.type = eltype;
  469. elem.value = vl;
  470. setAttributes(elem, options);
  471. if(eltype !== "button"){
  472. if(autowidth) {
  473. if(!options.size) { $(elem).css({width:"98%"}); }
  474. } else if (!options.size) { options.size = 20; }
  475. }
  476. $(elem).attr("role",role);
  477. break;
  478. case "image" :
  479. case "file" :
  480. elem = document.createElement("input");
  481. elem.type = eltype;
  482. setAttributes(elem, options);
  483. break;
  484. case "custom" :
  485. elem = document.createElement("span");
  486. try {
  487. if($.isFunction(options.custom_element)) {
  488. var celm = options.custom_element.call($t,vl,options);
  489. if(celm) {
  490. celm = $(celm).addClass("customelement").attr({id:options.id,name:options.name});
  491. $(elem).empty().append(celm);
  492. } else {
  493. throw "e2";
  494. }
  495. } else {
  496. throw "e1";
  497. }
  498. } catch (e) {
  499. if (e==="e1") { $.jgrid.info_dialog($.jgrid.errors.errcap,"function 'custom_element' "+$.jgrid.edit.msg.nodefined, $.jgrid.edit.bClose);}
  500. if (e==="e2") { $.jgrid.info_dialog($.jgrid.errors.errcap,"function 'custom_element' "+$.jgrid.edit.msg.novalue,$.jgrid.edit.bClose);}
  501. else { $.jgrid.info_dialog($.jgrid.errors.errcap,typeof e==="string"?e:e.message,$.jgrid.edit.bClose); }
  502. }
  503. break;
  504. }
  505. return elem;
  506. },
  507. // Date Validation Javascript
  508. checkDate : function (format, date) {
  509. var daysInFebruary = function(year){
  510. // February has 29 days in any year evenly divisible by four,
  511. // EXCEPT for centurial years which are not also divisible by 400.
  512. return (((year % 4 === 0) && ( year % 100 !== 0 || (year % 400 === 0))) ? 29 : 28 );
  513. },
  514. tsp = {}, sep;
  515. format = format.toLowerCase();
  516. //we search for /,-,. for the date separator
  517. if(format.indexOf("/") !== -1) {
  518. sep = "/";
  519. } else if(format.indexOf("-") !== -1) {
  520. sep = "-";
  521. } else if(format.indexOf(".") !== -1) {
  522. sep = ".";
  523. } else {
  524. sep = "/";
  525. }
  526. format = format.split(sep);
  527. date = date.split(sep);
  528. if (date.length !== 3) { return false; }
  529. var j=-1,yln, dln=-1, mln=-1, i;
  530. for(i=0;i<format.length;i++){
  531. var dv = isNaN(date[i]) ? 0 : parseInt(date[i],10);
  532. tsp[format[i]] = dv;
  533. yln = format[i];
  534. if(yln.indexOf("y") !== -1) { j=i; }
  535. if(yln.indexOf("m") !== -1) { mln=i; }
  536. if(yln.indexOf("d") !== -1) { dln=i; }
  537. }
  538. if (format[j] === "y" || format[j] === "yyyy") {
  539. yln=4;
  540. } else if(format[j] ==="yy"){
  541. yln = 2;
  542. } else {
  543. yln = -1;
  544. }
  545. var daysInMonth = [0,31,29,31,30,31,30,31,31,30,31,30,31],
  546. strDate;
  547. if (j === -1) {
  548. return false;
  549. }
  550. strDate = tsp[format[j]].toString();
  551. if(yln === 2 && strDate.length === 1) {yln = 1;}
  552. if (strDate.length !== yln || (tsp[format[j]]===0 && date[j]!=="00")){
  553. return false;
  554. }
  555. if(mln === -1) {
  556. return false;
  557. }
  558. strDate = tsp[format[mln]].toString();
  559. if (strDate.length<1 || tsp[format[mln]]<1 || tsp[format[mln]]>12){
  560. return false;
  561. }
  562. if(dln === -1) {
  563. return false;
  564. }
  565. strDate = tsp[format[dln]].toString();
  566. if (strDate.length<1 || tsp[format[dln]]<1 || tsp[format[dln]]>31 || (tsp[format[mln]]===2 && tsp[format[dln]]>daysInFebruary(tsp[format[j]])) || tsp[format[dln]] > daysInMonth[tsp[format[mln]]]){
  567. return false;
  568. }
  569. return true;
  570. },
  571. isEmpty : function(val)
  572. {
  573. if (val.match(/^\s+$/) || val === "") {
  574. return true;
  575. }
  576. return false;
  577. },
  578. checkTime : function(time){
  579. // checks only hh:ss (and optional am/pm)
  580. var re = /^(\d{1,2}):(\d{2})([apAP][Mm])?$/,regs;
  581. if(!$.jgrid.isEmpty(time))
  582. {
  583. regs = time.match(re);
  584. if(regs) {
  585. if(regs[3]) {
  586. if(regs[1] < 1 || regs[1] > 12) { return false; }
  587. } else {
  588. if(regs[1] > 23) { return false; }
  589. }
  590. if(regs[2] > 59) {
  591. return false;
  592. }
  593. } else {
  594. return false;
  595. }
  596. }
  597. return true;
  598. },
  599. checkValues : function(val, valref, customobject, nam) {
  600. var edtrul,i, nm, dft, len, g = this, cm = g.p.colModel;
  601. if(customobject === undefined) {
  602. if(typeof valref==='string'){
  603. for( i =0, len=cm.length;i<len; i++){
  604. if(cm[i].name===valref) {
  605. edtrul = cm[i].editrules;
  606. valref = i;
  607. if(cm[i].formoptions != null) { nm = cm[i].formoptions.label; }
  608. break;
  609. }
  610. }
  611. } else if(valref >=0) {
  612. edtrul = cm[valref].editrules;
  613. }
  614. } else {
  615. edtrul = customobject;
  616. nm = nam===undefined ? "_" : nam;
  617. }
  618. if(edtrul) {
  619. if(!nm) { nm = g.p.colNames != null ? g.p.colNames[valref] : cm[valref].label; }
  620. if(edtrul.required === true) {
  621. if( $.jgrid.isEmpty(val) ) { return [false,nm+": "+$.jgrid.edit.msg.required,""]; }
  622. }
  623. // force required
  624. var rqfield = edtrul.required === false ? false : true;
  625. if(edtrul.number === true) {
  626. if( !(rqfield === false && $.jgrid.isEmpty(val)) ) {
  627. if(isNaN(val)) { return [false,nm+": "+$.jgrid.edit.msg.number,""]; }
  628. }
  629. }
  630. if(edtrul.minValue !== undefined && !isNaN(edtrul.minValue)) {
  631. if (parseFloat(val) < parseFloat(edtrul.minValue) ) { return [false,nm+": "+$.jgrid.edit.msg.minValue+" "+edtrul.minValue,""];}
  632. }
  633. if(edtrul.maxValue !== undefined && !isNaN(edtrul.maxValue)) {
  634. if (parseFloat(val) > parseFloat(edtrul.maxValue) ) { return [false,nm+": "+$.jgrid.edit.msg.maxValue+" "+edtrul.maxValue,""];}
  635. }
  636. var filter;
  637. if(edtrul.email === true) {
  638. if( !(rqfield === false && $.jgrid.isEmpty(val)) ) {
  639. // taken from $ Validate plugin
  640. filter = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i;
  641. if(!filter.test(val)) {return [false,nm+": "+$.jgrid.edit.msg.email,""];}
  642. }
  643. }
  644. if(edtrul.integer === true) {
  645. if( !(rqfield === false && $.jgrid.isEmpty(val)) ) {
  646. if(isNaN(val)) { return [false,nm+": "+$.jgrid.edit.msg.integer,""]; }
  647. if ((val % 1 !== 0) || (val.indexOf('.') !== -1)) { return [false,nm+": "+$.jgrid.edit.msg.integer,""];}
  648. }
  649. }
  650. if(edtrul.date === true) {
  651. if( !(rqfield === false && $.jgrid.isEmpty(val)) ) {
  652. if(cm[valref].formatoptions && cm[valref].formatoptions.newformat) {
  653. dft = cm[valref].formatoptions.newformat;
  654. if( $.jgrid.formatter.date.masks.hasOwnProperty(dft) ) {
  655. dft = $.jgrid.formatter.date.masks[dft];
  656. }
  657. } else {
  658. dft = cm[valref].datefmt || "Y-m-d";
  659. }
  660. if(!$.jgrid.checkDate (dft, val)) { return [false,nm+": "+$.jgrid.edit.msg.date+" - "+dft,""]; }
  661. }
  662. }
  663. if(edtrul.time === true) {
  664. if( !(rqfield === false && $.jgrid.isEmpty(val)) ) {
  665. if(!$.jgrid.checkTime (val)) { return [false,nm+": "+$.jgrid.edit.msg.date+" - hh:mm (am/pm)",""]; }
  666. }
  667. }
  668. if(edtrul.url === true) {
  669. if( !(rqfield === false && $.jgrid.isEmpty(val)) ) {
  670. filter = /^(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
  671. if(!filter.test(val)) {return [false,nm+": "+$.jgrid.edit.msg.url,""];}
  672. }
  673. }
  674. if(edtrul.custom === true) {
  675. if( !(rqfield === false && $.jgrid.isEmpty(val)) ) {
  676. if($.isFunction(edtrul.custom_func)) {
  677. var ret = edtrul.custom_func.call(g,val,nm,valref);
  678. return $.isArray(ret) ? ret : [false,$.jgrid.edit.msg.customarray,""];
  679. }
  680. return [false,$.jgrid.edit.msg.customfcheck,""];
  681. }
  682. }
  683. }
  684. return [true,"",""];
  685. }
  686. });
  687. })(jQuery);