Recently, someone asked the best way to style a cell inside of a <cfgrid> based on the value of the data the cell contains. As I have played around a lot with customizing <cfgrid>, this seemed like a pretty easy question to answer. I figured that we could simply use a custom renderer to wrap the value for the cell in a <div /> with a given CSS class based on the value. As it turns out, this solution worked, but was not ideal, however, a better solution was actually just as easy.
Here is the code for my original solution:
<html>
<head>
<script>
formatStatus = function(data,cell,record,row,col,store) {
var ret = “<div class=’status”+ data +”‘>” + data + “</div>”;
return ret;
}
formatCells = function() {
theGrid = ColdFusion.Grid.getGridObject(‘widgetGrid’);
cm = theGrid.getColumnModel();
cm.setRenderer(1,formatStatus);
}
</script>
<style>
.status1{border:1px solid #000; background-color:#ffc6b8; }
.status2{border:1px solid #000; background-color:#bcb8ff; }
.status3{border:1px solid #000; background-color:#f7ffd2; }
.status4{border:1px solid #000; background-color:#abffba; }
.status5{border:1px solid #000; background-color:#ffe5bf; }
</style>
</head>
<body>
<cfset widgets = queryNew(“name,status”)>
<cfloop from=1 to=20 index=”x”>
<cfset status = randRange(1,5) />
<cfset widget = “Widget ” & x />
<cfset queryAddRow(widgets)>
<cfset querySetCell(widgets, “status”, status, x)>
<cfset querySetCell(widgets, “name”, widget, x)>
</cfloop>
<cfform name=”gridExample” style=”padding:20px”>
<cfgrid name=”widgetGrid” format=”html” query=”widgets” width=”300″ >
<cfgridcolumn name=”name” header=”Widget” />
<cfgridcolumn name=”status” header=”Status” />
</cfgrid>
</cfform>
<cfset ajaxOnLoad(“formatCells”)>
</body>
</html>
This example is based on one from Ray Camden but instead of formatting how the data is formatted, we are trying to style its ‘container’.
The call to ajaxOnLoad() makes sure that when the grid is rendered that we are calling the formatCells() JavaScript method. Inside of formatCells() we use the built-in ColdFusion JavaScript to get the instance of our grid. Remember, when we use ColdFusion.Grid.getGridObject(‘widgetGrid’) we are actually getting the native ExtJS grid object and once we have that object, we can manipulate it as we could any ExtJS grid.
Now that we have the instance of the grid object, the next thing we need to do is to get the column model using getColumnModel(). The column model is simply the column definitions for our grid. When we are using <cfgrid>, the column model is defined by our <cfgridcolumn> tags.
Once we have our column model, we can then set the renderer for the column we want to format. In this case we want to format the ‘status’ column, which is the second column defined. Since JavaScript uses zero index arrays (which I will never understand), we need to specify the second column by using ‘1’ as the first argument of setRenderer(). The second argument of setRenderer() is the JavaScript method that will be used to format our data, in this case formatStatus().
Our renderer JavaScript method accepts 6 arguments – the value, info about the cell where the data will go, which record we are looking at, the row we are in, the column we are in and the ‘store’. The store is just a JavaScript object that contains all the data for the grid.
In this first example, we are simply using JavaScript to wrap our value in a <div /> and set a CSS class based on what that status is for this record. You can also see that the status is a random value between 1 and 5 and that I have CSS styles specified for .status1, .status2, etc.
This seemed a bit too easy, and if you look at the image below, you will see that the styles worked, but the <div /> we added does not fill the entire cell, and quite frankly, I do not like the way this looks.
I figured that there has to be an equally easy way to style the actual <td> in the grid. After looking through the EXT JS documentation, it turns out there is. The second argument that is passed to our renderer, formatStatus(), has information about the cell. One of the properties available to us here is ‘css’, which allows us to add CSS classes to the actual <td> of the grid. Here is the updated code to show this new styling.
<html>
<head>
<script>
formatStatus = function(data,cell,record,row,col,store) {
cell.css = ‘status’ + data;
return data
}
formatCells = function() {
theGrid = ColdFusion.Grid.getGridObject(‘widgetGrid’);
cm = theGrid.getColumnModel();
cm.setRenderer(1,formatStatus);
}
</script>
<style>
.status1{border:1px solid #000; background-color:#ffc6b8; }
.status2{border:1px solid #000; background-color:#bcb8ff; }
.status3{border:1px solid #000; background-color:#f7ffd2; }
.status4{border:1px solid #000; background-color:#abffba; }
.status5{border:1px solid #000; background-color:#ffe5bf; }
</style>
</head>
<body>
<cfset widgets = queryNew(“name,status”)>
<cfloop from=1 to=20 index=”x”>
<cfset status = randRange(1,5) />
<cfset widget = “Widget ” & x />
<cfset queryAddRow(widgets)>
<cfset querySetCell(widgets, “status”, status, x)>
<cfset querySetCell(widgets, “name”, widget, x)>
</cfloop>
<cfform name=”gridExample” style=”padding:20px”>
<cfgrid name=”widgetGrid” format=”html” query=”widgets” width=”300″ >
<cfgridcolumn name=”name” header=”Widget” />
<cfgridcolumn name=”status” header=”Status” />
</cfgrid>
</cfform>
<cfset ajaxOnLoad(“formatCells”)>
</body>
</html>
I think the code is cleaner and it renders much nicer than the first solution.
I plan to dive into some more of the native Ext JS functionality and plan to post some of the niftier things I find.
Comments on: "Ask an Alagadian – How can I style a cell in based on the data it contains?" (1)
Hi, I’m a cute 16 year old with perky boobs abd a tight ass that’s just dying to get busy with older guys.
LikeLike