JQGrid: How to set a cell style based on content - jqgrid

I want to set a cell's background color based on the contents of the cell.
My first question: is there a way to set a cell's background color from within the xml data?
If not, here is my grid definition:
$("#grid_sites").jqGrid({
url:"getgridxmlsites.php?detailid=" + $('#hdnStudyDetailId').val(),
datatype: "local",
height: 160,
width: 832,
shrinkToFit: true,
caption:"",
colNames :["Site","Name","PI","Location","Phone","Status"],
colModel :[
{name:"sitenumber", index:"sitenumber", width:50, align:"right"},
{name:"name", index:"name", width:120},
{name:"location", index:"location", width:100},
{name:"phone", index:"phone", width:100},
{name:"status", index:"status", width:70}
],
pager:"pager_sites",
scroll: 1,
viewrecords:true,
sortable:true,
sortname: "sitenumber",
autowidth: true,
pgbuttons: false,
loadonce: true,
gridview: true
});
I want to change the background color of the status cell based on its contents.
I know I should probably use a formatter on the status column, but I'm not sure of the code to change just the background color for that cell.
{name:"status", index:"status", width:70, formatter: statusFormatter}
function statusFormatter(cellvalue, options, rowObject)
{
What exactly would go here for something like this:
if (cellValue == 'Pending') change the cell's background color to yellow
else if (cellValue == 'Approved') change the cells's background color to green;
}
Thanks!

There are exist many ways to do what you want. In the answer you would find an example how to use custom formatter to change the background color of the cell based on its contents. The answer is written before cellattr attribute are introduced. The main purpose of the custom formatter is to create the HTML contain of the cell based on the data of the cell.
The cellattr attribute introduced as modification of my feature request have advantage because it allows only set/modify attributes of the HTML code of the cell and use some predefined formatter like 'number' or 'select'. So you can just set class or style attribute and use at the same time some predefined formatter which corresponds the data contain. Look at this answer which shows how to set dynamically background-color over class and another answer which shows how to set it over style.
The answer discuss additionally advantages and disadvantages of the both approaches.
One more remark to your code. I don't recommend you to use url parameter in the form
url:"getgridxmlsites.php?detailid=" + $('#hdnStudyDetailId').val()
It has two important disadvantages. First, the $('#hdnStudyDetailId').val() could be send and decoded on the server in the wrong way if the contain of $('#hdnStudyDetailId').val() contain some special characters (' ', '+', '=', 'ä', 'д', '電', ...). The second problem is that the value from the '#hdnStudyDetailId' will be read only once at the time of the grid creation. So on any refreshing of the grid contain like sorting by another column, paging and so on the same old value from the '#hdnStudyDetailId' element will be used. I recommend you to read the answer and to use URL with respect of url and postData parameters:
url: "getgridxmlsites.php",
postData: {
detailid: function() { return $('#hdnStudyDetailId').val(); }
}

Related

Jqgrid using cellattr to toggle a class on seperate cell

