I would like to alter the search filters after a user has submitted them. Normally jqGrid returns name in colmodel as the value for field, I would like to change this behavior for a specific column:
I would like to change:
{"groupOp":"AND","rules":[{"field":"available","op":"eq","data":"true"}]}
to
{"groupOp":"AND","rules":[{"field":"s.trait.available","op":"eq","data":"true"}]}
I have tried altering the submitted form in the ways below; firebug shows that the functions are never being called.
var searchOptions = {
multipleSearch:true, multipleGroup:false, closeOnEscape:true, closeAfterSearch:true,
sopt:['ge', 'eq', 'le'],
beforeSubmit:function (params, postdata) {
//alterations would be here
}
,
onclickSubmit:function (params, postdata) {
//alterations would be here
}
}
This approach works for editOptions and delOptions, I am not sure why I cannot get this to work for searching.
If you use the searching toolbar you can use beforeSearch callback to modify the postData.filter. In case of Singe Field searching or Advanced Searching you can use onSearch.
In the answer you can see how the postData.filter can be modified.
UPDATED: You did something wrong in your tests. The only problem is that the current implementation of searching don't initialize this to the grid, but it's not explicitly documented somewhere.
I created the demo for you which demonstrate that you do can modify the filter before relaoding of the grid will be started. If you would search in the grid for 'Client' equal to 300 the search request will be modified to 'amount' equal to 300 and you would see the results
The corresponding code is
$('#list').jqGrid('navGrid', '#pager', {add: false, edit: false, del: false}, {}, {}, {},
{
multipleSearch: true,
overlay: 0,
onSearch: function () {
var i, l, rules, rule, $grid = $('#list'),
postData = $grid.jqGrid('getGridParam', 'postData'),
filters = $.parseJSON(postData.filters);
if (filters && typeof filters.rules !== 'undefined' && filters.rules.length > 0) {
rules = filters.rules;
for (i = 0; i < rules.length; i++) {
rule = rules[i];
if (rule.field === 'name') {
// make modifications only for the 'contains' operation
rule.field = 'amount';
}
}
postData.filters = JSON.stringify(filters);
}
}});
Related
I am new to the JQGRID, I need to format jqgrid based on certain values, lets say if the "NAME" column contains value of "HEMA" and "RAJU" then their respective row should contain the value of n/a (meaning their gender, mobile, location , country should be n/a). I am stuck as I could not figure out how to approach this problem in jqgrid. Guidance will be highly appreciated. I have attached image for clear explanation.
I did some searching but could not find anything closest I could find was formatter but did not work.
var url = "test/gridresult";
$(function(){
("#result").jqGrid({
url:url,
datatype: "jsonstring",
multiselect:false,
colNames:['Id','NAME', 'GENDER', 'MOBILE','LOCATION','COUNTRY'],
colModel:[
{name:'id',index:'id', resizable:true},
{name:'name',index:'name', resizable:true},
{name:'mobile',index:'mobile', resizable:true},
{name:'country',index:'country', resizable:true},
],
rowNum:100,
pager: '#prowed1',
sortname: 'id',
loadonce: true,
sortorder: "desc",
jsonReader;{
repeatitem:false,
root:"rows",
page:"page",
records:"records",
cell:""
}
});
});
this seems working, I am getting name from loop but how do I set n/a in a row for that particular name
var rows = $("#result").jqGrid('getDataIDs');
for (var i = 0; i < rows.length; i++)
{
var status = $("#resultTable2").getCell(rows[i],"NAME");
alert("initial value "+status);
if(status == "HEMA")
{
//need to set value of n/a for row that belongs to HEMA
}
}
<!-- begin snippet: js hide: false console: true babel: false -->
demo pic for my question
Guys I was able to fix it using formatter. Spent good amount of time and finally got it fixed.
function valFormat( cellvalue, options, rowObject ){
var val;
if(rowObject.name=='HEMA' ){
val='N/A';
}else{
val=cellvalue;
}
return val;
}
and in the jqgrid:
{name:'name',index:'name', resizable:true, formatter:valFormat},
I have handsontable and I don't know what event that I need to validate a specific cell if its empty or not.
technically I have specific cell to be a required cell, if the cell is empty then it will call a callback or return false after executing a post.
I have used beforeChange() function before and I think it is not appropriate event for the issue.
Here's an image link.
What you want to do is use the validator option in the columns setting.
Here is some more information on validators and an example but below is the code that would go with it.
emptyValidator = function(value, callback) {
if (isEmpty(value)) { // isEmpty is a function that determines emptiness, you should define it
callback(false);
} else {
callback(true);
}
}
Then in the columns setting, supply each column and if that column should have all its cells be non-empty, supply this as the validator, just like they show in the handonstable example page.
Here is my work around: http://jsfiddle.net/Yulinwu/s6p39uje/
Firstly, you can add a custom property named required to the column settings.
hot = new Handsontable(container, {
...
columns: [{
...
}, {
type: 'numeric',
format: '$ 0,0.00',
required: true, // Add a new setting named required
validator: Handsontable.NumericValidator
}]
});
Then, you can add a listener to beforeValidate event using addHook, which returns false if a cell is required but empty.
hot.addHook('beforeValidate', function(value, row, prop, source) {
var ifRequired = this.getCellMeta(row, prop).required;
console.log(ifRequired);
if (ifRequired && value === '') {
return false
} else {
return 0
}
});
Use allowEmpty:false for that column like:-
{
data: 'EmpNo',
type: 'numeric',
allowInvalid: false,
allowEmpty:false
}
And in the setting of handsontable use afterValidate as below-
afterValidate: function (isValid, value, row, prop, source) {
if (!isValid) {
$("#submitBtn").prop("disabled", true);
alert('Only non empty numbers are allowed');
}
else {
$("#submitBtn").prop("disabled", false);
}
}
Please guide me on a work around for having a set of columns frozen and the rest having cell edit feature along with column reordering/ show- hide options using jqgrid.
Thank You.
Please try this, simple solution,
Hide or remove cellEdit: true
Then add the below lines in above and below the setFrozenColumns
Previous code:
$("#jqGrid2").jqGrid('setFrozenColumns');
New Code:
$("#jqGrid2").jqGrid("setGridParam", {cellEdit: false, sortable: false});
$("#jqGrid2").jqGrid('setFrozenColumns');
$("#jqGrid2").jqGrid("setGridParam", {cellEdit: true, sortable: true});
The problem is that the current implementation of setFrozenColumns have some restrictions. Editing (in any editing mode) and sortable: true is not allowed for frozen columns, but setFrozenColumns. Moreover sortable: true should don't allow to resort headers of frozen columns. On the other side setFrozenColumns contains simple test of some parameters (see here) and the method do nothing if some such parameters (like cellEdit or sortable) are set.
I suggested in the post (with the demo) the way how to implement a workaround. The way is modification of approach from the answer and this one.
I find your question interesting and so I created the demo which demonstrates how one do can implement your requirements. It displays the following results (animated gif):
It uses mostly the following code
// create the grid
$grid.jqGrid({
...
});
$grid.bind("jqGridLoadComplete jqGridInlineEditRow jqGridAfterEditCell jqGridAfterRestoreCell jqGridInlineAfterRestoreRow jqGridAfterSaveCell jqGridInlineAfterSaveRow", function () {
fixPositionsOfFrozenDivs.call(this);
});
$grid.jqGrid("setGridParam", {cellEdit: false, sortable: false});
$grid.jqGrid("setFrozenColumns");
$grid.jqGrid("setGridParam", {cellEdit: true, sortable: true});
fixPositionsOfFrozenDivs.call($grid[0]);
try {
var p = $grid.jqGrid("getGridParam"), tid = $.jgrid.jqID(p.id), colModel = p.colModel, i, n = colModel.length, cm,
skipIds = [];
for (i = 0; i < n; i++) {
cm = colModel[i];
if ($.inArray(cm.name, ["cb", "rn", "subgrid"]) >=0 || cm.frozen) {
skipIds.push("#jqgh_" + tid + "_" + $.jgrid.jqID(cm.name));
}
}
$grid.jqGrid("setGridParam", {sortable: {options: {
items: skipIds.length > 0 ? ">th:not(:has(" + skipIds.join(",") + "),:hidden)" : ">th:not(:hidden)"
}}});
$grid.jqGrid("sortableColumns", $($grid[0].grid.hDiv).find(".ui-jqgrid-labels"));
} catch (e) {}
colModel: [
{ name: 'Id', index: 'Id', hidden: true, search: false },
{ name: 'Name', index: 'Name', hidden: true, search: false },
]
Just as the setSelection method allows selection of a row in jqGrid based on the row number, is it possible to similarly select a row based on one of the cell values.
For e.g. in the colModel above, is it possible to select a row having a certain 'Id' or 'Name' value...assuming that these values are unique for each row.
In the loadComplete: portion of your jqGrid you could iterate over each row and test for the value you are looking for. If the value is found, select the row.
Ex
loadComplete: function () {
var rowIds = $(this).jqGrid('getDataIDs');
for (i = 1; i <= rowIds.length; i++) {
rowData = $(this).jqGrid('getRowData', i);
if (rowData['Id'] == idSearchValue ) {
$(this).jqGrid('setSelection',i);
} //if
} //for
...
There would also be the rowattr: but I can't seem to find where you can get the rowID of the current row. Oleg might see this and respond as well as it was his addition to jqGrid but I didn't have any luck with my testing or read though of where you would get the current rowId to pass to the setSelection method.
If you have an array of objects containing cells values, you will need another approach.
Eg. with your colModel, you would like to retrieve rows with these values:
let toSearch = [
{ Name: 'Arthur', Id: 150},
{ Name: 'Julien', Id: 90},
]
Then what you can do is to retrieve the whole data from the jqGrid table and seek after values dynamically:
let data = $grid.jqGrid('getGridParam', 'data');
let toSelect = data.filter((row,i) => {
return toSearch.some(toSelectRow => {
for(let prop in prevRow) {
if(prevRow[prop] != row[prop])
return false;
}
return true;
})
});
toSelect.forEach((row) => $grid.jqGrid('setSelection',row.id, false)); // Prevent firing onSelectRow event
Here we pass false to prevent from firing onSelectRow event, if you need it just remove false
I have a PHP-script to handle the AJAX-Requests of many different jqGrid's.
I generate the "ORDER BY" statement with the 'sidx' and 'sord' parameters and the "LIMIT" statement with the 'page' and 'rows' parameters.
Similar to the PHP-example here.
The problem is, that in the PHP-script I can not determine if the loadonce-parameter of the current jqGrid is set or not.
But only if it is not set, I have to filter the returned data (LIMIT by page and rows).
How can I force jqGrid to send an additional parameter?
I dont want to change all my Grids. Is there a global way of doing it?
------ EDIT ------
With the help from this answers (here and here) i got this now.
$.extend($.jgrid.defaults, {
postData: {
loadingType: function() {
var isLoadonce = $("#list1").jqGrid('getGridParam', 'loadonce');
console.log('isLoadonce: ' + isLoadonce);
return isLoadonce ? 'loadAll' : 'loadChunk';
},
},
});
This works, if the Grid has the ID "list1". How can I reference the current Grid without ID?
------ EDIT 2 ------
This seems to work. It looks to me a bit like a hack. Is there a better way?
$.extend($.jgrid.defaults, {
serializeGridData: function(postData) {
var isLoadonce = $(this).jqGrid('getGridParam', 'loadonce');
var newPostData = $.extend(postData, {
loadingType: isLoadonce ? 'loadAll' : 'loadChunk'
});
return $.param(newPostData);
},
});
To pass in an extra parameter you can add:
postData: { ExtraDataName: ExtraDataValue },
then whenever jqGrid goes to get data it will pass that name pair to your controller.
With serializeGridData, jqGrid provides an event to modify the data sent with the Request. The event is called in the context of the current Grid, so we can access the current Grid with this.
By exdending $.jgrid.defaults we can make all Grids sending their loadonce parameter as additional requestparameter without changing any Grid.
$.extend($.jgrid.defaults, {
serializeGridData: function(postData) {
var isLoadonce = $(this).jqGrid('getGridParam', 'loadonce');
var newPostData = $.extend(postData, {
loadingType: isLoadonce ? 'loadAll' : 'loadChunk'
});
return $.param(newPostData);
},
});