posts - 495,comments - 227,trackbacks - 0
http://skirtlesden.com/articles/styling-extjs-grid-cells

Styling ExtJS Grid Cells

Author: skirtle First posted: 29-Jan-2012 Last updated: 26-Dec-2012
JavaScript CSS ExtJS Grid Styling

Styling grid cells is a common topic for help requests on the Sencha forums. There are a number of techniques available depending on exactly what styling should be applied where. This article introduces the most widely-used of these techniques along with some of the theory behind how they work.

Default Grid Styling

Let's start by taking a look at the default styling for a grid using the blue theme:

Some key styling features to note include:

  • Rows alternate between white and light grey. It's intended to be subtle but it varies a lot between monitors so you may find it difficult to see.
  • There is a light grey dividing line between each row. There isn't an equivalent vertical line between columns.
  • Moving the mouse cursor over the rows adds a grey highlight. The top and bottom border of the row also darkens when highlighted.
  • Selecting a row adds a light blue background and a dotted blue border.

For reference, the code for this grid looks like this:

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'], 
        ... 
    } 
});

The Grid Markup

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.

<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:

  • x-grid-row – Applied to the 
    <tr>
     element for each row of the grid.
  • x-grid-row-alt – Applied to the 
    <tr>
     element for alternate rows of the grid.
  • x-grid-cell – Applied to the 
    <td>
     element for each cell.
  • x-grid-cell-first – Applied to the 
    <td>
     element for the first cell in each row.
  • x-grid-cell-last – Applied to the 
    <td>
     element for the last cell in each row.

Column Lines

One simple change that can be made without any custom CSS is to add vertical lines between the columns. This just needs the settingcolumnLines to be set to true.

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.

Styling All Grid Cells

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.

Making the grid cells appear yellow needs some CSS like this:

.custom-grid .x-grid-cell 
    background-color#ffa
    border-bottom-color#ffc
    border-top-color#ff5
    color#009
}

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 thebackground-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-styledashed
    border-top-color#999
    border-top-styledashed

 
/* 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-stylesolid
    border-top-color#999
    border-top-stylesolid
}

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.

Alternate Rows

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.

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.

Styling Rows

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:

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.

Static Column Styling

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.

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-weightbold
}

In the CSS selector above note that x-grid-row is on the <tr> element and custom-column is on the <td> element.

First and Last Column

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.

Ext.create('Ext.grid.Panel', { 
    cls: 'custom-first-last'
    ... 
});
.custom-first-last .x-grid-row-selected .x-grid-cell-first 
    background-imageurl(/static/lib/silk/bullet_go.png)
    background-repeatno-repeat
    padding-left12px

 
.custom-first-last .x-grid-row-selected .x-grid-cell-last 
    background-imageurl(/static/lib/silk/user_green.png)
    background-positionright
    background-repeatno-repeat
}

Dynamic Column Styling

Often the styling for a column will vary row by row. A column renderer allows the tdCls to be set individually for each cell.

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 
    backgroundurl(/static/lib/silk/user.png) no-repeat 2px 1px
    padding-left16px

 
.female-cell 
    backgroundurl(/static/lib/silk/user_female.png) no-repeat 2px 1px
    padding-left16px
}

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.

Styling Dirty Fields

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.

Ext.create('Ext.grid.Panel', { 
    cls: 'custom-dirty'
    ... 
});
.custom-dirty .x-grid-dirty-cell 
    background-color#ffa
    background-imageurl(/static/lib/silk/bullet_red.png)
    background-positionright center
    color#090
}
-----

External Links

Feedback

Email feedback to skirtle@skirtlesden.com

Feedback and constructive criticism are welcome, including corrections for minor errors such as spelling mistakes. The names and email addresses of those providing feedback will not be published without their permission. Feedback that results in a significant revision to an article will usually be credited.

posted on 2014-03-26 17:56 SIMONE 阅读(579) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: