I'm using jqGrid v5.0.2 to implement custom formatter. I'm having summaries enabled in the columns. I want to display the text in Red, if the column value is greater than 40. I have implemented Oleg's solution to my problem. The formatting works, but it is getting applied to the summary row also. For Example :
Resource Week1
-------- -----
Mr.X 45
-Task1 25
-Task2 20
1) In the above example I only want the cells with values 20 and 25 to be red (If they are individually above 40), but the grouped cell 45 also is displayed in red.I want the grouped cell to be red only if it is above 80(40+40). Any suggestions on how to achieve my desired result ?
My Code :
{
name: "FirstWeek",
editable: true,
sortable: false,
formatter: function (cellvalue) {
var color;
var val = Number(cellvalue);
if (val > 40) {
color = 'red';
}
var cellHtml = "<span style='color:" + color + "' originalValue='" +
val + "'>" + val + "</span>";
return cellHtml;
},
unformatter: function(cellValue, options, cellObject) {
return $(cellObject.html()).attr("originalValue");
},
summaryTpl: "<b>{0}</b>",
summaryType: "sum",
editrules: { number: true, minValue: 0, maxValue: 40 }
}
2)While inline editing the custom formatted cell, I'm getting <span class="cellWithoutBackground" style="color:undefined;">25</span> in the cell(UI) . I have used the unformatter function also.That doesn't seem to work. Help appreciated.
I recommend you to remove formatter and unformatter callbacks and to use cellattr callback instead in the column. It could be defined like:
cellattr: function(rowId, val, rawObject) {
if (Number(val) > 40) {
return " style='color: red'";
}
}
or something like
cellattr: function(rowId, val, rawObject) {
if (Number(val) > 40) {
return " class='my-text-color'";
}
}
where you set class my-text-color on specific cells (<td> elements) of the column. If you use class attribute then you should define additional CSS rule like
.my-text-color {
color: red;
}
Related
I'm using jquery.jqgrid version v4.4.4, mvc 5.
In my inline jqgrid, i have Phone Number colModel need to be mask in US Phone number format and my code looks like,
{
name: 'PhoneNumber', index: 'PhoneNumber', editable: true, sortable: true, width: 300, classes: "grid-col",
editoptions: { dataInit: function (elem) {
$(elem).mask("?(999) 999-9999");
$(this).val(elem);
}
}
},
If i type like this'(454)453-3233' the field(textbox) holds the correct value and get saved as '4544533233' in database correctly. To remove the brackets and hypen i used,
PhoneNumber = PhoneNumber.replace(/\D/g, ''); //Removes anything that is not a digit \D
The issue is,
First,if i type like this '( 54)4 - 65' then the field formatted itself and holds (544)65 which is wrong.
Second, the existing phone numbers are not masked, displays in the grid without mask format.
1).How to make the field to hold and save the input with same position as i typed?
2).How to display the existing Phone Number('4544533233'stored like this in db) in mask format?
Thanks.
colModel[{ name: 'DOB', width: 75, editable: true, formatter: dateFormatter, editoptions: { class: 'isDateField' } }]
//dateFormatter function to format before saving
function dateFormatter(cellvalue, options, rowObject) {
if (cellvalue !== undefined) {
var formattedValue = (cellvalue.slice(0, 4) + '/' + cellvalue.slice(4, 6) + '/' + cellvalue.slice(6, 8));
if (formattedValue==='//') {
return ('');
}
return formattedValue;
}
};
I'm working with a Kendo treelist widget, and disappointed to see there's no rowTemplate option as there is on the Kendo grid.
I see a columnTemplate option (i.e. http://docs.telerik.com/kendo-ui/api/javascript/ui/treelist#configuration-columns.template ), but this will affect the entire column.
However, I need to drill into each cell value and set a css color property based on a ratio ( i.e. If value/benchmark < .2, assign <span style='color:red;'> , but my color value is dynamic.
There's a dataBound: and dataBinding: event on the treelist, but I'm still trying to figure out how to intercept each cell value and set the color once I've done my calculation.
var treeOptions = {
dataSource: ds,
columns: colDefs,
selectable: true,
scrollable: true,
resizable: true,
reorderable: true,
height: 320,
change: function (e) {
// push selected dataItem
var selectedRow = this.select();
var row = this.dataItem(selectedRow);
},
dataBound: function (e) {
console.log("dataBinding");
var ds = e.sender.dataSource.data();
var rows = e.sender.table.find("tr");
}
};
and this is where I'm building out the `colDefs' object (column definitions):
function parseHeatMapColumns(data, dimId) {
// Creates the Column Headers of the heatmap treelist.
// typeId=0 is 1st Dimension; typeId=1 is 2nd Dimension
var column = [];
column.push({
"field": "field0",
"title": "Dimension",
headerAttributes: { style: "font-weight:" + 'bold' + ";" },
attributes : { style: "font-weight: bold;" }
});
var colIdx = 1; // start at column 1 to build col headers for the 2nd dimension grouping
_.each(data, function (item) {
if (item.typeId == dimId) {
// Dimension values are duplicated, so push unique values (i.e. trade types may have dupes, whereas a BkgLocation may not).
var found = _.find(column, { field0: item.field0 });
if (found == undefined) {
column.push({
field: "field2",
title: item.field0,
headerAttributes: {
style: "font-weight:" + 'bold'
}
,template: "<span style='color:red;'>#: field2 #</span>"
});
colIdx++;
}
}
});
return column;
}
**** UPDATE ****
In order to embed some logic within the template :
function configureHeatMapColumnDefs(jsonData, cols, model) {
var colDef = '';
var dimId = 0;
var colorProp;
var columns = kendoGridService.parseHeatMapColumns(jsonData, dimId);
// iterate columns and set color property; NB: columns[0] is the left-most "Dimension" column, so we start from i=1.
for (var i = 1; i <= columns.length-1; i++) {
columns[i]['template'] = function (data) {
var color = 'black';
if (data.field2 < 1000) {
color = 'red';
}
else if (data.field2 < 5000) {
color = 'green';
}
return "<span style='color:" + color + ";'>" + data.field2 + "</span>";
};
}
return columns;
}
Advice is appreciated.
Thanks,
Bob
In the databound event you can iterate through the rows. For each row you can get the dataItem associated with it using the dataitem() method (http://docs.telerik.com/kendo-ui/api/javascript/ui/treelist#methods-dataItem)
Once you have the dataitem, calculate your ration and if the row meets the criteria for color, change the cell DOM element:
dataBound: function (e) {
var that = e.sender;
var rows = e.sender.table.find("tr");
rows.each(function(idx, row){
var dataItem = that.dataItem(row);
var ageCell = $(row).find("td").eq(2);
if (dataItem.Age > 30) {
//mark in red
var ageText = ageCell.text();
ageCell.html('<span style="color:red;">' + ageText + '</span>');
}
}
DEMO
UPDATE: you can also do this with a template:
$("#treelist").kendoTreeList({
dataSource: dataSource,
height: 540,
selectable: true,
columns: [
{ field: "Position"},
{ field: "Name" },
{ field: "Age",
template: "# if ( data.Age > 30 ) { #<span style='color:red;'> #= data.Age # </span> #}else{# #= data.Age # #}#"
}
],
});
DEMO
I have a jqgrid which has been loaded from dwr call. It is a dynamic table. In POJO I set 3 status and generate dynamic checkbox.
This is my pojo code.
private String cBox;
public String cBox()
{
if (style() == D)
{
return i l create checkbox here;
}
else if (style() == E)
{
return checkbox will be created ;
}
else if (getStatusFlag() == F)
{
return checkbox will be created;
}
return cBox;
}
I load jqgrid like this.
colNames : ['Code no.', 'Title' ],
colModel : [{
name : 'code_no',
index : 'code_no',
width : '100%',
sorttype : 'text',
align : 'left'
},
{
name : 'title',
index : 'title',
width : '100%',
sorttype : 'text',
align : 'left'
}]
I want to make the entire row bold, if the style is D and I want to make the background color of the row blue when the color is E. How should I customize the jqgrid row ?
The following function will examine each column cell value and if the TestValue is matching add the class to the row.
rowattr: function (rd) {
if (rd.ColumnName == TestValue) { return {"class": "RowBoldClass"}; }//if
},
and the matching class
RowBoldClass { font-weight:bold; .....
how can I make one single cell editable out of a not editable column?
my javaScript looks like this:
$( '#grid' ).jqGrid({
// ...
cellEdit : true,
colModel : [
{ name : "id", index : "id", editable : false },
{ name : "wbs", index : "wbs", editable : false },
{ name : "value", index : "value", editable : false }
],
loadComplete : function(data) {
// ... foreach ( cell in data.rows.columns ) ...
if ( cell.shouldBeEditable ) {
jQuery('#grid').setCell(cell.row, cell.col, '', 'green', { editable : true });
}
}
// ...
}
so, after globally setting columns as not editable, I try to set them as editable locally, based on some criteria (to identify them more easily I also paint them green).
Alas, it's not working: cells become green, but when I try to click them they do not become editable.
Inspecting the selected cell with firebug reveals the edit-cell class to be correctly applied.
As a last note, it's working if I set columns as editable in the first instance.
I suggest you do it in reverse. Make the column editable, but disable the cells that you do not want to be editable. This is a function I wrote to disable cells:
// cellName is the name defined in your colModel
function disableGridCell(cellName) {
var cell = $('[name="' + cellName + '"]');
cell.css('display', 'none');
var div = $("<div>")
.css('width', '100%')
.css('height', '100%')
.css('border', '1px solid #000')
.css('background-color', '#CCC')
.text('xxxxxxxxxxxx');
cell.parent().append(div);
}
I call disableGridCell inside of my onEditFunc of my grid's editRow function:
$('#grid').jqGrid('editRow', id, keys, onEditFunc);
function onEditFunc(id) {
if (condition to disable cell) {
disableGridCell('CellName');
}
}
I found a nice workaround to the problem (thanks to Walter for getting me on the right track).
Instead of locking all the cells and selectively unlocking them in a declarative manner (which may lead to long load times), I'm declaring all the cells as editable.
Then I'm attaching a callback to afterEditCell option:
var $grid = $('#grid');
$grid.jqGrid({
// ...
afterEditCell : function(rowid, cellname, value, iRow, iCol) {
if ( shouldNotBeEditable(iRow, iCol) ) {
$grid.setCell(rowid, cellname, '', 'not-editable-cell');
$grid.restoreCell(iRow, iCol);
}
},
// ...
});
This way the cell is immediately reset to its previous value and I ensure that the callback gets called only once per not-to-be-edited cell, since the cell is made into a not-editable-cell after the first call.
colModel:[
{name:'description',index:'description', width:4, sortable: false, editable: true},
{name:'qty',index:'qty', width:1,sortable: false, editable: true},
{name:'cost',index:'cost', width:1, editable: true, sortable: false},
{name:'totalCost',index:'totalCost', width:1, sortable: false}
onCellSelect: function(rowid, iCol, cellcontent, e) {
//here it will allow editing of either qty or cost col for that rowid
//only if both cols have a numeric value already
if(iCol===1 || iCol===2) {
var rowdata = $("#projectTable").getRowData(rowid);
var itemCost = parseInt(rowdata['cost']);
var qty = parseInt(rowdata['qty']);
if(!$.isNumeric(itemCost) || !$.isNumeric(qty)) {
$("#projectTable").jqGrid('setColProp','qty',{editable: false});
$("#projectTable").jqGrid('setColProp','cost',{editable: false});
} else {
$("#projectTable").jqGrid('setColProp','qty',{editable: true});
$("#projectTable").jqGrid('setColProp','cost',{editable: true});
}
}
},
Is there a way to create a custom field that has multiple input elements? I'm consulting the documentation and creating a single input element is pretty straight forward, but I'm not exactly sure how you'd add more than one.
Has anyone crossed this bridge before? If so, how did you do it?
Here's some sample code:
...
{name: 'Dimensions', index: 'Dimensions', hidden: true, editable: true,
edittype: 'custom', editoptions: {custom_element: dimensionsElement,
custom_value: dimensionsValue}, editrules: {edithidden: true}},
...
function dimensionsElement(value, options) {
var el = document.createElement("input");
el.type = "text";
el.value = value;
return el;
}
function dimensionsValue(elem) {
return $(elem).val();
}
You can use jQuery to create multiple input elements. So if your field is for example a persons full name you can use following
{ name: 'FullName', editable: true, edittype: 'custom', width: 300,
editoptions: {
custom_element: function(value, options) {
// split full name to the first and last name
var parts = value.split(' ');
// create a string with subelements
var elemStr = '<div><input id="'+options.id +
'_first" size="10" value="' + parts[0] +
'" /></br><input id="'+options.id + '_last' +
'"size="20" value="' + parts[1] + '" /></div>';
// return DOM element from jQuery object
return $(elemStr)[0];
},
custom_value: function(elem) {
var inputs = $("input", $(elem)[0]);
var first = inputs[0].value;
var last = inputs[1].value;
return first + ' '+ last;
}
}},
It is of cause a raw code fragment and you should improve the layout of input elements (the value of size attribute for example). It shows the main concept of building of custom edit elements.
UPDATED: If you use custom editing it is important to use recreateForm: true parameter (see http://www.trirand.com/jqgridwiki/doku.php?id=wiki:form_editing). See jqgrid - Set the custom_value of edittype: 'custom' for details.