EVOLUTION-MANAGER
Edit File: grid.custom.js
/*jshint eqeqeq:false */ /*global jQuery */ (function($){ /** * jqGrid extension for custom methods * Tony Tomov tony@trirand.com * http://trirand.com/blog/ * * Wildraid wildraid@mail.ru * Oleg Kiriljuk oleg.kiriljuk@ok-soft-gmbh.com * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl-2.0.html **/ "use strict"; $.jgrid.extend({ getColProp : function(colname){ var ret ={}, $t = this[0]; if ( !$t.grid ) { return false; } var cM = $t.p.colModel, i; for ( i=0;i<cM.length;i++ ) { if ( cM[i].name === colname ) { ret = cM[i]; break; } } return ret; }, setColProp : function(colname, obj){ //do not set width will not work return this.each(function(){ if ( this.grid ) { if ( obj ) { var cM = this.p.colModel, i; for ( i=0;i<cM.length;i++ ) { if ( cM[i].name === colname ) { $.extend(true, this.p.colModel[i],obj); break; } } } } }); }, sortGrid : function(colname,reload, sor){ return this.each(function(){ var $t=this,idx=-1,i, sobj=false; if ( !$t.grid ) { return;} if ( !colname ) { colname = $t.p.sortname; } for ( i=0;i<$t.p.colModel.length;i++ ) { if ( $t.p.colModel[i].index === colname || $t.p.colModel[i].name === colname ) { idx = i; if($t.p.frozenColumns === true && $t.p.colModel[i].frozen === true) { sobj = $t.grid.fhDiv.find("#" + $t.p.id + "_" + colname); } break; } } if ( idx !== -1 ){ var sort = $t.p.colModel[idx].sortable; if(!sobj) { sobj = $t.grid.headers[idx].el; } if ( typeof sort !== 'boolean' ) { sort = true; } if ( typeof reload !=='boolean' ) { reload = false; } if ( sort ) { $t.sortData("jqgh_"+$t.p.id+"_" + colname, idx, reload, sor, sobj); } } }); }, clearBeforeUnload : function () { return this.each(function(){ var grid = this.grid; if ($.isFunction(grid.emptyRows)) { grid.emptyRows.call(this, true, true); // this work quick enough and reduce the size of memory leaks if we have someone } $(document).unbind("mouseup.jqGrid" + this.p.id ); $(grid.hDiv).unbind("mousemove"); // TODO add namespace $(this).unbind(); grid.dragEnd = null; grid.dragMove = null; grid.dragStart = null; grid.emptyRows = null; grid.populate = null; grid.populateVisible = null; grid.scrollGrid = null; grid.selectionPreserver = null; grid.bDiv = null; grid.cDiv = null; grid.hDiv = null; grid.cols = null; var i, l = grid.headers.length; for (i = 0; i < l; i++) { grid.headers[i].el = null; } this.formatCol = null; this.sortData = null; this.updatepager = null; this.refreshIndex = null; this.setHeadCheckBox = null; this.constructTr = null; this.formatter = null; this.addXmlData = null; this.addJSONData = null; this.grid = null; }); }, GridDestroy : function () { return this.each(function(){ if ( this.grid ) { if ( this.p.pager ) { // if not part of grid $(this.p.pager).remove(); } try { $(this).jqGrid('clearBeforeUnload'); $("#gbox_"+$.jgrid.jqID(this.id)).remove(); } catch (_) {} } }); }, GridUnload : function(){ return this.each(function(){ if ( !this.grid ) {return;} var defgrid = {id: $(this).attr('id'),cl: $(this).attr('class')}; if (this.p.pager) { $(this.p.pager).empty().removeClass("ui-state-default ui-jqgrid-pager ui-corner-bottom"); } var newtable = document.createElement('table'); $(newtable).attr({id:defgrid.id}); newtable.className = defgrid.cl; var gid = $.jgrid.jqID(this.id); $(newtable).removeClass("ui-jqgrid-btable"); if( $(this.p.pager).parents("#gbox_"+gid).length === 1 ) { $(newtable).insertBefore("#gbox_"+gid).show(); $(this.p.pager).insertBefore("#gbox_"+gid); } else { $(newtable).insertBefore("#gbox_"+gid).show(); } $(this).jqGrid('clearBeforeUnload'); $("#gbox_"+gid).remove(); }); }, setGridState : function(state) { return this.each(function(){ if ( !this.grid ) {return;} var $t = this; if(state === 'hidden'){ $(".ui-jqgrid-bdiv, .ui-jqgrid-hdiv","#gview_"+$.jgrid.jqID($t.p.id)).slideUp("fast"); if($t.p.pager) {$($t.p.pager).slideUp("fast");} if($t.p.toppager) {$($t.p.toppager).slideUp("fast");} if($t.p.toolbar[0]===true) { if( $t.p.toolbar[1] === 'both') { $($t.grid.ubDiv).slideUp("fast"); } $($t.grid.uDiv).slideUp("fast"); } if($t.p.footerrow) { $(".ui-jqgrid-sdiv","#gbox_"+$.jgrid.jqID($t.p.id)).slideUp("fast"); } $(".ui-jqgrid-titlebar-close span",$t.grid.cDiv).removeClass("ui-icon-circle-triangle-n").addClass("ui-icon-circle-triangle-s"); $t.p.gridstate = 'hidden'; } else if(state === 'visible') { $(".ui-jqgrid-hdiv, .ui-jqgrid-bdiv","#gview_"+$.jgrid.jqID($t.p.id)).slideDown("fast"); if($t.p.pager) {$($t.p.pager).slideDown("fast");} if($t.p.toppager) {$($t.p.toppager).slideDown("fast");} if($t.p.toolbar[0]===true) { if( $t.p.toolbar[1] === 'both') { $($t.grid.ubDiv).slideDown("fast"); } $($t.grid.uDiv).slideDown("fast"); } if($t.p.footerrow) { $(".ui-jqgrid-sdiv","#gbox_"+$.jgrid.jqID($t.p.id)).slideDown("fast"); } $(".ui-jqgrid-titlebar-close span",$t.grid.cDiv).removeClass("ui-icon-circle-triangle-s").addClass("ui-icon-circle-triangle-n"); $t.p.gridstate = 'visible'; } }); }, filterToolbar : function(p){ p = $.extend({ autosearch: true, searchOnEnter : true, beforeSearch: null, afterSearch: null, beforeClear: null, afterClear: null, searchurl : '', stringResult: false, groupOp: 'AND', defaultSearch : "bw", searchOperators : false, resetIcon : "x", operands : { "eq" :"==", "ne":"!","lt":"<","le":"<=","gt":">","ge":">=","bw":"^","bn":"!^","in":"=","ni":"!=","ew":"|","en":"!@","cn":"~","nc":"!~","nu":"#","nn":"!#"} }, $.jgrid.search , p || {}); return this.each(function(){ var $t = this; if(this.ftoolbar) { return; } var triggerToolbar = function() { var sdata={}, j=0, v, nm, sopt={},so; $.each($t.p.colModel,function(){ var $elem = $("#gs_"+$.jgrid.jqID(this.name), (this.frozen===true && $t.p.frozenColumns === true) ? $t.grid.fhDiv : $t.grid.hDiv); nm = this.index || this.name; if(p.searchOperators ) { so = $elem.parent().prev().children("a").attr("soper") || p.defaultSearch; } else { so = (this.searchoptions && this.searchoptions.sopt) ? this.searchoptions.sopt[0] : this.stype==='select'? 'eq' : p.defaultSearch; } v = this.stype === "custom" && $.isFunction(this.searchoptions.custom_value) && $elem.length > 0 && $elem[0].nodeName.toUpperCase() === "SPAN" ? this.searchoptions.custom_value.call($t, $elem.children(".customelement:first"), "get") : $elem.val(); if(v || so==="nu" || so==="nn") { sdata[nm] = v; sopt[nm] = so; j++; } else { try { delete $t.p.postData[nm]; } catch (z) {} } }); var sd = j>0 ? true : false; if(p.stringResult === true || $t.p.datatype === "local" || p.searchOperators === true) { var ruleGroup = "{\"groupOp\":\"" + p.groupOp + "\",\"rules\":["; var gi=0; $.each(sdata,function(i,n){ if (gi > 0) {ruleGroup += ",";} ruleGroup += "{\"field\":\"" + i + "\","; ruleGroup += "\"op\":\"" + sopt[i] + "\","; n+=""; ruleGroup += "\"data\":\"" + n.replace(/\\/g,'\\\\').replace(/\"/g,'\\"') + "\"}"; gi++; }); ruleGroup += "]}"; $.extend($t.p.postData,{filters:ruleGroup}); $.each(['searchField', 'searchString', 'searchOper'], function(i, n){ if($t.p.postData.hasOwnProperty(n)) { delete $t.p.postData[n];} }); } else { $.extend($t.p.postData,sdata); } var saveurl; if($t.p.searchurl) { saveurl = $t.p.url; $($t).jqGrid("setGridParam",{url:$t.p.searchurl}); } var bsr = $($t).triggerHandler("jqGridToolbarBeforeSearch") === 'stop' ? true : false; if(!bsr && $.isFunction(p.beforeSearch)){bsr = p.beforeSearch.call($t);} if(!bsr) { $($t).jqGrid("setGridParam",{search:sd}).trigger("reloadGrid",[{page:1}]); } if(saveurl) {$($t).jqGrid("setGridParam",{url:saveurl});} $($t).triggerHandler("jqGridToolbarAfterSearch"); if($.isFunction(p.afterSearch)){p.afterSearch.call($t);} }, clearToolbar = function(trigger){ var sdata={}, j=0, nm; trigger = (typeof trigger !== 'boolean') ? true : trigger; $.each($t.p.colModel,function(){ var v, $elem = $("#gs_"+$.jgrid.jqID(this.name),(this.frozen===true && $t.p.frozenColumns === true) ? $t.grid.fhDiv : $t.grid.hDiv); if(this.searchoptions && this.searchoptions.defaultValue !== undefined) { v = this.searchoptions.defaultValue; } nm = this.index || this.name; switch (this.stype) { case 'select' : $elem.find("option").each(function (i){ if(i===0) { this.selected = true; } if ($(this).val() === v) { this.selected = true; return false; } }); if ( v !== undefined ) { // post the key and not the text sdata[nm] = v; j++; } else { try { delete $t.p.postData[nm]; } catch(e) {} } break; case 'text': $elem.val(v || ""); if(v !== undefined) { sdata[nm] = v; j++; } else { try { delete $t.p.postData[nm]; } catch (y){} } break; case 'custom': if ($.isFunction(this.searchoptions.custom_value) && $elem.length > 0 && $elem[0].nodeName.toUpperCase() === "SPAN") { this.searchoptions.custom_value.call($t, $elem.children(".customelement:first"), "set", v || ""); } break; } }); var sd = j>0 ? true : false; $t.p.resetsearch = true; if(p.stringResult === true || $t.p.datatype === "local") { var ruleGroup = "{\"groupOp\":\"" + p.groupOp + "\",\"rules\":["; var gi=0; $.each(sdata,function(i,n){ if (gi > 0) {ruleGroup += ",";} ruleGroup += "{\"field\":\"" + i + "\","; ruleGroup += "\"op\":\"" + "eq" + "\","; n+=""; ruleGroup += "\"data\":\"" + n.replace(/\\/g,'\\\\').replace(/\"/g,'\\"') + "\"}"; gi++; }); ruleGroup += "]}"; $.extend($t.p.postData,{filters:ruleGroup}); $.each(['searchField', 'searchString', 'searchOper'], function(i, n){ if($t.p.postData.hasOwnProperty(n)) { delete $t.p.postData[n];} }); } else { $.extend($t.p.postData,sdata); } var saveurl; if($t.p.searchurl) { saveurl = $t.p.url; $($t).jqGrid("setGridParam",{url:$t.p.searchurl}); } var bcv = $($t).triggerHandler("jqGridToolbarBeforeClear") === 'stop' ? true : false; if(!bcv && $.isFunction(p.beforeClear)){bcv = p.beforeClear.call($t);} if(!bcv) { if(trigger) { $($t).jqGrid("setGridParam",{search:sd}).trigger("reloadGrid",[{page:1}]); } } if(saveurl) {$($t).jqGrid("setGridParam",{url:saveurl});} $($t).triggerHandler("jqGridToolbarAfterClear"); if($.isFunction(p.afterClear)){p.afterClear();} }, toggleToolbar = function(){ var trow = $("tr.ui-search-toolbar",$t.grid.hDiv), trow2 = $t.p.frozenColumns === true ? $("tr.ui-search-toolbar",$t.grid.fhDiv) : false; if(trow.css("display") === 'none') { trow.show(); if(trow2) { trow2.show(); } } else { trow.hide(); if(trow2) { trow2.hide(); } } }, buildRuleMenu = function( elem, left, top ){ $("#sopt_menu").remove(); left=parseInt(left,10); top=parseInt(top,10) + 18; var fs = $('.ui-jqgrid-view').css('font-size') || '11px'; var str = '<ul id="sopt_menu" class="ui-search-menu" role="menu" tabindex="0" style="font-size:'+fs+';left:'+left+'px;top:'+top+'px;">', selected = $(elem).attr("soper"), selclass, aoprs = [], ina; var i=0, nm =$(elem).attr("colname"),len = $t.p.colModel.length; while(i<len) { if($t.p.colModel[i].name === nm) { break; } i++; } var cm = $t.p.colModel[i], options = $.extend({}, cm.searchoptions); if(!options.sopt) { options.sopt = []; options.sopt[0]= cm.stype==='select' ? 'eq' : p.defaultSearch; } $.each(p.odata, function() { aoprs.push(this.oper); }); for ( i = 0 ; i < options.sopt.length; i++) { ina = $.inArray(options.sopt[i],aoprs); if(ina !== -1) { selclass = selected === p.odata[ina].oper ? "ui-state-highlight" : ""; str += '<li class="ui-menu-item '+selclass+'" role="presentation"><a class="ui-corner-all g-menu-item" tabindex="0" role="menuitem" value="'+p.odata[ina].oper+'" oper="'+p.operands[p.odata[ina].oper]+'"><table cellspacing="0" cellpadding="0" border="0"><tr><td width="25px">'+p.operands[p.odata[ina].oper]+'</td><td>'+ p.odata[ina].text+'</td></tr></table></a></li>'; } } str += "</ul>"; $('body').append(str); $("#sopt_menu").addClass("ui-menu ui-widget ui-widget-content ui-corner-all"); $("#sopt_menu > li > a").hover( function(){ $(this).addClass("ui-state-hover"); }, function(){ $(this).removeClass("ui-state-hover"); } ).click(function( e ){ var v = $(this).attr("value"), oper = $(this).attr("oper"); $($t).triggerHandler("jqGridToolbarSelectOper", [v, oper, elem]); $("#sopt_menu").hide(); $(elem).text(oper).attr("soper",v); if(p.autosearch===true){ var inpelm = $(elem).parent().next().children()[0]; if( $(inpelm).val() || v==="nu" || v ==="nn") { triggerToolbar(); } } }); }; // create the row var tr = $("<tr class='ui-search-toolbar' role='rowheader'></tr>"); var timeoutHnd; $.each($t.p.colModel,function(ci){ var cm=this, soptions, surl, self, select = "", sot="=", so, i, th = $("<th role='columnheader' class='ui-state-default ui-th-column ui-th-"+$t.p.direction+"'></th>"), thd = $("<div style='position:relative;height:auto;padding-right:0.3em;padding-left:0.3em;'></div>"), stbl = $("<table class='ui-search-table' cellspacing='0'><tr><td class='ui-search-oper'></td><td class='ui-search-input'></td><td class='ui-search-clear'></td></tr></table>"); if(this.hidden===true) { $(th).css("display","none");} this.search = this.search === false ? false : true; if(this.stype === undefined) {this.stype='text';} soptions = $.extend({},this.searchoptions || {}); if(this.search){ if(p.searchOperators) { so = (soptions.sopt) ? soptions.sopt[0] : cm.stype==='select' ? 'eq' : p.defaultSearch; for(i = 0;i<p.odata.length;i++) { if(p.odata[i].oper === so) { sot = p.operands[so] || ""; break; } } var st = soptions.searchtitle != null ? soptions.searchtitle : p.operandTitle; select = "<a title='"+st+"' style='padding-right: 0.5em;' soper='"+so+"' class='soptclass' colname='"+this.name+"'>"+sot+"</a>"; } $("td:eq(0)",stbl).attr("colindex",ci).append(select); if(soptions.clearSearch === undefined) { soptions.clearSearch = true; } if(soptions.clearSearch) { var csv = p.resetTitle || 'Clear Search Value'; $("td:eq(2)",stbl).append("<a title='"+csv+"' style='padding-right: 0.3em;padding-left: 0.3em;' class='clearsearchclass'>"+p.resetIcon+"</a>"); } else { $("td:eq(2)", stbl).hide(); } switch (this.stype) { case "select": surl = this.surl || soptions.dataUrl; if(surl) { // data returned should have already constructed html select // primitive jQuery load self = thd; $(self).append(stbl); $.ajax($.extend({ url: surl, dataType: "html", success: function(res) { if(soptions.buildSelect !== undefined) { var d = soptions.buildSelect(res); if (d) { $("td:eq(1)",stbl).append(d); } } else { $("td:eq(1)",stbl).append(res); } if(soptions.defaultValue !== undefined) { $("select",self).val(soptions.defaultValue); } $("select",self).attr({name:cm.index || cm.name, id: "gs_"+cm.name}); if(soptions.attr) {$("select",self).attr(soptions.attr);} $("select",self).css({width: "100%"}); // preserve autoserch $.jgrid.bindEv.call($t, $("select",self)[0], soptions); if(p.autosearch===true){ $("select",self).change(function(){ triggerToolbar(); return false; }); } res=null; } }, $.jgrid.ajaxOptions, $t.p.ajaxSelectOptions || {} )); } else { var oSv, sep, delim; if(cm.searchoptions) { oSv = cm.searchoptions.value === undefined ? "" : cm.searchoptions.value; sep = cm.searchoptions.separator === undefined ? ":" : cm.searchoptions.separator; delim = cm.searchoptions.delimiter === undefined ? ";" : cm.searchoptions.delimiter; } else if(cm.editoptions) { oSv = cm.editoptions.value === undefined ? "" : cm.editoptions.value; sep = cm.editoptions.separator === undefined ? ":" : cm.editoptions.separator; delim = cm.editoptions.delimiter === undefined ? ";" : cm.editoptions.delimiter; } if (oSv) { var elem = document.createElement("select"); elem.style.width = "100%"; $(elem).attr({name:cm.index || cm.name, id: "gs_"+cm.name}); var sv, ov, key, k; if(typeof oSv === "string") { so = oSv.split(delim); for(k=0; k<so.length;k++){ sv = so[k].split(sep); ov = document.createElement("option"); ov.value = sv[0]; ov.innerHTML = sv[1]; elem.appendChild(ov); } } else if(typeof oSv === "object" ) { for (key in oSv) { if(oSv.hasOwnProperty(key)) { ov = document.createElement("option"); ov.value = key; ov.innerHTML = oSv[key]; elem.appendChild(ov); } } } if(soptions.defaultValue !== undefined) { $(elem).val(soptions.defaultValue); } if(soptions.attr) {$(elem).attr(soptions.attr);} $(thd).append(stbl); $.jgrid.bindEv.call($t, elem , soptions); $("td:eq(1)",stbl).append( elem ); if(p.autosearch===true){ $(elem).change(function(){ triggerToolbar(); return false; }); } } } break; case "text": var df = soptions.defaultValue !== undefined ? soptions.defaultValue: ""; $("td:eq(1)",stbl).append("<input type='text' style='width:100%;padding:0px;' name='"+(cm.index || cm.name)+"' id='gs_"+cm.name+"' value='"+df+"'/>"); $(thd).append(stbl); if(soptions.attr) {$("input",thd).attr(soptions.attr);} $.jgrid.bindEv.call($t, $("input",thd)[0], soptions); if(p.autosearch===true){ if(p.searchOnEnter) { $("input",thd).keypress(function(e){ var key = e.charCode || e.keyCode || 0; if(key === 13){ triggerToolbar(); return false; } return this; }); } else { $("input",thd).keydown(function(e){ var key = e.which; switch (key) { case 13: return false; case 9 : case 16: case 37: case 38: case 39: case 40: case 27: break; default : if(timeoutHnd) { clearTimeout(timeoutHnd); } timeoutHnd = setTimeout(function(){triggerToolbar();},500); } }); } } break; case "custom": $("td:eq(1)",stbl).append("<span style='width:95%;padding:0px;' name='"+(cm.index || cm.name)+"' id='gs_"+cm.name+"'/>"); $(thd).append(stbl); try { if($.isFunction(soptions.custom_element)) { var celm = soptions.custom_element.call($t,soptions.defaultValue !== undefined ? soptions.defaultValue: "",soptions); if(celm) { celm = $(celm).addClass("customelement"); $(thd).find("span[name='" + (cm.index || cm.name) + "']").append(celm); } else { throw "e2"; } } else { throw "e1"; } } catch (e) { if (e === "e1") { $.jgrid.info_dialog($.jgrid.errors.errcap,"function 'custom_element' "+$.jgrid.edit.msg.nodefined,$.jgrid.edit.bClose);} if (e === "e2") { $.jgrid.info_dialog($.jgrid.errors.errcap,"function 'custom_element' "+$.jgrid.edit.msg.novalue,$.jgrid.edit.bClose);} else { $.jgrid.info_dialog($.jgrid.errors.errcap,typeof e==="string"?e:e.message,$.jgrid.edit.bClose); } } break; } } $(th).append(thd); $(tr).append(th); if(!p.searchOperators) { $("td:eq(0)",stbl).hide(); } }); $("table thead",$t.grid.hDiv).append(tr); if(p.searchOperators) { $(".soptclass",tr).click(function(e){ var offset = $(this).offset(), left = ( offset.left ), top = ( offset.top); buildRuleMenu(this, left, top ); e.stopPropagation(); }); $("body").on('click', function(e){ if(e.target.className !== "soptclass") { $("#sopt_menu").hide(); } }); } $(".clearsearchclass",tr).click(function(e){ var ptr = $(this).parents("tr:first"), coli = parseInt($("td.ui-search-oper", ptr).attr('colindex'),10), sval = $.extend({},$t.p.colModel[coli].searchoptions || {}), dval = sval.defaultValue ? sval.defaultValue : ""; if($t.p.colModel[coli].stype === "select") { if(dval) { $("td.ui-search-input select", ptr).val( dval ); } else { $("td.ui-search-input select", ptr)[0].selectedIndex = 0; } } else { $("td.ui-search-input input", ptr).val( dval ); } // ToDo custom search type if(p.autosearch===true){ triggerToolbar(); } }); this.ftoolbar = true; this.triggerToolbar = triggerToolbar; this.clearToolbar = clearToolbar; this.toggleToolbar = toggleToolbar; }); }, destroyFilterToolbar: function () { return this.each(function () { if (!this.ftoolbar) { return; } this.triggerToolbar = null; this.clearToolbar = null; this.toggleToolbar = null; this.ftoolbar = false; $(this.grid.hDiv).find("table thead tr.ui-search-toolbar").remove(); }); }, destroyGroupHeader : function(nullHeader) { if(nullHeader === undefined) { nullHeader = true; } return this.each(function() { var $t = this, $tr, i, l, headers, $th, $resizing, grid = $t.grid, thead = $("table.ui-jqgrid-htable thead", grid.hDiv), cm = $t.p.colModel, hc; if(!grid) { return; } $(this).unbind('.setGroupHeaders'); $tr = $("<tr>", {role: "rowheader"}).addClass("ui-jqgrid-labels"); headers = grid.headers; for (i = 0, l = headers.length; i < l; i++) { hc = cm[i].hidden ? "none" : ""; $th = $(headers[i].el) .width(headers[i].width) .css('display',hc); try { $th.removeAttr("rowSpan"); } catch (rs) { //IE 6/7 $th.attr("rowSpan",1); } $tr.append($th); $resizing = $th.children("span.ui-jqgrid-resize"); if ($resizing.length>0) {// resizable column $resizing[0].style.height = ""; } $th.children("div")[0].style.top = ""; } $(thead).children('tr.ui-jqgrid-labels').remove(); $(thead).prepend($tr); if(nullHeader === true) { $($t).jqGrid('setGridParam',{ 'groupHeader': null}); } }); }, setGroupHeaders : function ( o ) { o = $.extend({ useColSpanStyle : false, groupHeaders: [] },o || {}); return this.each(function(){ this.p.groupHeader = o; var ts = this, i, cmi, skip = 0, $tr, $colHeader, th, $th, thStyle, iCol, cghi, //startColumnName, numberOfColumns, titleText, cVisibleColumns, colModel = ts.p.colModel, cml = colModel.length, ths = ts.grid.headers, $htable = $("table.ui-jqgrid-htable", ts.grid.hDiv), $trLabels = $htable.children("thead").children("tr.ui-jqgrid-labels:last").addClass("jqg-second-row-header"), $thead = $htable.children("thead"), $theadInTable, $firstHeaderRow = $htable.find(".jqg-first-row-header"); if($firstHeaderRow[0] === undefined) { $firstHeaderRow = $('<tr>', {role: "row", "aria-hidden": "true"}).addClass("jqg-first-row-header").css("height", "auto"); } else { $firstHeaderRow.empty(); } var $firstRow, inColumnHeader = function (text, columnHeaders) { var length = columnHeaders.length, i; for (i = 0; i < length; i++) { if (columnHeaders[i].startColumnName === text) { return i; } } return -1; }; $(ts).prepend($thead); $tr = $('<tr>', {role: "rowheader"}).addClass("ui-jqgrid-labels jqg-third-row-header"); for (i = 0; i < cml; i++) { th = ths[i].el; $th = $(th); cmi = colModel[i]; // build the next cell for the first header row thStyle = { height: '0px', width: ths[i].width + 'px', display: (cmi.hidden ? 'none' : '')}; $("<th>", {role: 'gridcell'}).css(thStyle).addClass("ui-first-th-"+ts.p.direction).appendTo($firstHeaderRow); th.style.width = ""; // remove unneeded style iCol = inColumnHeader(cmi.name, o.groupHeaders); if (iCol >= 0) { cghi = o.groupHeaders[iCol]; numberOfColumns = cghi.numberOfColumns; titleText = cghi.titleText; // caclulate the number of visible columns from the next numberOfColumns columns for (cVisibleColumns = 0, iCol = 0; iCol < numberOfColumns && (i + iCol < cml); iCol++) { if (!colModel[i + iCol].hidden) { cVisibleColumns++; } } // The next numberOfColumns headers will be moved in the next row // in the current row will be placed the new column header with the titleText. // The text will be over the cVisibleColumns columns $colHeader = $('<th>').attr({role: "columnheader"}) .addClass("ui-state-default ui-th-column-header ui-th-"+ts.p.direction) .css({'height':'22px', 'border-top': '0 none'}) .html(titleText); if(cVisibleColumns > 0) { $colHeader.attr("colspan", String(cVisibleColumns)); } if (ts.p.headertitles) { $colHeader.attr("title", $colHeader.text()); } // hide if not a visible cols if( cVisibleColumns === 0) { $colHeader.hide(); } $th.before($colHeader); // insert new column header before the current $tr.append(th); // move the current header in the next row // set the coumter of headers which will be moved in the next row skip = numberOfColumns - 1; } else { if (skip === 0) { if (o.useColSpanStyle) { // expand the header height to two rows $th.attr("rowspan", "2"); } else { $('<th>', {role: "columnheader"}) .addClass("ui-state-default ui-th-column-header ui-th-"+ts.p.direction) .css({"display": cmi.hidden ? 'none' : '', 'border-top': '0 none'}) .insertBefore($th); $tr.append(th); } } else { // move the header to the next row //$th.css({"padding-top": "2px", height: "19px"}); $tr.append(th); skip--; } } } $theadInTable = $(ts).children("thead"); $theadInTable.prepend($firstHeaderRow); $tr.insertAfter($trLabels); $htable.append($theadInTable); if (o.useColSpanStyle) { // Increase the height of resizing span of visible headers $htable.find("span.ui-jqgrid-resize").each(function () { var $parent = $(this).parent(); if ($parent.is(":visible")) { this.style.cssText = 'height: ' + $parent.height() + 'px !important; cursor: col-resize;'; } }); // Set position of the sortable div (the main lable) // with the column header text to the middle of the cell. // One should not do this for hidden headers. $htable.find("div.ui-jqgrid-sortable").each(function () { var $ts = $(this), $parent = $ts.parent(); if ($parent.is(":visible") && $parent.is(":has(span.ui-jqgrid-resize)")) { $ts.css('top', ($parent.height() - $ts.outerHeight()) / 2 + 'px'); } }); } $firstRow = $theadInTable.find("tr.jqg-first-row-header"); $(ts).bind('jqGridResizeStop.setGroupHeaders', function (e, nw, idx) { $firstRow.find('th').eq(idx).width(nw); }); }); }, setFrozenColumns : function () { return this.each(function() { if ( !this.grid ) {return;} var $t = this, cm = $t.p.colModel,i=0, len = cm.length, maxfrozen = -1, frozen= false; // TODO treeGrid and grouping Support if($t.p.subGrid === true || $t.p.treeGrid === true || $t.p.cellEdit === true || $t.p.sortable || $t.p.scroll ) { return; } if($t.p.rownumbers) { i++; } if($t.p.multiselect) { i++; } // get the max index of frozen col while(i<len) { // from left, no breaking frozen if(cm[i].frozen === true) { frozen = true; maxfrozen = i; } else { break; } i++; } if( maxfrozen>=0 && frozen) { var top = $t.p.caption ? $($t.grid.cDiv).outerHeight() : 0, hth = $(".ui-jqgrid-htable","#gview_"+$.jgrid.jqID($t.p.id)).height(); //headers if($t.p.toppager) { top = top + $($t.grid.topDiv).outerHeight(); } if($t.p.toolbar[0] === true) { if($t.p.toolbar[1] !== "bottom") { top = top + $($t.grid.uDiv).outerHeight(); } } $t.grid.fhDiv = $('<div style="position:absolute;left:0px;top:'+top+'px;height:'+hth+'px;" class="frozen-div ui-state-default ui-jqgrid-hdiv"></div>'); $t.grid.fbDiv = $('<div style="position:absolute;left:0px;top:'+(parseInt(top,10)+parseInt(hth,10) + 1)+'px;overflow-y:hidden" class="frozen-bdiv ui-jqgrid-bdiv"></div>'); $("#gview_"+$.jgrid.jqID($t.p.id)).append($t.grid.fhDiv); var htbl = $(".ui-jqgrid-htable","#gview_"+$.jgrid.jqID($t.p.id)).clone(true); // groupheader support - only if useColSpanstyle is false if($t.p.groupHeader) { $("tr.jqg-first-row-header, tr.jqg-third-row-header", htbl).each(function(){ $("th:gt("+maxfrozen+")",this).remove(); }); var swapfroz = -1, fdel = -1, cs, rs; $("tr.jqg-second-row-header th", htbl).each(function(){ cs= parseInt($(this).attr("colspan"),10); rs= parseInt($(this).attr("rowspan"),10); if(rs) { swapfroz++; fdel++; } if(cs) { swapfroz = swapfroz+cs; fdel++; } if(swapfroz === maxfrozen) { return false; } }); if(swapfroz !== maxfrozen) { fdel = maxfrozen; } $("tr.jqg-second-row-header", htbl).each(function(){ $("th:gt("+fdel+")",this).remove(); }); } else { $("tr",htbl).each(function(){ $("th:gt("+maxfrozen+")",this).remove(); }); } $(htbl).width(1); // resizing stuff $($t.grid.fhDiv).append(htbl) .mousemove(function (e) { if($t.grid.resizing){ $t.grid.dragMove(e);return false; } }); if($t.p.footerrow) { var hbd = $(".ui-jqgrid-bdiv","#gview_"+$.jgrid.jqID($t.p.id)).height(); $t.grid.fsDiv = $('<div style="position:absolute;left:0px;top:'+(parseInt(top,10)+parseInt(hth,10) + parseInt(hbd,10)+1)+'px;" class="frozen-sdiv ui-jqgrid-sdiv"></div>'); $("#gview_"+$.jgrid.jqID($t.p.id)).append($t.grid.fsDiv); var ftbl = $(".ui-jqgrid-ftable","#gview_"+$.jgrid.jqID($t.p.id)).clone(true); $("tr",ftbl).each(function(){ $("td:gt("+maxfrozen+")",this).remove(); }); $(ftbl).width(1); $($t.grid.fsDiv).append(ftbl); } $($t).bind('jqGridResizeStop.setFrozenColumns', function (e, w, index) { var rhth = $(".ui-jqgrid-htable",$t.grid.fhDiv); $("th:eq("+index+")",rhth).width( w ); var btd = $(".ui-jqgrid-btable",$t.grid.fbDiv); $("tr:first td:eq("+index+")",btd).width( w ); if($t.p.footerrow) { var ftd = $(".ui-jqgrid-ftable",$t.grid.fsDiv); $("tr:first td:eq("+index+")",ftd).width( w ); } }); // sorting stuff $($t).bind('jqGridSortCol.setFrozenColumns', function (e, index, idxcol) { var previousSelectedTh = $("tr.ui-jqgrid-labels:last th:eq("+$t.p.lastsort+")",$t.grid.fhDiv), newSelectedTh = $("tr.ui-jqgrid-labels:last th:eq("+idxcol+")",$t.grid.fhDiv); $("span.ui-grid-ico-sort",previousSelectedTh).addClass('ui-state-disabled'); $(previousSelectedTh).attr("aria-selected","false"); $("span.ui-icon-"+$t.p.sortorder,newSelectedTh).removeClass('ui-state-disabled'); $(newSelectedTh).attr("aria-selected","true"); if(!$t.p.viewsortcols[0]) { if($t.p.lastsort !== idxcol) { $("span.s-ico",previousSelectedTh).hide(); $("span.s-ico",newSelectedTh).show(); } } }); // data stuff //TODO support for setRowData $("#gview_"+$.jgrid.jqID($t.p.id)).append($t.grid.fbDiv); $($t.grid.bDiv).scroll(function () { $($t.grid.fbDiv).scrollTop($(this).scrollTop()); }); if($t.p.hoverrows === true) { $("#"+$.jgrid.jqID($t.p.id)).unbind('mouseover').unbind('mouseout'); } $($t).bind('jqGridAfterGridComplete.setFrozenColumns', function () { $("#"+$.jgrid.jqID($t.p.id)+"_frozen").remove(); $($t.grid.fbDiv).height($($t.grid.bDiv).height()-16); var btbl = $("#"+$.jgrid.jqID($t.p.id)).clone(true); $("tr[role=row]",btbl).each(function(){ $("td[role=gridcell]:gt("+maxfrozen+")",this).remove(); }); $(btbl).width(1).attr("id",$t.p.id+"_frozen"); $($t.grid.fbDiv).append(btbl); if($t.p.hoverrows === true) { $("tr.jqgrow", btbl).hover( function(){ $(this).addClass("ui-state-hover"); $("#"+$.jgrid.jqID(this.id), "#"+$.jgrid.jqID($t.p.id)).addClass("ui-state-hover"); }, function(){ $(this).removeClass("ui-state-hover"); $("#"+$.jgrid.jqID(this.id), "#"+$.jgrid.jqID($t.p.id)).removeClass("ui-state-hover"); } ); $("tr.jqgrow", "#"+$.jgrid.jqID($t.p.id)).hover( function(){ $(this).addClass("ui-state-hover"); $("#"+$.jgrid.jqID(this.id), "#"+$.jgrid.jqID($t.p.id)+"_frozen").addClass("ui-state-hover");}, function(){ $(this).removeClass("ui-state-hover"); $("#"+$.jgrid.jqID(this.id), "#"+$.jgrid.jqID($t.p.id)+"_frozen").removeClass("ui-state-hover"); } ); } btbl=null; }); if(!$t.grid.hDiv.loading) { $($t).triggerHandler("jqGridAfterGridComplete"); } $t.p.frozenColumns = true; } }); }, destroyFrozenColumns : function() { return this.each(function() { if ( !this.grid ) {return;} if(this.p.frozenColumns === true) { var $t = this; $($t.grid.fhDiv).remove(); $($t.grid.fbDiv).remove(); $t.grid.fhDiv = null; $t.grid.fbDiv=null; if($t.p.footerrow) { $($t.grid.fsDiv).remove(); $t.grid.fsDiv = null; } $(this).unbind('.setFrozenColumns'); if($t.p.hoverrows === true) { var ptr; $("#"+$.jgrid.jqID($t.p.id)).bind('mouseover',function(e) { ptr = $(e.target).closest("tr.jqgrow"); if($(ptr).attr("class") !== "ui-subgrid") { $(ptr).addClass("ui-state-hover"); } }).bind('mouseout',function(e) { ptr = $(e.target).closest("tr.jqgrow"); $(ptr).removeClass("ui-state-hover"); }); } this.p.frozenColumns = false; } }); } }); })(jQuery);