Let's start by taking a look at the default styling for a grid using the blue theme: css
Timothy
|
34
|
M
|
Susan
|
67
|
F
|
Elizabeth
|
12
|
F
|
Richard
|
27
|
M
|
Simon
|
8
|
M
|
Roger
|
10
|
M
|
Barry
|
7
|
M
|
Margaret
|
52
|
F
|
Kerry
|
93
|
F
|
Some key styling features to note include: html
For reference, the code for this grid looks like this: app
Ext.create('Ext.grid.Panel', { height: 230, width: 300, columns: [ {dataIndex: 'name', flex: 1, text: 'Name'}, {dataIndex: 'age', flex: 1, text: 'Age'}, {dataIndex: 'sex', flex: 1, text: 'Sex'} ], store: { fields: ['name', 'age', 'sex'], ... } });
Most grid styling is done using CSS. To understand the CSS it's necessary to be familiar with the HTML markup of a grid. Below is a simplified version of that markup. At its heart it's really just an HTML table. It's worth taking a moment to familiarize yourself with this markup if you haven't studied it before. You can refer back to it later when we start looking at the CSS rules. ide
<div class="x-panel x-grid"> <!-- The column headers --> <div class="x-grid-header-ct">...</div> <!-- The panel body --> <div class="x-panel-body x-grid-body"> <!-- The grid view --> <div class="x-grid-view"> <table class="x-grid-table"> <tbody> <!-- A dummy row used to resize columns --> <tr class="x-grid-header-row">...</tr> <!-- The first grid row --> <tr class="x-grid-row"> <td class="x-grid-cell x-grid-cell-first"> <div class="x-grid-cell-inner">Timothy</div> </td> <td class="x-grid-cell"> <div class="x-grid-cell-inner">34</div> </td> <td class="x-grid-cell x-grid-cell-last"> <div class="x-grid-cell-inner">M</div> </td> </tr> <!-- The second grid row --> <tr class="x-grid-row x-grid-row-alt"> ... </tr> ... </tbody> </table> </div> </div> </div>
There are a few CSS classes that are particularly worthy of note in this markup: flex
<tr>
element for each row of the grid. <tr>
element for alternate rows of the grid. <td>
element for each cell. <td>
element for the first cell in each row. <td>
element for the last cell in each row. One simple change that can be made without any custom CSS is to add vertical lines between the columns. This just needs the setting columnLines to be set to true. ui
Timothy
|
34
|
M
|
Susan
|
67
|
F
|
Elizabeth
|
12
|
F
|
Richard
|
27
|
M
|
Simon
|
8
|
M
|
Roger
|
10
|
M
|
Barry
|
7
|
M
|
Margaret
|
52
|
F
|
Kerry
|
93
|
F
|
Ext.create('Ext.grid.Panel', { columnLines: true, ... });
This setting adds a handful of CSS classes to the outermost <div> element of the grid. The most important of these is x-panel-with-col-lines, which has an accompanying rule in the default stylesheet to put a grey border down the right-hand side of each grid cell. this
Timothy
|
34
|
M
|
Susan
|
67
|
F
|
Elizabeth
|
12
|
F
|
Richard
|
27
|
M
|
Simon
|
8
|
M
|
Roger
|
10
|
M
|
Barry
|
7
|
M
|
Margaret
|
52
|
F
|
Kerry
|
93
|
F
|
Ext.create('Ext.grid.Panel', { cls: 'custom-grid', ... });
The setting cls is common to all ExtJS components. It adds a CSS class to the main element for the component. In this case it will put the classcustom-grid on the outermost <div> element. url
Making the grid cells appear yellow needs some CSS like this: spa
.custom-grid .x-grid-cell { background-color: #ffa; border-bottom-color: #ffc; border-top-color: #ff5; color: #009; }
This page is using the 'scoped' ExtJS CSS file. This requires all of the selectors shown in these examples to be prefixed with the class x-reset. This has been omitted from the code samples as it isn't usually required. code
The selector for this rule will match all the <td> cells for this grid. Notice how the styling is applied to the cells rather than the rows. A common mistake is to try to change the background-color for the <tr> element rather than the <td>. This doesn't work because the cells have their own background-color, which completely hides the row.
A little more CSS is needed to handle mouse-over and selection. In both cases the grid automatically adds a CSS class to the <tr> element that we can use to style the cells in those rows.
/* Grid cells when the mouse cursor is over the row */ .custom-grid .x-grid-row-over .x-grid-cell { background-color: #ff6; border-bottom-color: #999; border-bottom-style: dashed; border-top-color: #999; border-top-style: dashed; } /* Grid cells in the selected row */ .custom-grid .x-grid-row-selected .x-grid-cell { background-color: #ff0 !important; border-bottom-color: #999; border-bottom-style: solid; border-top-color: #999; border-top-style: solid; }
One last thing to note here is the use of the !important flag in the code above. Generally this should be avoided but it can't be helped here because it's overriding a rule in the default ExtJS CSS that also uses this flag.
As we've already seen, alternate rows of a grid have the class x-grid-row-alt. This makes it easy to do simple striping effects.
Timothy
|
34
|
M
|
Susan
|
67
|
F
|
Elizabeth
|
12
|
F
|
Richard
|
27
|
M
|
Simon
|
8
|
M
|
Roger
|
10
|
M
|
Barry
|
7
|
M
|
Margaret
|
52
|
F
|
Kerry
|
93
|
F
|
Ext.create('Ext.grid.Panel', { cls: 'extra-alt', ... });
.extra-alt .x-grid-row .x-grid-cell { background-color: #fff; color: #000; } .extra-alt .x-grid-row-alt .x-grid-cell { background-color: #000; color: #fff; }
If you don't want to take advantage of row striping then you can disable it like this:
Ext.create('Ext.grid.Panel', { ... viewConfig: { stripeRows: false } }
Adding the class x-grid-row-alt to alternate rows incurs a performance penalty. Every time the row order changes the grid needs to go through all of its rows and update the CSS classes. If you aren't styling alternate rows differently from each other then you should claim back that performance by turning off row striping. The earlier example of turning all the rows yellow would be a suitable candidate for this.
In many cases the styling for a row is dependent on the data for that row. That data is represented by a record in the store. We can add a CSS class to the <tr> element based on the record using the config option getRowClass:
Timothy
|
34
|
M
|
Susan
|
67
|
F
|
Elizabeth
|
12
|
F
|
Richard
|
27
|
M
|
Simon
|
8
|
M
|
Roger
|
10
|
M
|
Barry
|
7
|
M
|
Margaret
|
52
|
F
|
Kerry
|
93
|
F
|
Ext.create('Ext.grid.Panel', { ... viewConfig: { stripeRows: false, getRowClass: function(record) { return record.get('age') < 18 ? 'child-row' : 'adult-row'; } } });
.child-row .x-grid-cell { background-color: #ffe2e2; color: #900; } .adult-row .x-grid-cell { background-color: #e2ffe2; color: #090; }
Recall that the class x-grid-cell is on the <td> elements for each cell of the row.
The simplest way to style a column is to add a CSS class to every <td> element in that column. The column config setting tdCls does just that.
Timothy
|
34
|
M
|
Susan
|
67
|
F
|
Elizabeth
|
12
|
F
|
Richard
|
27
|
M
|
Simon
|
8
|
M
|
Roger
|
10
|
M
|
Barry
|
7
|
M
|
Margaret
|
52
|
F
|
Kerry
|
93
|
F
|
Ext.create('Ext.grid.Panel', { ... columns: [ {...}, {dataIndex: 'age', flex: 1, text: 'Age', tdCls: 'custom-column'}, {...} ], ... });
.x-grid-row .custom-column { background-color: #ecf; color: #090; font-weight: bold; }
In the CSS selector above note that x-grid-row is on the <tr> element and custom-column is on the <td> element.
As we've already seen, the cells in the first and last columns of a grid have special CSS classes on them. These can be used to style the cells in those columns. The key difference between this and a tdCls is that the tdCls follows its column when the columns are reordered. If you try reordering the columns in this example you'll see that the styling does not follow the column.
Timothy
|
34
|
M
|
Susan
|
67
|
F
|
Elizabeth
|
12
|
F
|
Richard
|
27
|
M
|
Simon
|
8
|
M
|
Roger
|
10
|
M
|
Barry
|
7
|
M
|
Margaret
|
52
|
F
|
Kerry
|
93
|
F
|
Ext.create('Ext.grid.Panel', { cls: 'custom-first-last', ... });
.custom-first-last .x-grid-row-selected .x-grid-cell-first { background-image: url(/static/lib/silk/bullet_go.png); background-repeat: no-repeat; padding-left: 12px; } .custom-first-last .x-grid-row-selected .x-grid-cell-last { background-image: url(/static/lib/silk/user_green.png); background-position: right; background-repeat: no-repeat; }
Often the styling for a column will vary row by row. A column renderer allows the tdCls to be set individually for each cell.
Timothy
|
34
|
Male
|
Susan
|
67
|
Female
|
Elizabeth
|
12
|
Female
|
Richard
|
27
|
Male
|
Simon
|
8
|
Male
|
Roger
|
10
|
Male
|
Barry
|
7
|
Male
|
Margaret
|
52
|
Female
|
Kerry
|
93
|
Female
|
Ext.create('Ext.grid.Panel', { ... columns: [ {...}, {...}, { dataIndex: 'sex', flex: 1, text: 'Sex', renderer: function(value, meta) { if (value === 'M') { meta.tdCls = 'male-cell'; return 'Male'; } meta.tdCls = 'female-cell'; return 'Female'; } } ], ... });
.male-cell { background: url(/static/lib/silk/user.png) no-repeat 2px 1px; padding-left: 16px; } .female-cell { background: url(/static/lib/silk/user_female.png) no-repeat 2px 1px; padding-left: 16px; }
While it isn't shown in this example, the third argument passed to the renderer function is the record for the row, which allows the tdCls to be derived from other fields if necessary.
By default, a dirty field is marked with a red triangle in the top-left corner of the corresponding cell. As you might expect, this is achieved by adding a CSS class to the <td> element. The triangle itself is rendered using a background image. Customizing it just needs a bit of CSS.
Timothy
|
17
|
M
|
Sue
|
67
|
F
|
Elizabeth
|
12
|
F
|
Rick
|
29
|
M
|
Simon
|
8
|
M
|
Roger
|
10
|
M
|
Sally
|
7
|
F
|
Margaret
|
51
|
F
|
Kerry
|
93
|
F
|
Timothy
|
17
|
M
|
Sue
|
67
|
F
|
Elizabeth
|
12
|
F
|
Rick
|
29
|
M
|
Simon
|
8
|
M
|
Roger
|
10
|
M
|
Sally
|
7
|
F
|
Margaret
|
51
|
F
|
Kerry
|
93
|
F
|
Ext.create('Ext.grid.Panel', { cls: 'custom-dirty', ... });
.custom-dirty .x-grid-dirty-cell { background-color: #ffa; background-image: url(/static/lib/silk/bullet_red.png); background-position: right center; color: #090; }