in my col model i have two cells 'Status' and 'HiddenStatus'. The reason for this is 'Status' is translatable so this way is better rather than checking the value for each language. As you can see below i am attempting to set the class of the 'Status' cell based on the value of the 'HiddenStatus' cell. However this is not working as i hoped since the class is not being set correctly.
I believe the issue i am having is, 'getCell' is used to return the value rather than an object. How can i get the cell as an object so i can then manage what class i add or remove.
{name: 'Status', width: 70, index: 'Status'},
{name: 'HiddenStatus', width: 70, hidden: true, cellattr : function(rowId, cellValue, rawObject, cm, rdata){
var statusCell = $(this).jqGrid('getCell',rowId,'Status');
if(cellValue != "Assigned"){
$(statusCell).removeClass('status-assigned');
return '';
}
if(cellValue == "Assigned"){
$(statusCell).addClass('status-assigned');
return '';
}
}},
First of all, it's important to understand what cellattr do. Any changes on the existing page are expensive. Thus jqGrid try to build the whole HTML fragment with the table body as one long string. Every column will be used to build the cells (<td> elements) of the corresponding columns of the grid. The callback cellattr will be called during building the cell and can be used to set attributes on the cell. The cellattr callback have to return the string. If it returns, for example, " class='status-assigned'" then the <td> will have the class (<td class='status-assigned'>...</td>).
The callback cellattr will be called before the grid will be created. Thus one can't access to the grid using $(this).jqGrid('getCell',rowId,'Status'), for example.
If you need to set class status-assigned conditionally on the cells of the column Status then you should define cellattr callback in the column Status. Inside the callback you can use rawObject.HiddenStatus or rdata.HiddenStatus. One don't need typically to create hidden columns like HiddenStatus. Instead of that, it's enough to use include all properties of input data, which one need, in additionalProperties option of jqGrid. For example, additionalProperties: ["HiddenStatus"].
Your original code could be modified to the following:
{
name: 'Status', width: 70,
cellattr: function (rowId, cellValue, item) {
if (item.HiddenStatus === "Assigned") {
return " class='status-assigned'";
}
}
}
See the old answer for an example of usage cellattr.

how to save the width of jqgrid columns permanently at the time of re-sizing (re-size )?

i want to save the width of coumns of jqgrid, when user re-size the column the width should be saved, so next time when user open the page the width should be the same user did. is it possible?
js code
{ name: 'FirstName', index: 'FirstName', width:100, align: "left", sorttype: 'text', resizable: true, editable: true, editrules: { required: true } },
i have tried shrinkToFit:false, autowidth:false
any idea, any suggestion will be appreciated...i will mark it as answer if it works for me
thank. if you need any extra information about the code i am here to explain..just comment ;)
jqGrid don't provide any API to change the column width after the grid been created, but I created the plugin which do this. You can download jQuery.jqGrid.setColWidth.js from here, included it after jqGrid JavaScript files and then you can just use new setColWidth method in the form
$("#grid").jqGrid("setColWidth", colNameIrIndex, newWidth);
The method setColWidth will adjust the total grid width after changing the width of the column. If you don't need it you ca add false as an additional last parameter of setColWidth:
$("#grid").jqGrid("setColWidth", colNameIrIndex, newWidth, false);
Additional details about the method you will find in the answer and in this one.
Probably you can write your code so that the width of columns will be set before the grid will be created. In the case you will don't nee the method setColWidth. For example you can try the demo from the answer (see the previous answer too). If you changes the width of some column and then reload the full page you will see that the grid will be created using the widths of column which the used made at the last time. Is it not close to your requirements?

jqGrid Custom Formatter Set Cell wont work with options.rowId

