I have a column- Company in ExtJs gridPanel.
In the backend I have put a condition -
{id:'Company',header: "Company", sortable: true, dataIndex: 'comp',
renderer: function(value, cell) {
if(status='unemployed')
{ return 'n/a';}
}
Now,If the column has values like 'Apple' ,'Google','n/a','Microsoft', It is not sorting it in proper order. How should I handle 'n/a' while sorting?
I'd suggest to use just blank value for the n/a case. It would appear on the top of the list.
You can also to put a space before 'n', like ' n/a'.
Related
I have to display cell content like
Policy
Part
Cert
Separated with next line character
In slickgrid table and so on.
How can I do this?
I searched but nothing worked for me.
What should I do with this is there any way to fit contents by height.
I Have this code written for breaking cells
columnname: <p>+policy+</p><br/>+part......and so on.
Any lead will be highly appreciated.
Better register a new formatter for your column.
Example
function myformatter(row, cell, value, columnDef, dataContext) {
return "<style='text-decoration: underline;color: #669900;height:120px;'>" + value +";
}
And call myformatter into column definition
var columns = [];
columns[0] = { id: "id", name: "columnname", field: "id", sortable: true, width: 5, formatter: myformatter };
setRowData takes almost 5 seconds when the grid has 300 rows, 30 cols, and 4 frozen cols.
$("#tbl").jqGrid({
gridview: true,
url: '../controller/GetData',
datatype: "json",
rowNum: pageSize,
viewrecords: true,
loadtext: '',
loadui: 'disable',
rowList: [1000, 2000, 3000],
width: $(window).width() - LeftMargin,
shrinkToFit: false,
pager: '#dvPager',
pagerpos: 'left',
colNames: GetColNames(selectedViewName, viewCols),
colModel: GetColModel(selectedViewName, viewCols),
cmTemplate: {
title: false
},
recordtext: "Displaying {0} - {1} of {2}",
rowattr: function (rowData) {
},
//onCellSelect: function (rowid, iCol, cellcontent, e) {
// e.stopPropagation();
// proto.editcell(rowid, iCol, cellcontent, e);
//},
loadComplete: function (data) {..},
onPaging: function (data) {..},
serializeGridData: function (postData) {..}
});
Can you please guide me with the performance tuning tips?
In GetColModel we are binding columns as follows -
'Discount': {
name: 'Discount', index: 'Discount', width: colModelWidthDict['Discount'], title: false, sortable: false, resizable: colResizable, hidden: !bReadCalculationSellInfo,
formatter: function (cellValue, option, rowObject) {
if (rowObject.level == 0 || (rowObject.Flag == 0 && (rowObject.Discountable && rowObject.Discountable.toLowerCase() == 'no')))
return '';
else {
if (!proto.IsReadOnly(rowObject) && ((rowObject.Flag == 0 && (rowObject.Discountable && rowObject.Discountable.toLowerCase() == 'yes')) || rowObject.Flag > 0))
return proto.GetControls("Discount", option.rowId, "Numeric", rowObject.Discount, 6, 90)
else
return '<span class="amt">' + cellValue + '</span>';
}
},
unformat: function (cellValue, option) {
return cellValue;
},
cellattr: function (rowId, val, rowObject, cm, rdata) {
if (parseInt(rowObject.PPPChngDisc) == 1)
return ' style="color:red"';
}
}
//code for colModel - 1 column above
In general you should prefer to modify only small number of rows. If you modify one row then the web browser have to recalculate position of all other rows (500 rows) of the grid. In the case modifying 300 rows means 300*500 operations for the web browser.
If you fill the whole grid and you use gridview: true option then jqGrid places at the beginning all the data for the grid body in array of strings. After preparing of all information in string format jqGrid place the whole body of the grid as one operation. It's just one assigning innerHTML property of tbody. Thus it's more effective to reload the whole grid as to make modification of many rows of the grid in the loop using setRowData.
So I would recommend you to reload the grid in your case.
Moreover you should consider to reduce the number of rows in the page of grid. If you use rowNum: 500 you just reduce the performance of your page tin many times without any advantage for the user. The user can see about 20 rows of the data only. Only if the user scrolls he/she is able to see another information. In the same way the user could click next page button. Holding 500 rows force web browser make a lot of unneeded work. Modifying of the first row from 500 the web browser have to recalculate position of all 500 rows. Even if the user move the mouse over a row the web browser change the class of the hovering row and it have to recalculate position of all other from 500 rows event the rows are not visible.
One more remark. The implementation of frozen columns in jqGrid 4.6 is slow. Starting with the end of 2014 and publishing 4.7.1 with changing Lisanse and making jqGrid commercial I develop free jqGrid as fork based on jqGrid 4.7 (see the readme for more details). I implemented a lot of changes and new features in the fork. The recent changes includes many improvement of frozen columns feature. If you loads free jqGrid or just try it directly from GitHub by including the corresponding URLs (see the wiki) you will see that the performance of frozen columns is dramatically improved. Additionally frozen columns supports now row and cell editing in all editing modes. I plan to publish free jqGrid 4.9 soon. So I recommend you to try it.
UPDATED: You posted the code, which you use in comments below. I see the main problem in the implementation of Process function which will be called on change in the <input> fields on the grid. I recommend you to try something like this one:
function Process(contrl) {
var $cntrl = $(contrl),
$td = $cntrl.closest("tr.jqgrow>td"),
$tr = $td.parent(),
rowId = $tr.attr("id"),
newValue = $cntrl.val(),
$grid = $("#list"),
p = $grid[0].p,
colModel = p.colModel,
columnName = colModel[$td[0].cellIndex].name, // name of column of edited cell
localRowData = $grid.jqGrid("getLocalRow", rowId),
iColTotal = p.iColByName.total;
// modify local data
localRowData[columnName] = newValue;
localRowData.total = parseInt(localRowData.quantity) * parseFloat(localRowData.unit);
// modify the cell in the cell (in DOM)
//$grid.jqGrid("setCell", rowId, "total", localRowData.total);
$($tr[0].cells[iColTotal]).text(localRowData.total);
return false;
}
One can event improve the code and not use setCell at all. It's important to understand that local grid hold the data in the form of JavaScript object. The access to the data is very quickly. You can modify the data without any side effects existing with DOM elements. In the above code I use only relative search inside of the DOM of the row using closest and parent. It works very quickly. I recommend to save $("#list") in the variable outside of the Process (move var $grid = $("#list") in the outer function) and just use $grid variable. It will make access to the DOM of page very quickly. The line localRowData = $grid.jqGrid("getLocalRow", rowId) get the reference to internal JavaScript data object which represent the internal data of the row. By modifying the data by localRowData[columnName] = newValue; or localRowData.total = ... we make the half of job. One need only to change the value in the DOM on the cell Total. I used iColByName which exist in the latest sources of free jqGrid on GitHub. It get just the column index in colModel by column name. One can find the same information alternatively if one use more old jqGrid. The line $($tr[0].cells[iColTotal]).text(localRowData.total); shows how to assign manually the data in the cell. It's the most quick way to do this, but one assign the data without the usage formatter. For more common case (for example in case of frozen "total" column) one can use the commented row above: $grid.jqGrid("setCell", rowId, "total", localRowData.total);.
I have a simple jqgrid.
colModel: [ { name: 'CatId', index: 'CatId', width: 30, align: 'left' }, ...
What I want to do is turn a column into a hyperlink like this example I find on google:
formatoptions:{baseLinkUrl:'someurl.php', addParam: '&action=edit'}
However I want to put the CatId as the parameter, eg:
formatoptions:{baseLinkUrl:'someurl.php', addParam: '&action=<CatId>'}
I can't seem to find any examples of how to do this, other than possibly just hooking into the loadcomplete event and going through and manually updating every row. Is there a nice way to solve this?
The URL used by formatter: "showlink" will be constructed using formatoptions which could be baseLinkUrl, showAction, idName and addParam. The formatter "showlink" uses rowid (the id attribute of <tr> elements of the grid) for constructing the URL. The URL will be built as
baseLinkUrl + showAction + '?' + idName + '=' + rowId + addParam
So the main problem is whether the value of CatId column be used or can be used as the rowid. If you would use key: true option to the definition of CatId column then jqGrid will use the value from CatId as rowid and you could use
formatter: "showlink", formatoptions: { baseLinkUrl: "someurl.php", idName: "action" }
If the value of CatId column can't be used as rowid then I would recommend you to use formatter: "dynamicLink" instead (see jQuery.jqGrid.dynamicLink.js here). I described it in the answer.
I am trying to update the cell value of a particular column in my grid. I am using local JSON for populating the grid datatype: "local".
The column definition of that column is as follows:-
{
name: 'details',
index: 'details',
label: 'Details',
editable: false,
align: 'center',
formatter: function(cellvalue, options, rowObject) {
if (rowObject['verified']) {
return 'sdfsfsd'; // actually hyperlink for the cellvalue
}
return '';
}
}
I am using the following line of code to update the cell value:-
// rowid is 1
grid.jqGrid('setCell', 1, 'details', 'DONE!');
Also tried like this:
// the last parameter true to force update
grid.jqGrid('setCell', 1, 'details', 'DONE!', null, null, true);
However, the cell value is cleared out (cell becomes empty, <td> content is empty). This happens only for this column, and not for other columns in the grid. What am I missing?
Thanks
Vivek Ragunathan
If you use custom formatter you should specify unformatter too. The function formatter will be used to set the value in the cell. At the beginning of cell editing jqGrid need to get the value from the cell. The function unformat do the job.
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.