// przerobiony fragment kodu jqgrid $.jgrid.extend({ //ostatnio zaznaczony wiersz lastSelectedId : undefined, //pomocnicza zmienna : jeśli true, to po załadowaniu grida //należy odpalić setSelection z parametrem lastSelectedId //uwaga: to nie to samo co odpalić scrollToLastSelection setOnComplete : false, //widok z funkcją mówiącą, który w kolejności będzie wiersz o danym id findIdUrl : undefined, //scrolluje do wiersza który jest 'row'-ty od góry, przy założeniu //że wszystkich wierszy jest rowcount scrollToRow : function(row, rowcount) { return this.each(function(){ var rowIndex = row; var recordsCount = rowcount; var clientHeight = $(this.grid.bDiv)[0].clientHeight; var scrollTop = $(this.grid.bDiv)[0].scrollTop; var scrollRange = $(this.grid.bDiv)[0].scrollHeight; //Załóżmy, że wiersze mają jedną wysokość... var rowTop = Math.round((rowIndex - 1) * (scrollRange / recordsCount)); $(this.grid.bDiv)[0].scrollTop = rowTop - Math.round(clientHeight / 2); }); }, //scrolls to row and sets selection scrollAndSet : function(id, row, count) { return this.each(function(){ var $t = this; $($t).jqGrid('setGridParam', {'lastSelectedId' : id}); if ($t.rows.namedItem(id)) { $($t).jqGrid('setSelection', id); } else {//odwlekamy zaznaczanie do załadowania (complete) $($t).jqGrid('setGridParam', {'setOnComplete' : true}); } $($t).jqGrid('scrollToRow', row, count); }); }, // added by bniton scrollToIdAndSet : function (id){ return this.each(function(){ var $t = this; $($t).jqGrid('setGridParam', {'lastSelectedId' : id}); if ($t.rows.namedItem(id)) { $($t).jqGrid('setSelection', id); } else {//odwlekamy zaznaczanie do załadowania (complete) $($t).jqGrid('setGridParam', {'setOnComplete' : true}); } $($t).jqGrid('scrollToId', id); }); }, scrollToId : function(id) { return this.each(function(){ var $t = this; data = { id: id }; $.extend(data, $($t).jqGrid('getGridParam','postData')); $.get($t.p.findIdUrl, data, function(resp){ var rowIndex = resp['rowIndex']; var recordsCount = resp['records']; $($t).jqGrid('scrollAndSet', id, rowIndex, recordsCount); }); }); }, //wracamy do ostatniego zaznaczenia scrollToLastSelection : function() { return this.each(function() { if(this.p.lastSelectedId != undefined) { $(this).jqGrid('scrollToId', this.p.lastSelectedId); } }); }, //łatka setSelection : function(selection) { return this.each(function(){ var $t = this; var pt=$t.rows.namedItem(selection+""); if(!pt) { return; } $($t).jqGrid("editCell", pt.rowIndex, 1, false, true); }) }, GridNav : function() { return this.each(function () { var $t = this; if (!$t.grid || $t.p.cellEdit !== true ) {return;} // trick to process keydown on non input elements $t.p.knv = $t.p.id + "_kn"; var selection = $("<span style='width:0px;height:0px;background-color:black;' tabindex='0'><span tabindex='-1' style='width:0px;height:0px;background-color:grey' id='"+$t.p.knv+"'></span></span>"), i, kdir; $(selection).insertBefore($t.grid.cDiv); $("#"+$t.p.knv) .focus() .keydown(function (e){ kdir = e.keyCode; if($t.p.direction == "rtl") { if(kdir==37) { kdir = 39;} else if (kdir==39) { kdir = 37; } } switch (kdir) { case 38: if ($t.p.iRow-1 >0 ) { scrollGrid($t.p.iRow-1,$t.p.iCol,'vu',1); $($t).jqGrid("editCell",$t.p.iRow-1,$t.p.iCol,false); return false; } break; case 40 : if ($t.p.iRow+1 <= $t.rows.length-1) { scrollGrid($t.p.iRow+1,$t.p.iCol,'vd',1); $($t).jqGrid("editCell",$t.p.iRow+1,$t.p.iCol,false); return false; } break; case 37 : if ($t.p.iCol -1 >= 0) { i = findNextVisible($t.p.iCol-1,'lft'); scrollGrid($t.p.iRow, i,'h',1); $($t).jqGrid("editCell",$t.p.iRow, i,false); return false; } break; case 39 : if ($t.p.iCol +1 <= $t.p.colModel.length-1) { i = findNextVisible($t.p.iCol+1,'rgt'); scrollGrid($t.p.iRow,i,'h',1); $($t).jqGrid("editCell",$t.p.iRow,i,false); return false; } break; case 13: if (parseInt($t.p.iCol,10)>=0 && parseInt($t.p.iRow,10)>=0) { $($t).jqGrid("editCell",$t.p.iRow,$t.p.iCol,true); return false; } break; case 33: // pageUp if ($t.p.iRow-10 >0 ) { scrollGrid($t.p.iRow-30,$t.p.iCol,'vu',10); $($t).jqGrid("editCell",$t.p.iRow-10,$t.p.iCol,false); return false; } break; case 34: // pageDown if ($t.p.iRow+10 <= $t.rows.length-1) { scrollGrid($t.p.iRow+30,$t.p.iCol,'vd',10); $($t).jqGrid("editCell",$t.p.iRow+10,$t.p.iCol,false); return false; } break; } return true; }); function scrollGrid(iR, iC, tp, amount){ if (tp.substr(0,1)=='v') { var ch = $($t.grid.bDiv)[0].clientHeight, st = $($t.grid.bDiv)[0].scrollTop, nROT = $t.rows[iR].offsetTop+$t.rows[iR].clientHeight, pROT = $t.rows[iR].offsetTop; if(tp == 'vd') { if(nROT >= ch) { $($t.grid.bDiv)[0].scrollTop = $($t.grid.bDiv)[0].scrollTop + ($t.rows[iR].clientHeight + 2) * amount; } } if(tp == 'vu'){ if (pROT < st ) { $($t.grid.bDiv)[0].scrollTop = $($t.grid.bDiv)[0].scrollTop - ($t.rows[iR].clientHeight + 2) * amount; } } } if(tp=='h') { var cw = $($t.grid.bDiv)[0].clientWidth, sl = $($t.grid.bDiv)[0].scrollLeft, nCOL = $t.rows[iR].cells[iC].offsetLeft+$t.rows[iR].cells[iC].clientWidth, pCOL = $t.rows[iR].cells[iC].offsetLeft; if(nCOL >= cw+parseInt(sl,10)) { $($t.grid.bDiv)[0].scrollLeft = $($t.grid.bDiv)[0].scrollLeft + $t.rows[iR].cells[iC].clientWidth; } else if (pCOL < sl) { $($t.grid.bDiv)[0].scrollLeft = $($t.grid.bDiv)[0].scrollLeft - $t.rows[iR].cells[iC].clientWidth; } } } function findNextVisible(iC,act){ var ind, i; if(act == 'lft') { ind = iC+1; for (i=iC;i>=0;i--){ if ($t.p.colModel[i].hidden !== true) { ind = i; break; } } } if(act == 'rgt') { ind = iC-1; for (i=iC; i<$t.p.colModel.length;i++){ if ($t.p.colModel[i].hidden !== true) { ind = i; break; } } } return ind; } }); }, //dodatkowy czwarty parametr, jeśli jest dostarczony, mówi by nie zmieniać focusa editCell : function (iRow,iCol, ed, noFocus){ return this.each(function (){ var $t = this, nm, tmp,cc; if (!$t.grid || $t.p.cellEdit !== true) {return;} if ($.isFunction($t.p.beforeSelectCell)) { if (!$t.p.beforeSelectCell.call($t, $t.rows[iRow].id,nm,tmp,iRow,iCol)) return; } iCol = parseInt(iCol,10); // select the row that can be used for other methods $t.p.selrow = $t.rows[iRow].id; if (!$t.p.knv) {$($t).jqGrid("GridNav");} // check to see if we have already edited cell if ($t.p.savedRow.length>0) { // prevent second click on that field and enable selects if (ed===true ) { if(iRow == $t.p.iRow && iCol == $t.p.iCol){ return; } } // save the cell $($t).jqGrid("saveCell",$t.p.savedRow[0].id,$t.p.savedRow[0].ic); } else if (!noFocus){ //zmiana w stosunku do jqGrida window.setTimeout(function () { $("#"+$t.p.knv).attr("tabindex","-1").focus();},0); } nm = $t.p.colModel[iCol].name; if (nm=='subgrid' || nm=='cb' || nm=='rn') {return;} cc = $("td:eq("+iCol+")",$t.rows[iRow]); if ($t.p.colModel[iCol].editable===true && ed===true && !cc.hasClass("not-editable-cell")) { if(parseInt($t.p.iCol,10)>=0 && parseInt($t.p.iRow,10)>=0) { $("td:eq("+$t.p.iCol+")",$t.rows[$t.p.iRow]).removeClass("edit-cell ui-state-highlight"); $($t.rows[$t.p.iRow]).removeClass("selected-row ui-state-hover"); } $(cc).addClass("edit-cell ui-state-highlight"); $($t.rows[iRow]).addClass("selected-row ui-state-hover"); try { tmp = $.unformat(cc,{rowId: $t.rows[iRow].id, colModel:$t.p.colModel[iCol]},iCol); } catch (_) { tmp = $(cc).html(); } if($t.p.autoencode) { tmp = $.jgrid.htmlDecode(tmp); } if (!$t.p.colModel[iCol].edittype) {$t.p.colModel[iCol].edittype = "text";} $t.p.savedRow.push({id:iRow,ic:iCol,name:nm,v:tmp}); if($.isFunction($t.p.formatCell)) { var tmp2 = $t.p.formatCell.call($t, $t.rows[iRow].id,nm,tmp,iRow,iCol); if(tmp2 !== undefined ) {tmp = tmp2;} } var opt = $.extend({}, $t.p.colModel[iCol].editoptions || {} ,{id:iRow+"_"+nm,name:nm}); var elc = $.jgrid.createEl($t.p.colModel[iCol].edittype,opt,tmp,true,$.extend({},$.jgrid.ajaxOptions,$t.p.ajaxSelectOptions || {})); if ($.isFunction($t.p.beforeEditCell)) { $t.p.beforeEditCell.call($t, $t.rows[iRow].id,nm,tmp,iRow,iCol); } $(cc).html("").append(elc).attr("tabindex","0"); //zmiana w stosunku do jqGrida if (!noFocus) { window.setTimeout(function () { $(elc).focus();},0); } $("input, select, textarea",cc).bind("keydown",function(e) { if (e.keyCode === 27) { if($("input.hasDatepicker",cc).length >0) { if( $(".ui-datepicker").is(":hidden") ) { $($t).jqGrid("restoreCell",iRow,iCol); } else { $("input.hasDatepicker",cc).datepicker('hide'); } } else { $($t).jqGrid("restoreCell",iRow,iCol); } } //ESC if (e.keyCode === 13) {$($t).jqGrid("saveCell",iRow,iCol);}//Enter if (e.keyCode == 9) { if(!$t.grid.hDiv.loading ) { if (e.shiftKey) {$($t).jqGrid("prevCell",iRow,iCol);} //Shift TAb else {$($t).jqGrid("nextCell",iRow,iCol);} //Tab } else { return false; } } e.stopPropagation(); }); if ($.isFunction($t.p.afterEditCell)) { $t.p.afterEditCell.call($t, $t.rows[iRow].id,nm,tmp,iRow,iCol); } } else { if (parseInt($t.p.iCol,10)>=0 && parseInt($t.p.iRow,10)>=0) { $("td:eq("+$t.p.iCol+")",$t.rows[$t.p.iRow]).removeClass("edit-cell ui-state-highlight"); $($t.rows[$t.p.iRow]).removeClass("selected-row ui-state-hover"); } cc.addClass("edit-cell ui-state-highlight"); $($t.rows[iRow]).addClass("selected-row ui-state-hover"); if ($.isFunction($t.p.onSelectCell)) { tmp = cc.html().replace(/\ \;/ig,''); $t.p.onSelectCell.call($t, $t.rows[iRow].id,nm,tmp,iRow,iCol); } } $t.p.iCol = iCol; $t.p.iRow = iRow; }); } }); /* * jqFilter jQuery jqGrid filter addon. * Copyright (c) 2011, Tony Tomov, tony@trirand.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 * * The work is inspired from this Stefan Pirvu * http://www.codeproject.com/KB/scripting/json-filtering.aspx * * The filter uses JSON entities to hold filter rules and groups. Here is an example of a filter: { "groupOp": "AND", "groups" : [ { "groupOp": "OR", "rules": [ { "field": "name", "op": "eq", "data": "England" }, { "field": "id", "op": "le", "data": "5"} ] } ], "rules": [ { "field": "name", "op": "eq", "data": "Romania" }, { "field": "id", "op": "le", "data": "1"} ] } */ /*global jQuery, $, window, navigator */ (function ($) { $.fn.jqFilter = function( arg ) { if (typeof arg === 'string') { var fn = $.fn.jqFilter[arg]; if (!fn) { throw ("jqFilter - No such method: " + arg); } var args = $.makeArray(arguments).slice(1); return fn.apply(this,args); } var p = $.extend(true,{ filter: null, columns: [], onChange : null, checkValues : null, error: false, errmsg : "", errorcheck : true, showQuery : true, sopt : null, ops : [ {"name": "eq", "description": "equal", "operator":"="}, {"name": "ne", "description": "not equal", "operator":"<>"}, {"name": "lt", "description": "less", "operator":"<"}, {"name": "le", "description": "less or equal","operator":"<="}, {"name": "gt", "description": "greater", "operator":">"}, {"name": "ge", "description": "greater or equal", "operator":">="}, {"name": "bw", "description": "begins with", "operator":"LIKE"}, {"name": "bn", "description": "does not begin with", "operator":"NOT LIKE"}, {"name": "in", "description": "in", "operator":"IN"}, {"name": "ni", "description": "not in", "operator":"NOT IN"}, {"name": "ew", "description": "ends with", "operator":"LIKE"}, {"name": "en", "description": "does not end with", "operator":"NOT LIKE"}, {"name": "cn", "description": "contains", "operator":"LIKE"}, {"name": "nc", "description": "does not contain", "operator":"NOT LIKE"}, {"name": "nu", "description": "is null", "operator":"IS NULL"}, {"name": "nn", "description": "is not null", "operator":"IS NOT NULL"}, {"name": "re", "description": "matches regex", "operator":"REGEXP"}, {"name": "nr", "description": "does not match regex", "operator":"NOT REGEXP"}, {"name": "se", "description": "equal for sure", "operator":"="}, {"name": "sd", "description": "different for sure", "operator":"<>"}, {"name": "me", "description": "maybe equal", "operator":"="}, {"name": "md", "description": "maybe different", "operator":"<>"} ], numopts : ['eq','ne', 'lt', 'le', 'gt', 'ge', 'nu', 'nn', 'in', 'ni'], stropts : ['eq', 'ne', 'bw', 'bn', 'ew', 'en', 'cn', 'nc', 'nu', 'nn', 'in', 'ni'], _gridsopt : [], // grid translated strings, do not tuch groupOps : ["AND", "OR"], groupButton : true }, arg || {}); return this.each( function() { if (this.filter) {return;} this.p = p; // setup filter in case if they is not defined if (this.p.filter === null || this.p.filter === undefined) { this.p.filter = { groupOp: this.p.groupOps[0], rules: [], groups: [] }; } var i, len = this.p.columns.length, cl, isIE = /msie/i.test(navigator.userAgent) && !window.opera; // translating the options if(this.p._gridsopt.length) { // ['eq','ne','lt','le','gt','ge','bw','bn','in','ni','ew','en','cn','nc'] for(i=0;i<this.p._gridsopt.length;i++) { this.p.ops[i].description = this.p._gridsopt[i]; } } this.p.initFilter = $.extend(true,{},this.p.filter); // set default values for the columns if they are not set if( !len ) {return;} for(i=0; i < len; i++) { cl = this.p.columns[i]; if( cl.stype ) { // grid compatibility cl.inputtype = cl.stype; } else if(!cl.inputtype) { cl.inputtype = 'text'; } if( cl.sorttype ) { // grid compatibility cl.searchtype = cl.sorttype; } else if (!cl.searchtype) { cl.searchtype = 'string'; } if(cl.hidden === undefined) { // jqGrid compatibility cl.hidden = false; } if(!cl.label) { cl.label = cl.name; } if(cl.index) { cl.name = cl.index; } if(!cl.hasOwnProperty('searchoptions')) { cl.searchoptions = {}; } if(!cl.hasOwnProperty('searchrules')) { cl.searchrules = {}; } } if(this.p.showQuery) { $(this).append("<table class='queryresult ui-widget ui-widget-content' style='display:block;max-width:440px;border:0px none;'><tbody><tr><td class='query'></td></tr></tbody></table>"); } /* *Perform checking. * */ var checkData = function(val, colModelItem) { var ret = [true,""]; if($.isFunction(colModelItem.searchrules)) { ret = colModelItem.searchrules(val, colModelItem); } else if($.jgrid && $.jgrid.checkValues) { try { ret = $.jgrid.checkValues(val, -1, null, colModelItem.searchrules, colModelItem.label); } catch (e) {} } if(ret && ret.length && ret[0] === false) { p.error = !ret[0]; p.errmsg = ret[1]; } }; /* moving to common randId = function() { return Math.floor(Math.random()*10000).toString(); }; */ this.onchange = function ( ){ // clear any error this.p.error = false; this.p.errmsg=""; return $.isFunction(this.p.onChange) ? this.p.onChange.call( this, this.p ) : false; }; /* * Redrow the filter every time when new field is added/deleted * and field is changed */ this.reDraw = function() { $("table.group:first",this).remove(); var t = this.createTableForGroup(p.filter, null); $(this).append(t); }; /* * Creates a grouping data for the filter * @param group - object * @param parentgroup - object */ this.createTableForGroup = function(group, parentgroup) { var that = this, i; // this table will hold all the group (tables) and rules (rows) var table = $("<table class='group ui-widget ui-widget-content' style='border:0px none;'><tbody></tbody></table>"); // create error message row if(parentgroup === null) { $(table).append("<tr class='error' style='display:none;'><th colspan='5' class='ui-state-error' align='left'></th></tr>"); } var tr = $("<tr></tr>"); $(table).append(tr); // this header will hold the group operator type and group action buttons for // creating subgroup "+ {}", creating rule "+" or deleting the group "-" var th = $("<th colspan='5' align='left'></th>"); tr.append(th); // dropdown for: choosing group operator type var groupOpSelect = $("<select class='opsel'></select>"); th.append(groupOpSelect); // populate dropdown with all posible group operators: or, and var str= "", selected; for (i = 0; i < p.groupOps.length; i++) { selected = group.groupOp === that.p.groupOps[i] ? " selected='selected'" :""; str += "<option value='"+that.p.groupOps[i]+"'" + selected+">"+that.p.groupOps[i]+"</option>"; } groupOpSelect .append(str) .bind('change',function() { group.groupOp = $(groupOpSelect).val(); that.onchange(); // signals that the filter has changed }); // button for adding a new subgroup var inputAddSubgroup ="<span></span>"; if(this.p.groupButton) { inputAddSubgroup = $("<input type='button' value='+ {}' title='Add subgroup' class='add-group'/>"); inputAddSubgroup.bind('click',function() { if (group.groups === undefined ) { group.groups = []; } group.groups.push({ groupOp: p.groupOps[0], rules: [], groups: [] }); // adding a new group that.reDraw(); // the html has changed, force reDraw that.onchange(); // signals that the filter has changed return false; }); } th.append(inputAddSubgroup); // button for adding a new rule var inputAddRule = $("<input type='button' value='+' title='Add rule' class='add-rule ui-add'/>"), cm; inputAddRule.bind('click',function() { //if(!group) { group = {};} if (group.rules === undefined) { group.rules = []; } for (i = 0; i < that.p.columns.length; i++) { // but show only serchable and serchhidden = true fields var searchable = (typeof that.p.columns[i].search === 'undefined') ? true: that.p.columns[i].search , hidden = (that.p.columns[i].hidden === true), ignoreHiding = (that.p.columns[i].searchoptions.searchhidden === true); if ((ignoreHiding && searchable) || (searchable && !hidden)) { cm = that.p.columns[i]; break; } } var opr; if( cm.searchoptions.sopt ) {opr = cm.searchoptions.sopt;} else if(that.p.sopt) { opr= that.p.sopt; } else if (cm.searchtype === 'string') {opr = that.p.stropts;} else {opr = that.p.numopts;} group.rules.push({ field: cm.name, op: opr[0], data: "" }); // adding a new rule that.reDraw(); // the html has changed, force reDraw // for the moment no change have been made to the rule, so // this will not trigger onchange event return false; }); th.append(inputAddRule); // button for delete the group if (parentgroup !== null) { // ignore the first group var inputDeleteGroup = $("<input type='button' value='-' title='Delete group' class='delete-group'/>"); th.append(inputDeleteGroup); inputDeleteGroup.bind('click',function() { // remove group from parent for (i = 0; i < parentgroup.groups.length; i++) { if (parentgroup.groups[i] === group) { parentgroup.groups.splice(i, 1); break; } } that.reDraw(); // the html has changed, force reDraw that.onchange(); // signals that the filter has changed return false; }); } // append subgroup rows if (group.groups !== undefined) { for (i = 0; i < group.groups.length; i++) { var trHolderForSubgroup = $("<tr></tr>"); table.append(trHolderForSubgroup); var tdFirstHolderForSubgroup = $("<td class='first'></td>"); trHolderForSubgroup.append(tdFirstHolderForSubgroup); var tdMainHolderForSubgroup = $("<td colspan='4'></td>"); tdMainHolderForSubgroup.append(this.createTableForGroup(group.groups[i], group)); trHolderForSubgroup.append(tdMainHolderForSubgroup); } } if(group.groupOp === undefined) { group.groupOp = that.p.groupOps[0]; } // append rules rows if (group.rules !== undefined) { for (i = 0; i < group.rules.length; i++) { table.append( this.createTableRowForRule(group.rules[i], group) ); } } return table; }; /* * Create the rule data for the filter */ this.createTableRowForRule = function(rule, group ) { // save current entity in a variable so that it could // be referenced in anonimous method calls var that=this, tr = $("<tr></tr>"), //document.createElement("tr"), // first column used for padding //tdFirstHolderForRule = document.createElement("td"), i, op, trpar, cm, str="", selected; //tdFirstHolderForRule.setAttribute("class", "first"); tr.append("<td class='first'></td>"); // create field container var ruleFieldTd = $("<td class='columns'></td>"); tr.append(ruleFieldTd); // dropdown for: choosing field var ruleFieldSelect = $("<select></select>"); ruleFieldTd.append(ruleFieldSelect); ruleFieldSelect.bind('change',function() { rule.field = $(ruleFieldSelect).val(); trpar = $(this).parents("tr:first"); for (i=0;i<that.p.columns.length;i++) { if(that.p.columns[i].name === rule.field) { cm = that.p.columns[i]; break; } } if(!cm) {return;} cm.searchoptions.id = $.jgrid.randId(); if(isIE && cm.inputtype === "text") { if(!cm.searchoptions.size) { cm.searchoptions.size = 10; } } var elm = $.jgrid.createEl(cm.inputtype,cm.searchoptions, "", true, that.p.ajaxSelectOptions, true); $(elm).addClass("input-elm"); //that.createElement(rule, ""); if( cm.searchoptions.sopt ) {op = cm.searchoptions.sopt;} else if(that.p.sopt) { op= that.p.sopt; } else if (cm.searchtype === 'string') {op = that.p.stropts;} else {op = that.p.numopts;} // operators var s ="",so=""; if (that.p.ops.indexOf(rule.op) == -1) rule.op = op[0]; for ( i = 0; i < that.p.ops.length; i++) { if($.inArray(that.p.ops[i].name, op) !== -1) { so = rule.op === that.p.ops[i].name ? " selected=selected" : ""; s += "<option value='"+that.p.ops[i].name+"'"+ so+">"+that.p.ops[i].description+"</option>"; } } $(".selectopts",trpar).empty().append( s ); // data $(".data",trpar).empty().append( elm ); $(".input-elm",trpar).bind('change',function() { rule.data = $(this).val(); if($.isArray(rule.data)) { rule.data = rule.data.join(","); } that.onchange(); // signals that the filter has changed }); setTimeout(function(){ //IE, Opera, Chrome rule.data = $(elm).val(); that.onchange(); // signals that the filter has changed }, 0); }); // populate drop down with user provided column definitions var j=0; for (i = 0; i < that.p.columns.length; i++) { // but show only serchable and serchhidden = true fields var searchable = (typeof that.p.columns[i].search === 'undefined') ? true: that.p.columns[i].search , hidden = (that.p.columns[i].hidden === true), ignoreHiding = (that.p.columns[i].searchoptions.searchhidden === true); if ((ignoreHiding && searchable) || (searchable && !hidden)) { selected = ""; if(rule.field === that.p.columns[i].name) { selected = " selected='selected'"; j=i; } str += "<option value='"+that.p.columns[i].name+"'" +selected+">"+that.p.columns[i].label+"</option>"; } } ruleFieldSelect.append( str ); // create operator container var ruleOperatorTd = $("<td class='operators'></td>"); tr.append(ruleOperatorTd); cm = p.columns[j]; // create it here so it can be referentiated in the onchange event //var RD = that.createElement(rule, rule.data); cm.searchoptions.id = $.jgrid.randId(); if(isIE && cm.inputtype === "text") { if(!cm.searchoptions.size) { cm.searchoptions.size = 10; } } var ruleDataInput = $.jgrid.createEl(cm.inputtype,cm.searchoptions, rule.data, true, that.p.ajaxSelectOptions, true); // dropdown for: choosing operator var ruleOperatorSelect = $("<select class='selectopts'></select>"); ruleOperatorTd.append(ruleOperatorSelect); ruleOperatorSelect.bind('change',function() { rule.op = $(ruleOperatorSelect).val(); trpar = $(this).parents("tr:first"); var rd = $(".input-elm",trpar)[0]; if (rule.op === "nu" || rule.op === "nn") { // disable for operator "is null" and "is not null" rule.data = ""; rd.value = ""; rd.setAttribute("readonly", "true"); rd.setAttribute("disabled", "true"); } else { rd.removeAttribute("readonly"); rd.removeAttribute("disabled"); } that.onchange(); // signals that the filter has changed }); // populate drop down with all available operators if( cm.searchoptions.sopt ) {op = cm.searchoptions.sopt;} else if(that.p.sopt) { op= that.p.sopt; } else if (cm.searchtype === 'string') {op = p.stropts;} else {op = that.p.numopts;} str=""; for ( i = 0; i < that.p.ops.length; i++) { if($.inArray(that.p.ops[i].name, op) !== -1) { selected = rule.op === that.p.ops[i].name ? " selected='selected'" : ""; str += "<option value='"+that.p.ops[i].name+"'"+selected+">"+that.p.ops[i].description+"</option>"; } } ruleOperatorSelect.append( str ); // create data container var ruleDataTd = $("<td class='data'></td>"); tr.append(ruleDataTd); // textbox for: data // is created previously //ruleDataInput.setAttribute("type", "text"); ruleDataTd.append(ruleDataInput); $(ruleDataInput) .addClass("input-elm") .bind('change', function() { rule.data = $(this).val(); if($.isArray(rule.data)) { rule.data = rule.data.join(","); } that.onchange(); // signals that the filter has changed }); // create action container var ruleDeleteTd = $("<td></td>"); tr.append(ruleDeleteTd); // create button for: delete rule var ruleDeleteInput = $("<input type='button' value='-' title='Delete rule' class='delete-rule ui-del'/>"); ruleDeleteTd.append(ruleDeleteInput); //$(ruleDeleteInput).html("").height(20).width(30).button({icons: { primary: "ui-icon-minus", text:false}}); ruleDeleteInput.bind('click',function() { // remove rule from group for (i = 0; i < group.rules.length; i++) { if (group.rules[i] === rule) { group.rules.splice(i, 1); break; } } that.reDraw(); // the html has changed, force reDraw that.onchange(); // signals that the filter has changed return false; }); return tr; }; this.getStringForGroup = function(group) { var s = "(", index; if (group.groups !== undefined) { for (index = 0; index < group.groups.length; index++) { if (s.length > 1) { s += " " + group.groupOp + " "; } try { s += this.getStringForGroup(group.groups[index]); } catch (eg) {alert(eg);} } } if (group.rules !== undefined) { try{ for (index = 0; index < group.rules.length; index++) { if (s.length > 1) { s += " " + group.groupOp + " "; } s += this.getStringForRule(group.rules[index]); } } catch (e) {alert(e);} } s += ")"; if (s === "()") { return ""; // ignore groups that don't have rules } else { return s; } }; this.getStringForRule = function(rule) { var opUF = "",opC="", i, cm, ret, val, numtypes = ['int', 'integer', 'float', 'number', 'currency']; // jqGrid for (i = 0; i < this.p.ops.length; i++) { if (this.p.ops[i].name === rule.op) { opUF = this.p.ops[i].operator; opC = this.p.ops[i].name; break; } } for (i=0; i<this.p.columns.length; i++) { if(this.p.columns[i].name === rule.field) { cm = this.p.columns[i]; break; } } val = rule.data; if(opC === 'bw' || opC === 'bn') { val = val+"%"; } if(opC === 'ew' || opC === 'en') { val = "%"+val; } if(opC === 'cn' || opC === 'nc') { val = "%"+val+"%"; } if(opC === 'in' || opC === 'ni') { val = " ("+val+")"; } if(p.errorcheck) { checkData(rule.data, cm); } if($.inArray(cm.searchtype, numtypes) !== -1 || opC === 'nn' || opC === 'nu') { ret = rule.field + " " + opUF + " " + val; } else { ret = rule.field + " " + opUF + " \"" + val + "\""; } return ret; }; this.resetFilter = function () { this.p.filter = $.extend(true,{},this.p.initFilter); this.reDraw(); this.onchange(); }; this.hideError = function() { $("th.ui-state-error", this).html(""); $("tr.error", this).hide(); }; this.showError = function() { $("th.ui-state-error", this).html(this.p.errmsg); $("tr.error", this).show(); }; this.toUserFriendlyString = function() { return this.getStringForGroup(p.filter); }; this.toString = function() { // this will obtain a string that can be used to match an item. var that = this; function getStringRule(rule) { if(that.p.errorcheck) { var i, cm; for (i=0; i<that.p.columns.length; i++) { if(that.p.columns[i].name === rule.field) { cm = that.p.columns[i]; break; } } if(cm) {checkData(rule.data, cm);} } return rule.op + "(item." + rule.field + ",'" + rule.data + "')"; } function getStringForGroup(group) { var s = "(", index; if (group.groups !== undefined) { for (index = 0; index < group.groups.length; index++) { if (s.length > 1) { if (group.groupOp === "OR") { s += " || "; } else { s += " && "; } } s += getStringForGroup(group.groups[index]); } } if (group.rules !== undefined) { for (index = 0; index < group.rules.length; index++) { if (s.length > 1) { if (group.groupOp === "OR") { s += " || "; } else { s += " && "; } } s += getStringRule(group.rules[index]); } } s += ")"; if (s === "()") { return ""; // ignore groups that don't have rules } else { return s; } } return getStringForGroup(this.p.filter); }; // Here we init the filter this.reDraw(); if(this.p.showQuery) { this.onchange(); } // mark is as created so that it will not be created twice on this element this.filter = true; }); }; $.extend($.fn.jqFilter,{ /* * Return SQL like string. Can be used directly */ toSQLString : function() { var s =""; this.each(function(){ s = this.toUserFriendlyString(); }); return s; }, /* * Return filter data as object. */ filterData : function() { var s; this.each(function(){ s = this.p.filter; }); return s; }, getParameter : function (param) { if(param !== undefined) { if (this.p.hasOwnProperty(param) ) { return this.p[param]; } } return this.p; }, resetFilter: function() { return this.each(function(){ this.resetFilter(); }); }, addFilter: function (pfilter) { if (typeof pfilter === "string") { pfilter = jQuery.jgrid.parse( pfilter ); } this.each(function(){ this.p.filter = pfilter; this.reDraw(); this.onchange(); }); } }); })(jQuery);