Ext JS 4.1.3 Sencha Docs

Grids

The Grid Panel is one of the centerpieces of Ext JS. It's an incredibly versatile component that provides an easy way to display, sort, group, and edit data.

Basic Grid Panel

Simple Grid

Let's get started by creating a basic Grid Panel . Here's all you need to know to get a simple grid up and running:

Model and Store

A Grid Panel is simply a component that displays data contained in a Store. A Store can be thought of as a collection of records, or Model instances. For more information on Stores and Models see the Data guide. The benefit of this setup is clear separation of concerns. The Grid Panel is only concerned with displaying the data, while the Store takes care of fetching and saving the data using its Proxy.

First we need to define a Model. A Model is just a collection of fields that represents a type of data. Let's define a model that represents a "User":

Ext.define('User', {
    extend: 'Ext.data.Model',
    fields: [ 'name', 'email', 'phone' ]
});

Next let's create a Store that contains several User instances.

var userStore = Ext.create('Ext.data.Store', {
    model: 'User',
    data: [
        { name: 'Lisa', email: 'lisa@simpsons.com', phone: '555-111-1224' },
        { name: 'Bart', email: 'bart@simpsons.com', phone: '555-222-1234' },
        { name: 'Homer', email: 'home@simpsons.com', phone: '555-222-1244' },
        { name: 'Marge', email: 'marge@simpsons.com', phone: '555-222-1254' }
    ]
});

For sake of ease we configured the Store to load its data inline. In a real world application you'll usually configure the Store to use a Proxy to load data from the server. See the Data guide for more on using Proxies.

Grid Panel

Now that we have a Model which defines our data structure, and we've loaded several Model instances into a Store, we're ready to display the data using a Grid Panel:

Ext.create('Ext.grid.Panel', {
    renderTo: Ext.getBody(),
    store: userStore,
    width: 400,
    height: 200,
    title: 'Application Users',
    columns: [
        {
            text: 'Name',
            width: 100,
            sortable: false,
            hideable: false,
            dataIndex: 'name'
        },
        {
            text: 'Email Address',
            width: 150,
            dataIndex: 'email',
            hidden: true
        },
        {
            text: 'Phone Number',
            flex: 1,
            dataIndex: 'phone'
        }
    ]
});

And that's all there is to it. We just created a Grid Panel that renders itself to the body element, and we told it to get its data from the userStore Store that we created earlier. Finally we defined what columns the Grid Panel will have, and we used the dataIndex property to configure which field in the User Model each column will get its data from. The Name column has a fixed width of 100px and has sorting and hiding disabled, the Email Address column is hidden by default (it can be shown again by using the menu on any other column), and the Phone Number column flexes to fit the remainder of the Grid Panel's total width. For a larger example, see the Array Grid Example.

Renderers

You can use the renderer property of the column config to change the way data is displayed. A renderer is a function that modifies the underlying value and returns a new value to be displayed. Some of the most common renderers are included in Ext.util.Format, but you can write your own as well:

columns: [
    {
        text: 'Birth Date',
        dataIndex: 'birthDate',
        // format the date using a renderer from the Ext.util.Format class
        renderer: Ext.util.Format.dateRenderer('m/d/Y')
    },
    {
        text: 'Email Address',
        dataIndex: 'email',
        // format the email address using a custom renderer
        renderer: function(value) {
            return Ext.String.format('<a href="mailto:{0}">{1}</a>', value, value);
        }
    }
]

See Array Grid Example for a live demo that uses custom renderers.

Grouping

Grouping Grid

Organizing the rows in a Grid Panel into groups is easy, first we specify a groupField property on our store:

Ext.create('Ext.data.Store', {
    model: 'Employee',
    data: ...,
    groupField: 'department'
});

For more on grouping in Stores please refer to the Data guide. Next we configure a grid with a grouping Feature that will handle displaying the rows in groups:

Ext.create('Ext.grid.Panel', {
    ...
    features: [{ ftype: 'grouping' }]
});

See Grouping Grid Panel for a live example.

Selection Models

Sometimes Grid Panels are use only to display data on the screen, but usually it is necessary to interact with or update that data. All Grid Panels have a Selection Model which determines how data is selected. The two main types of Selection Model are Row Selection Model, where entire rows are selected, and Cell Selection Model, where individual cells are selected.

Grid Panels use a Row Selection Model by default, but it's easy to switch to a Cell Selection Model:

Ext.create('Ext.grid.Panel', {
    selType: 'cellmodel',
    store: ...
});

Using a Cell Selection Model changes a couple of things. Firstly, clicking on a cell now selects just that cell (using a Row Selection Model will select the entire row), and secondly the keyboard navigation will walk from cell to cell instead of row to row. Cell-based selection models are usually used in conjunction with editing.

Editing

Grid Panel has build in support for editing. We're going to look at the two main editing modes - row editing and cell editing

Cell Editing

Cell editing allows you to edit the data in a Grid Panel one cell at a time. The first step in implementing cell editing is to configure an editor for each Column in your Grid Panel that should be editable. This is done using the editor config. The simplest way is to specify just the xtype of the field you want to use as an editor:

Ext.create('Ext.grid.Panel', {
    ...
    columns: [
        {
            text: 'Email Address',
            dataIndex: 'email',
            editor: 'textfield'
       }
    ]
});

If you need more control over how the editor field behaves, the editor config can also take a config object for a Field. For example if we are using a Text Field and we want to require a value:

columns: [
    text: 'Name',
    dataIndex: 'name',
    editor: {
        xtype: 'textfield',
        allowBlank: false
    }
[

You can use any class in the Ext.form.field package as an editor field. Lets suppose we want to edit a column that contains dates. We can use a Date Field editor:

columns: [
    {
        text: 'Birth Date',
        dataIndex: 'birthDate',
        editor: 'datefield'
    }
]

Any Ext.grid.column.Columns in a Grid Panel that do not have a editor configured will not be editable.

Now that we've configured which columns we want to be editable, and the editor fields that will be used to edit the data, the next step is to specify a selection model. Let's use a Cell Selection Model in our Grid Panel config:

Ext.create('Ext.grid.Panel', {
    ...
    selType: 'cellmodel'
});

Finally, to enable editing we need to configure the Grid Panel with a Cell Editing Plugin:

Ext.create('Ext.grid.Panel', {
    ...
    selType: 'cellmodel',
    plugins: [
        Ext.create('Ext.grid.plugin.CellEditing', {
            clicksToEdit: 1
        })
    ]
});

And that's all it takes to create an editable grid using cell editing. See Cell Editing for a working example.

Cell Editing Grid

Row Editing

Row editing enables you to edit an entire row at a time, rather than editing cell by cell. Row editing works in exactly the same way as cell editing - all we need to do is change the plugin type to Ext.grid.plugin.RowEditing and set the selType to rowmodel.

Ext.create('Ext.grid.Panel', {
    ...
    selType: 'rowmodel',
    plugins: [
        Ext.create('Ext.grid.plugin.RowEditing', {
            clicksToEdit: 1
        })
    ]
});

Row Editing - Live Example

Row Editing Grid

Paging

Sometimes your data set is too large to display all on one page. Grid Panel supports two different methods of paging - Paging Toolbar which loads pages using previous/next buttons, and Paging Scroller which loads new pages inline as you scroll.

Store Setup

Before we can set up either type of paging on a Grid Panel, we have to configure the Store to support paging. In the below example we add a pageSize to the Store, and we configure our Reader with a totalProperty:

Ext.create('Ext.data.Store', {
    model: 'User',
    autoLoad: true,
    pageSize: 4,
    proxy: {
        type: 'ajax',
        url : 'data/users.json',
        reader: {
            type: 'json',
            root: 'users',
            totalProperty: 'total'
        }
    }
});

The totalProperty config tells the Reader where to get the total number of results in the JSON response. This Store is configured to consume a JSON response that looks something like this:

{
    "success": true,
    "total": 12,
    "users": [
        { "name": "Lisa", "email": "lisa@simpsons.com", "phone": "555-111-1224" },
        { "name": "Bart", "email": "bart@simpsons.com", "phone": "555-222-1234" },
        { "name": "Homer", "email": "home@simpsons.com", "phone": "555-222-1244" },
        { "name": "Marge", "email": "marge@simpsons.com", "phone": "555-222-1254" }
    ]
}

For more on Stores, Proxies, and Readers refer to the Data Guide.

Paging Toolbar

Now that we've setup our Store to support paging, all that's left is to configure a Paging Toolbar. You could put the Paging Toolbar anywhere in your application layout, but typically it is docked to the Grid Panel:

Ext.create('Ext.grid.Panel', {
    store: userStore,
    columns: ...,
    dockedItems: [{
        xtype: 'pagingtoolbar',
        store: userStore,   // same store GridPanel is using
        dock: 'bottom',
        displayInfo: true
    }]
});

Paging Toolbar

Paging Toolbar Example

Paging Scroller

Grid supports infinite scrolling as an alternative to using a paging toolbar. Your users can scroll through thousands of records without the performance penalties of renderering all the records on screen at once. The grid should be bound to a store with a pageSize specified.

Ext.create('Ext.grid.Panel', {
    // Use a PagingGridScroller (this is interchangeable with a PagingToolbar)
    verticalScroller: 'paginggridscroller',
    // do not reset the scrollbar when the view refreshs
    invalidateScrollerOnRefresh: false,
    // infinite scrolling does not support selection
    disableSelection: true,
    // ...
});

Infinite Scrolling Example