This is how you can display an image and a value inside an Ext GridPanel cell using a renderer function.
As in the previous example, to explain the approach I will use a GridPanel that displays movie rentals information. Together with movie titles and number of rentals, the grid will display rental trends using a small icon, as shown in the following screenshot:
How to do it
An ArrayStore will provide a few dummy records:
var store = new Ext.data.ArrayStore({
fields: ['title', 'rentals', 'trend'],
data: [['ACADEMY DINOSAUR', 305, 'up'],
['DRAGONFLY STRANGERS', 240, 'neutral'],
['FAMILY SWEET', 188, 'down'],
['FREAKY POCUS', 205, 'up'],
['GABLES METROPOLIS', 265, 'up']]
});
Next comes the GridPanel definition:
var grid = new Ext.grid.GridPanel({
title: 'Movie rentals this month',
store: store,
columns: [
{ id: 'title-col', header: "Title", width: 275, dataIndex: 'title', sortable: true },
{ header: "Rentals", width: 75, dataIndex: 'rentals', sortable: true, align: 'right',
renderer: function(value, metaData, record, rowIndex, colIndex, store) {
switch (record.data.trend) {
case 'down':
metaData.css = 'trend-down';
break;
case 'neutral':
metaData.css = 'trend-neutral';
break;
case 'up':
metaData.css = 'trend-up';
break;
}
return value + String.format('<img class="padding-img" src="{0}"/>',Ext.BLANK_IMAGE_URL);
}
}
],
autoExpandColumn: 'title-col',
renderTo: Ext.getBody(),
width: 350,
height: 175,
loadMask: true
});
How it works
In this example we assign a renderer function to the rentals column, and use the trend value to modify the rentals grid cell. This is possible because the renderer function's arguments include the current record object. From the record, we can get to the trend value via record.data.trend.
How do we display the value and the icon in the same cell? Well, we add the trend icon to the cell's background by inspecting record.data.trend and modifying the css property of the metaData object:
switch (record.data.trend) {
case 'down':
metaData.css = 'trend-down';
break;
case 'neutral':
metaData.css = 'trend-neutral';
break;
case 'up':
metaData.css = 'trend-up';
break;
}
Here are the styles used:
<style type="text/css">
.trend-down
{
background:url(img/trend-down.png) right no-repeat !important;
}
.trend-neutral
{
background:url(img/trend-neutral.png) right no-repeat !important;
}
.trend-up
{
background:url(img/trend-up.png) right no-repeat !important;
}
.padding-img
{
width:18px;height:0px;
}
</style>
As the column and the icon are both right-aligned and the icon is on the background, the cell's value is going to be positioned over the icon. But we want to display the value to the left of the icon, not over it. To accomplish this, we use a transparent image (using Ext.BLANK_IMAGE_URL) to add some padding between the value and the right border of the cell. This makes room for the icon:
return value + String.format('<img class="padding-img" src="{0}"/>',Ext.BLANK_IMAGE_URL);
Downloads
Download the sample from my downloads page.