Displaying Data with Grids in Ext JS

Colin Ramsay

October 2010

        Read more about this book      

(For more resources on Ext JS, see here.)

What is a grid anyway?

Ext JS grids are similar to a spreadsheet; there are two main parts to each spreadsheet:

  • Columns
  • Rows

Displaying Data with Grids in Ext JS

Here our columns are Title, Released, Genre, and Price. Each of the rows contains movies such as The Big Lebowski, Super Troopers, and so on. The rows are really our data; each row in the grid represents a record of data held in a data store.

A GridPanel is databound

Like many Ext JS Components, the GridPanel class is bound to a data store which provides it with the data shown in the user interface. So the first step in creating our GridPanel is creating and loading a store.

The data store in Ext JS gives us a consistent way of reading different data formats such as XML and JSON, and using this data in a consistent way throughout all of the Ext JS widgets. Regardless of whether this data is originally provided in JSON, XML, an array, or even a custom data type of our own, it's all accessed in the same way thanks to the consistency of the data store and how it uses a separate reader class which interprets the raw data.

Instead of using a pre-configured class, we will explicitly define the classes used to define and load a store.

The record definition

We first need to define the fields which a Record contains. A Record is a single row of data and we need to define the field names, which we want to be read into our store. We define the data type for each field, and, if necessary, we define how to convert from the raw data into the field's desired data type.

What we will be creating is a new class. We actually create a constructor which will be used by Ext JS to create records for the store.

As the 'create' method creates a constructor, we reference the resulting function with a capitalized variable name, as per standard CamelCase syntax:

