Ext.data.JsonP.grid({"title":"The Grid Component","guide":"

Grids

\n
\n

Contents

\n
    \n
  1. Basic Grid Panel
  2. \n
  3. Renderers
  4. \n
  5. Grouping
  6. \n
  7. Selection Models
  8. \n
  9. Editing
  10. \n
  11. Paging
  12. \n
\n
\n\n

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.

\n\n

Basic Grid Panel

\n\n

\"Simple

\n\n

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:

\n\n

Model and Store

\n\n

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.\nFor 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\nwith displaying the data, while the Store takes care of fetching and saving the data using its Proxy.

\n\n

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

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

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

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

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.

\n\n

Grid Panel

\n\n

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:

\n\n

For the sake of ease we configured the grid with renderTo to immediately render the grid into the HTML document. In a real world application, the grid will usually be a child item of a\nContainer and rendering will therefore be the responsibility of that Container and the developer must not render.

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

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.

\n\n

Renderers

\n\n

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:

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

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

\n\n

Grouping

\n\n

\"Grouping

\n\n

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

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

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:

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

See Grouping Grid Panel for a live example.

\n\n

Selection Models

\n\n

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.

\n\n

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

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

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.

\n\n

Editing

\n\n

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

\n\n

Cell Editing

\n\n

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:

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

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:

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

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:

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

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

\n\n

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:

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

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

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

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

\n\n

\"Cell

\n\n

Row Editing

\n\n

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.

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

Row Editing - Live Example

\n\n

\"Row

\n\n

Paging

\n\n

Sometimes your data set is too large to display all on one page. Grid Panel supports displaying individual pages from the dataset using a Paging Toolbar which loads pages using previous/next buttons.

\n\n

Store Setup

\n\n

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:

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

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:

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

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

\n\n

Paging Toolbar

\n\n

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:

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

\"Paging

\n\n

Paging Toolbar Example

\n\n

Buffered rendering

\n\n

Grids support buffered rendering of extremely large datasets as an alternative to using a paging toolbar.\nYour users can scroll through thousands of records without the performance penalties of renderering all the\nrecords on screen at once. The grid should be bound to a store with a pageSize specified.

\n\n

To use buffered rendering, configure your grid with the bufferedrenderer plugin. The Store can be\nfully loaded with a very large dataset.

\n\n

Only enough rows are rendered to fill the visible area of the grid with a little\n(configurable) overflow either side to\nallow scrolling. As scrolling proceeds, new rows are rendered in the direction of scroll, and rows are removed from\nthe receding side of the table.

\n\n
Ext.create('Ext.grid.Panel', {\n    // Use a BufferedRenderer plugin\n    plugins: {\n        ptype: 'bufferedrenderer'\n    },\n    // Configure the rest as usual\n    ...\n});\n
\n\n

Buffered rendering of a loaded store Example

\n\n

Buffered Stores

\n\n

If a dataset is extremely large, then loading the full dataset into the Store may be infeasible. In this case, the solution is to\nuse a buffered Store. When using a buffered store, the grid automatically uses the buffered rendering plugin.

\n\n

A buffered store must be configured with a pageSize, and maintains a sparsely populated cache\nof pages which are loaded from the server as needed.

\n\n

A buffered store only loads the pages required to render the visible portion of the dataset with a little\n(configurable) overflow either side to allow new data to be fetched by the buffered renderer\nfor immediate rendering while new pages are fetched in the background to fulfill future scrolling demands.

\n\n

As the user scrolls through the dataset, and pages move outside of the visible range, they may be purged from the store's page cache\ndepending upon the purgePageCount setting. Configuring this as zero means that once loaded,\npages are never purged from the cache, and may be returned to and rendered with no Ajax delay.

\n\n

Buffered store Example

\n"});