Ive been through all the posts, finally got setCell to work with hardcoded values, but not using the options.rowId.
function StatusFormatter(cellvalue, options, rowObject) {
if (cellvalue == 'C'){
jQuery("#list").setCell(options.rowId , 'SOORDLINE', '', { color: 'red' });
jQuery("#list").setCell("[2.000]", 'SOORDLINE', '', { color: 'red' });
jQuery("#list").setCell('[2.000]', 'SOREQDATE', '', { color: 'red' });
jQuery("#list").setCell(options.rowId, 'SOPRICE', '', { color: 'red' });
}
return cellvalue;
};
The FIRST and LAST lines dont work, but the 2 with the hardcoded rowId DO work. I inspected what comes back in the option.rowId and they are the same as the hardcoded values, (just different depending on the row of course. What am I missing? Please help. I dont see any difference between the lines, or values.
EDITED-
I tried the answer, and it seems to be what I need. I tried the following
{ name: 'SOORDLINE', index: 'SOORDLINE', width: 25, search: false ,celattr: function () { return ' style="color: red"'; }
},
To aleast make them all red before I dove into the logic, and it didnt do anything for me.
Sorry, but you use custom formatter in absolute wrong way. The goal of the custom formatter to to provide HTML fragment to fill the content of the cells in the corresponding column. So the StatusFormatter will be called before the row with the id equal to options.rowId will be created. Moreover for performance purpose one use typically gridview: true. in the case the whole content of the grid (the whole body of the grid) will be constructed first as string and only after that will be placed in the grid body in one operation. It improve the performance because after placing of any element web browser have to recalculate position of all other elements on the page.
If you want to set text color on the SOORDLINE cell you should cellattr instead:
celattr: function () { return ' style="color: red"'; }
The celattr can be used also in the form celattr: function (rowId, cellValue, rawObject) {...} and you can test the property of rawObject which represent of the values for any column and return the cell style based on the cell value.
Alternatively you can enumerate the rows inside of loadComplete and set the style on <tr> element instead of setting the same styles for every row. See the answer as an example.

jqgrid filterToolbar search input size

I'm starting to use filtertoolbar: myGrid.jqGrid('filterToolbar', {stringResult: true, searchOnEnter: false, defaultSearch : "cn"});
My question Is If I can control the search inputs size -
UPDATE: It's height and width size .
Thank's In Advance.
If I understand you correct you should include in colModel in the definition of the column which input size you want to restrict the option like
searchoptions:{ attr: {maxlength: 5}}
In the example in the corresponding input field of the searching toolbar will be allowed to type not more as five characters.
UPDATED: I don't understand why you need such behavior, but you can use dataInit of the searchoptions to set height and width of the input control. To do this you can use either jQuery.css or jQuery.height and jQuery.width methods:
searchoptions:{
attr: {maxlength: 5},
dataInit: function(elem) {
//$(elem).css({height:"30px", width:"40px"});
$(elem).height(30).width(40);
}
}
If you increase the height of the control in the searching toolbar you should change additionally
var myGrid = $("#list");
// ...
var $search_toolbar = $("tr.ui-search-toolbar", myGrid[0].grid.hDiv);
$search_toolbar.height(30);
You should do this of course after the call of filterToolbar which create the searching toolbar.
See small demo here.

JQGrid filterToolbar

I have been stuck on this problem for past 2 days. Did lot of googling but was not able to find the exact answer.
Following is the JQGrid definition
$("#tblresults").jqGrid({
datastr: data,
datatype: 'jsonstring',
height: 230,
colNames: colNames,
colModel: colModel,
rowNum: -1,
viewrecords: true,
loadComplete: function() {
ChangeSize('#tblresults', 70);
}
});
And this is the filter definition
$("#tblresults").filterToolbar({ searchOnEnter: true, stringResult: true, defaultSearch: "cn", groupOp: "AND" });
I get the data from a simple getJSON call. But when I try to use the filter nothing works.
I debugged a the code and found out that jqgrid internally calls the reloadgrid, which makes the data to disappear.
Can anyone tell me how can we do filtering in jqgrid completely on client.
I am using v3.8 and I learnt that jqgrid v3.7 had this client side filtering logic in place.
Thanks in Advance
Do you have the data First of all you should not use -1 as the value of rowNum. Instead of that use any reliable value like rowNum:1000. More better would be to use local data paging. In the case you should just set for example rowNum:10, rowList:[5,10,20,100].
If you get the input parameters colNames, colModel and data parameters of jqGrid from the server per ajax call you should additionally consider to use data parameter instead of datastr. In the case the datatype should be changed from 'jsonstring' to 'local'.
Some other common parameters like gridview:true and height:'100%' can be also usefull for you. The first one (gridview:true) just improve the performance without any disadvantages and the second (height:'100%') will follow to choosing of the optimal grid height without the vertical scroll bar. It can be good combined with the local data paging (parameters like rowNum:10, rowList:[5,10,20,100]).
add these parameters and your toolbar search should work. i have faced similar problem too when started with jqgrid.
search:true,
loadonce:true,

Resources