var Movie = Ext.data.Record.create([
{name: 'released', type: 'date', dateFormat: 'Y-m-d'},
{name: 'price', type: 'float'},
{name: 'available', type: 'bool'}

Each element in the passed array defines a field within the record. If an item is just a string, the string is used as the name of the field, and no data conversion is performed; the field's value will be whatever the Reader object (which we will learn more about soon) finds in the raw data.

If data conversion is required, then a field definition in the form of an object literal instead of a string may contain the following config options:

  • Name: The name by which the field will be referenced.
  • type: The data type in which the raw data item will be converted to when stored in the record. Values may be 'int', 'float', 'string', 'date', or 'bool'.
  • dateFormat: If the type of data to be held in the field is a date type, then we need to specify a format string as used by the Date.parseDate function.

Defining the data type can help to alleviate future problems, instead of having to deal with all string type data defining the data type, and lets us work with actual dates, Boolean values, and numbers. The following is a list of the built in data types:

Field type




String data




Uses JavaScript's parseInt function


Floating point number

Uses JavaScript's parseFloat function


True/False data



Date data

dateFormat config required to interpret incoming data.

Now that the first step has been completed, and we have a simple Record definition in place, we can move on to the next step of configuring a Reader that is able to understand the raw data.

The Reader

A store may accept raw data in several different formats. Raw data rows may be in the form of a simple array of values, or an object with named properties referencing the values, or even an XML element in which the values are child nodes.

We need to configure a store with a Reader object which knows how to extract data from the raw data that we are dealing with. There are three built in Reader classes in Ext JS.


The ArrayReader class can create a record from an array of values.

By default, values are read out of the raw array into a record's fields in the order that the fields were declared in the record definition we created. If fields are not declared in the same order that the values occur in the rows, the field's definition may contain a mapping config which specifies the array index from which we retrieve the field's value.


This JSONReader class is the most commonly used, and can create a record from raw JSON by decoding and reading the object's properties.

By default, the field's name is used as the property name from which it takes the field's value. If a different property name is required, the field's definition may contain a mapping config which specifies the name of the property from which to retrieve the field's value.


An XMLReader class can create a record from an XML element by accessing child nodes of the element.

By default, the field's name is used as the XPath mapping (not unlike HTML) from which to take the field's value. If a different mapping is required, the field's definition may contain a mapping config which specifies the mapping from which to retrieve the field's value.

Loading our data store

In our first attempt, we are going to create a grid that uses simple local array data stored in a JavaScript variable. The data we're using below in the movieData variable is taken from a very small movie database of some of my favorite movies.

The data store needs two things: the data itself, and a description of the data—or what could be thought of as the fields. A reader will be used to read the data from the array, and this is where we define the fields of data contained in our array.

The following code should be placed before the Ext JS OnReady function:

var movieData = [
"Office Space",
"Mike Judge",
"Work Sucks",
"Super Troopers",
"Jay Chandrasekhar",
"Altered State Police",
//...more rows of data removed for readability...//
var store = new Ext.data.Store({
data: movieData, ,
reader: new Ext.data.ArrayReader({idIndex: 0}, Movie)

If we view this code in a browser we would not see anything—that's because a data store is just a way of loading and keeping track of our data. The web browser's memory has our data in it. Now we need to configure the grid to display our data to the user.

Displaying structured data with a GridPanel

Displaying data in a grid requires several Ext JS classes to cooperate:

  • A Store: A data store is a client-side analogue of a database table. It encapsulates a set of records, each of which contains a defined set of fields.
  • A Record definition: This defines the fields (or "columns" in database terminology) which make up each record in the Store. Field name and datatype are defined here.
  • A Reader which uses a Record definition to extract field values from a raw data object to create the records for a Store.
  • A ColumnModel which specifies the details of each column, including the column header to display, and the name of the record field to be displayed for each column.
  • A GridPanel: A panel subclass which provides the controller logic to bind the above classes together to generate the grid's user interface.

If we were to display the data just as the store sees it now, we would end up with something like this:

Displaying Data with Grids in Ext JS

Now that is ugly—here's a breakdown of what's happening:

  • The Released date has been type set properly as a date, and interpreted from the string value in our data. It's provided in a native JavaScript date format—luckily Ext JS has ways to make this look pretty.
  • The Price column has been type set as a floating point number. Note that there is no need to specify the decimal precision.
  • The Avail column has been interpreted as an actual Boolean value, even if the raw data was not an actual Boolean value.

As you can see, it's quite useful to specify the type of data that is being read, and apply any special options that are needed so that we don't have to deal with converting data elsewhere in our code.

Before we move on to displaying the data in our grid, we should take a look at how the convert config works, as it can come in quite useful.

Converting data read into the store

If we need to, we can convert data as it comes into the store, massage it, remove any quirky parts, or create new fields all together. This should not be used as a way to change the display of data; that part will be handled elsewhere.

A common task might be to remove possible errors in the data when we load it, making sure it's in a consistent format for later actions. This can be done using a convert function, which is defined in the 'convert' config by providing a function, or reference to a function. In this case we are going to create a new field by using the data from another field and combining it with a few standard strings.

var store = new Ext.data.Store({
data: movieData,
reader: new Ext.data.ArrayReader({id:'id'}, [
{name: 'released', type: 'date', dateFormat: 'Y-m-d'},
{name:'coverthumb',convert:function(v, rawData){
return 'images/'+rawData[0]+'m.jpg';

This convert function when used in this manner will create a new field of data that looks like this:


We will use this new field of data shortly, so let's get a grid up and running.

        Read more about this book      

(For more resources on Ext JS, see here.)

Displaying the GridPanel

The class that pulls everything together is the GridPanel. This class takes care of placing the data into columns and rows, along with adding column headers, and boxing it all together in a neat little package.

The movie data store we created isn't much good to anybody just sitting in the computer's memory. Let's display it in a grid by creating a simple GridPanel:

  1. Let's add our data store to the following GridPanel code:

    Ext.onReady(function() {…
    var grid = new Ext.grid.GridPanel({
    renderTo: Ext.getBody(),
    frame: true,
    title: 'Movie Database',
    height: 200,
    width: 520,
    store: store,
    colModel: new Ext.grid.ColumnModel({
    defaultSortable: false,
    columns: [
    {header: "Title", dataIndex: 'title'},
    {header: "Director", dataIndex: 'director'},
    {header: "Released", dataIndex: 'released',
    xtype: 'datecolumn'},
    {header: "Genre", dataIndex: 'genre'},
    {header: "Tagline", dataIndex: 'tagline'}

  2. Bring this page up in a browser, and here's what we will see:

    Displaying Data with Grids in Ext JS

How did that work?

All except two of the config options used here should be familiar to us now because they are inherited from base classes such as the panel.

Believe it or not, there are only two new config options that are really essential to make a GridPanel different from a Panel! They are:

  • store: This references a store object which provides the data displayed in the grid. Any changes to the store are automatically applied to the UI.
  • ColModel: This is a ColumnModel object which defines how the column headers and data cells are to be displayed. It defines a header for each column, and the name of the field to display in that column.

We can almost read through the configuration like a sentence:

Render our grid into the body of the document, frame it, and give it a title of 'Movie Database'. The height will be 200 and the width 520; it will use our 'store' data store and have the columns specified.

This again shows us the benefits of both object-based configuration, and the Ext JS class hierarchy.

The configuration is readable, not a series of parameters whose order must be remembered.

Also, the renderTo frame, title, height, and width options are all inherited from base classes, and are common to all Panel classes. So we will never have to think about these once we have mastered the Panel class.

Defining a grid's column model

The ColumnModel class encapsulates a set of column objects, each of which defines an individual column's characteristics. This is a mirror image of the field definitions in the Record definition which specify how to read in a field's value from a raw data object.

The ColumnModel works at the opposite end of the data flow. It defines which fields from each record to display (you don't have to show them all), and also how the value from each field is to be converted back into string form for display in the UI.

The ColumnModel also maintains defaults to be applied to the columns which it manages, and offers an API to manipulate the columns, and provide information about them.

To define our grid's columns, we configure the ColumnModel with an array of column config objects. Each of the objects within a ColumnModel's columns array defines one column. The most useful options within a column definition are:

  • header: The HTML to display in the header area at the top of the column.
  • dataIndex: The name of the record field—as defined in the Record definition—to display in each cell of the column.
  • xtype: The type of column to create. This is optional, and defaults to a basic column which displays the referenced data field unchanged. But to display a formatted date using the default date format, we can specify 'datecolumn'. There are several other column xtypes described in the API documentation.

So a ColumnModel definition is like this:

new Ext.grid.ColumnModel({
defaultSortable: false,
columns: [
{header: 'Title', dataIndex: 'title'},
{header: 'Director', dataIndex: 'director'},
{header: 'Released', dataIndex: 'released'},
{header: 'Genre', dataIndex: 'genre'},
{header: 'Tagline', dataIndex: 'tagline'}

This will create grid column headers that look like the following. We have also set the default of sortable for each column to false by using a master config in the Column Model:

Displaying Data with Grids in Ext JS

Here are some other useful config options for each column within the column model:





Specifies a function which

returns formatted HTML to

display in a grid cell

Can be used to format the data for this column into your preferred format. Any type of data can be transformed. We will learn about these in the next

few pages.


Hides the column

Boolean value defining whether or not the column should be displayed.


Allows the UI to offer

checkboxes to hide/show

the column

If a column must not be hidden (or indeed begins hidden and must not be shown) by the user, set this option to true.


Specifies the column width

in pixels

The width of the column. Default is 100 pixels; overflowing content is hidden.


Specifies whether the

column is sortable

Boolean value specifying whether or not the column can be sorted. Overrides the defaultSortable configuration of the ColumnModel.

There are several built-in column types, all identified by their own unique xtype which provide special formatting capabilities for cell data.


Displays the text true or false (or the locale specific equivalents if you include the correct Ext JS locale file) in the column's cells depending on whether the cell's field value is true or false. It can be configured with alternative true/false display values. Example usage:

xtype: 'booleancolumn',
header: 'Available',
dataIndex: 'available',
trueText: 'Affirmative',
falseText: 'Negative'


This displays the cell's field value as a formatted date. By default, it uses the date format 'm/d/Y', but it can be configured with a format option specifying an alternative format. The value in the column's associated field must be a date object. Example usage:

header: "Released",
dataIndex: 'released',
xtype: 'datecolumn',
format: 'M d Y',
width: 70


Displays the cell's field value formatted according to a format string as used in Ext.util.Format.number. The default format string is "0.00". Example usage:

header: "Runtime",
dataIndex: 'runtime',
xtype: 'numbercolumn',
format: '0',
width: 70


Uses an Ext.XTemplate string to produce complex HTML with any fields from within the row's record embedded.

header: "Title",
dataIndex: 'title',
xtype: 'templatecolumn',
tpl: '<img src="{coverthumb}" ' +
'width="50" height="68" align="left">'+
'<b style="font-size:13px;">{title}</b><br>'+
'Director:<i> {director}</i><br>{tagline}'

The tokens in the template (tpl) between braces are field names from the store's record. The values are substituted in to create the rendered value. See the API documentation for the Ext.XTemplate class for more information.


Displays icons in a cell, and may be configurable with a handler function to process clicks on an icon. Example illustrating arguments passed to the handler function:

header: 'Delete',
sortable: false,
xtype: 'actioncolumn',
width: 40,
align: 'center',
iconCls: 'delete-movie',
handler: function(grid, rowIndex, colIdex, item, e) {


We have learned a lot in this article about presenting data in a grid. With this new-found knowledge we will be able to organize massive amounts of data into easy-to-understand grids.

Further resources on this subject:

You've been reading an excerpt of:

Learning Ext JS 3.2

Explore Title