Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / guides / grid / README.md
1 # Grids
2
3 The {@link Ext.grid.Panel 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.
4
5 ## Basic Grid Panel
6
7 {@img simple_grid.png Simple Grid}
8
9 Let's get started by creating a basic {@link Ext.grid.Panel Grid Panel} .  Here's all you need to know to get a simple grid up and running:
10
11 ### Model and Store
12
13 A {@link Ext.grid.Panel Grid Panel} is simply a component that displays data contained in a {@link Ext.data.Store Store}. A {@link Ext.data.Store Store} can be thought of as a collection of records, or {@link Ext.data.Model Model} instances. For more information on {@link Ext.data.Store Store}s and {@link Ext.data.Model Model}s see the [Data guide](#/guide/data).  The benefit of this setup is clear separation of concerns.  The {@link Ext.grid.Panel Grid Panel} is only concerned with displaying the data, while the {@link Ext.data.Store Store} takes care of fetching and saving the data using its {@link Ext.data.proxy.Proxy Proxy}.
14
15 First we need to define a {@link Ext.data.Model Model}. A {@link Ext.data.Model Model} is just a collection of fields that represents a type of data.  Let's define a model that represents a "User":
16
17     Ext.define('User', {
18         extend: 'Ext.data.Model',
19         fields: [ 'name', 'email', 'phone' ]
20     });
21
22 Next let's create a {@link Ext.data.Store Store} that contains several `User` instances.
23
24     var userStore = Ext.create('Ext.data.Store', {
25         model: 'User',
26         data: [
27             { name: 'Lisa', email: 'lisa@simpsons.com', phone: '555-111-1224' },
28             { name: 'Bart', email: 'bart@simpsons.com', phone: '555-222-1234' },
29             { name: 'Homer', email: 'home@simpsons.com', phone: '555-222-1244' },
30             { name: 'Marge', email: 'marge@simpsons.com', phone: '555-222-1254' }
31         ]
32     });
33
34 For sake of ease we configured the {@link Ext.data.Store Store} to load its data inline.  In a real world application you'll usually configure the {@link Ext.data.Store Store} to use a {@link Ext.data.Proxy Proxy} to load data from the server.  See the [Data guide](#/guide/data) for more on using {@link Ext.data.Proxy Proxies}.
35
36 ### Grid Panel
37
38 Now that we have a {@link Ext.data.Model Model} which defines our data structure, and we've loaded several {@link Ext.data.Model Model} instances into a {@link Ext.data.Store Store}, we're ready to display the data using a {@link Ext.grid.Panel Grid Panel}:
39
40     Ext.create('Ext.grid.Panel', {
41         renderTo: Ext.getBody(),
42         store: userStore,
43         width: 400,
44         height: 200,
45         title: 'Application Users',
46         columns: [
47             {
48                 text: 'Name',
49                 width: 100,
50                 sortable: false,
51                 hideable: false,
52                 dataIndex: 'name'
53             },
54             {
55                 text: 'Email Address',
56                 width: 150,
57                 dataIndex: 'email',
58                 hidden: true
59             },
60             {
61                 text: 'Phone Number',
62                 flex: 1,
63                 dataIndex: 'phone'
64             }
65         ]
66     });
67
68 And that's all there is to it.  We just created a {@link Ext.grid.Panel Grid Panel} that renders itself to the body element, and we told it to get its data from the `userStore` {@link Ext.data.Store Store} that we created earlier.  Finally we defined what columns the {@link Ext.grid.Panel Grid Panel} will have, and we used the `dataIndex` property to configure which field in the `User` {@link Ext.data.Model 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 {@link Ext.grid.Panel Grid Panel}'s total width.  To view this example live, see the [Simple Grid Example](guides/grid/examples/simple_grid/index.html).
69
70 ## Renderers
71
72 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 {@link Ext.util.Format}, but you can write your own as well:
73
74     columns: [
75         {
76             text: 'Birth Date',
77             dataIndex: 'birthDate',
78             // format the date using a renderer from the Ext.util.Format class
79             renderer: Ext.util.Format.dateRenderer('m/d/Y')
80         },
81         {
82             text: 'Email Address',
83             dataIndex: 'email',
84             // format the email address using a custom renderer
85             renderer: function(value) {
86                 return Ext.String.format('<a href="mailto:{0}">{1}</a>', value, value);
87             }
88         }
89     ]
90
91 See the [Renderers Example](guides/grid/examples/renderers/index.html) for a live demo that uses custom renderers.
92
93
94 ## Grouping
95
96 {@img grouping.png Grouping Grid}
97
98 Organizing the rows in a {@link Ext.grid.Panel Grid Panel} into groups is easy, first we specify a {@link Ext.data.Store#groupField groupField} property on our store:
99
100
101     Ext.create('Ext.data.Store', {
102         model: 'Employee',
103         data: ...,
104         groupField: 'department'
105     });
106
107 For more on gouping in {@link Ext.data.Store Store}s please refer to the [Data guide](#/guide/data).  Next we configure a grid with a grouping {@link Ext.grid.feature.Feature Feature} that will handle displaying the rows in groups:
108
109
110     Ext.create('Ext.grid.Panel', {
111         ...
112         features: [{ ftype: 'grouping' }]
113     });
114
115 See [Grouping Grid Panel](guides/grid/examples/grouping/index.html) for a live example.
116
117
118 ## Selection Models
119
120 Sometimes {@link Ext.grid.Panel Grid Panel}s are use only to display data on the screen, but usually it is necessary to interact with or update that data.  All {@link Ext.grid.Panel Grid Panel}s have a {@link Ext.selection.Model Selection Model} which determines how data is selected. The two main types of Selection Model are {@link Ext.selection.RowModel Row Selection Model}, where entire rows are selected, and {@link Ext.selection.CellModel Cell Selection Model}, where individual cells are selected.
121
122 {@link Ext.grid.Panel Grid Panel}s use a {@link Ext.selection.RowModel Row Selection Model} by default, but it's easy to switch to a {@link Ext.selection.CellModel Cell Selection Model}:
123
124     Ext.create('Ext.grid.Panel', {
125         selType: 'cellmodel',
126         store: ...
127     });
128
129 Using a {@link Ext.selection.CellModel Cell Selection Model} changes a couple of things. Firstly, clicking on a cell now selects just that cell (using a {@link Ext.selection.RowModel 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.
130
131 ## Editing
132
133 {@link Ext.grid.Panel Grid Panel} has build in support for editing.  We're going to look at the two main editing modes - row editing and cell editing
134
135 ### Cell Editing
136
137 Cell editing allows you to edit the data in a {@link Ext.grid.Panel Grid Panel} one cell at a time.  The first step in implementing cell editing is to configure an editor for each {@link Ext.grid.column.Column Column} in your {@link Ext.grid.Panel Grid Panel} that should be editable.  This is done using the {@link Ext.grid.column.Column#editor editor} config.  The simplest way is to specify just the xtype of the field you want to use as an editor:
138
139     Ext.create('Ext.grid.Panel', {
140         ...
141         columns: [
142             {
143                 text: 'Email Address',
144                 dataIndex: 'email',
145                 editor: 'textfield'
146            }
147         ]
148     });
149
150 If you need more control over how the editor field behaves, the {@link Ext.grid.column.Column#editor editor} config can also take a config object for a Field.  For example if we are using a {@link Ext.form.field.Text Text Field} and we want to require a value:
151
152     columns: [
153         text: 'Name',
154         dataIndex: 'name',
155         editor: {
156             xtype: 'textfield',
157             allowBlank: false
158         }
159     [
160
161 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 {@link Ext.form.field.Date Date Field} editor:
162
163     columns: [
164         {
165             text: 'Birth Date',
166             dataIndex: 'birthDate',
167             editor: 'datefield'
168         }
169     ]
170
171 Any {@link Ext.grid.column.Column}s in a {@link Ext.grid.Panel Grid Panel} that do not have a {@link Ext.grid.column.Column#editor editor} configured will not be editable.
172
173 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 {@link Ext.selection.CellModel Cell Selection Model} in our {@link Ext.grid.Panel Grid Panel} config:
174
175
176     Ext.create('Ext.grid.Panel', {
177         ...
178         selType: 'cellmodel'
179     });
180
181 Finally, to enable editing we need to configure the {@link Ext.grid.Panel Grid Panel} with a {@link Ext.grid.plugin.CellEditing Cell Editing Plugin}:
182
183     Ext.create('Ext.grid.Panel', {
184         ...
185         selType: 'cellmodel',
186         plugins: [
187             Ext.create('Ext.grid.plugin.CellEditing', {
188                 clicksToEdit: 1
189             })
190         ]
191     });
192
193 And that's all it takes to create an editable grid using cell editing. See [Cell Editing](guides/grid/examples/cell_editing) for a working example.
194
195 {@img cell_editing.png Cell Editing Grid}
196
197 ### Row Editing
198
199 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 {@link Ext.grid.plugin.RowEditing} and set the selType to `rowmodel`.
200
201     Ext.create('Ext.grid.Panel', {
202         ...
203         selType: 'rowmodel',
204         plugins: [
205             Ext.create('Ext.grid.plugin.RowEditing', {
206                 clicksToEdit: 1
207             })
208         ]
209     });
210
211 [Row Editing - Live Example](guides/grid/examples/row_editing)
212
213 {@img row_editing.png Row Editing Grid}
214
215 ## Paging
216
217 Sometimes your data set is too large to display all on one page.  {@link Ext.grid.Panel Grid Panel} supports two different methods of paging - {@link Ext.toolbar.Paging Paging Toolbar} which loads pages using previous/next buttons, and {@link Ext.grid.PagingScroller Paging Scroller} which loads new pages inline as you scroll.
218
219 ### Store Setup
220
221 Before we can set up either type of paging on a {@link Ext.grid.Panel Grid Panel}, we have to configure the {@link Ext.data.Store Store} to support paging.  In the below example we add a {@link Ext.data.Store#pageSize pageSize} to the {@link Ext.data.Store Store}, and we configure our {@link Ext.data.reader.Reader Reader} with a {@link Ext.data.reader.Reader#totalProperty totalProperty}:
222
223     Ext.create('Ext.data.Store', {
224         model: 'User',
225         autoLoad: true,
226         pageSize: 4,
227         proxy: {
228             type: 'ajax',
229             url : 'data/users.json',
230             reader: {
231                 type: 'json',
232                 root: 'users',
233                 totalProperty: 'total'
234             }
235         }
236     });
237
238 The {@link Ext.data.reader.Reader#totalProperty totalProperty} config tells the {@link Ext.data.reader.Reader Reader} where to get the total number of results in the JSON response.  This {@link Ext.data.Store Store} is configured to consume a JSON response that looks something like this:
239
240     {
241         "success": true,
242         "total": 12,
243         "users": [
244             { "name": "Lisa", "email": "lisa@simpsons.com", "phone": "555-111-1224" },
245             { "name": "Bart", "email": "bart@simpsons.com", "phone": "555-222-1234" },
246             { "name": "Homer", "email": "home@simpsons.com", "phone": "555-222-1244" },
247             { "name": "Marge", "email": "marge@simpsons.com", "phone": "555-222-1254" }
248         ]
249     }
250
251 For more on {@link Ext.data.Store Stores}, {@link Ext.data.proxy.Proxy Proxies}, and {@link Ext.data.reader.Reader Readers} refer to the [Data Guide](#/guide/data).
252
253 ### Paging Toolbar
254
255 Now that we've setup our {@link Ext.data.Store Store} to support paging, all that's left is to configure a {@link Ext.toolbar.Paging Paging Toolbar}.  You could put the {@link Ext.toolbar.Paging Paging Toolbar} anywhere in your application layout, but typically it is docked to the {@link Ext.grid.Panel Grid Panel}:
256
257     Ext.create('Ext.grid.Panel', {
258         store: userStore,
259         columns: ...,
260         dockedItems: [{
261             xtype: 'pagingtoolbar',
262             store: userStore,   // same store GridPanel is using
263             dock: 'bottom',
264             displayInfo: true
265         }]
266     });
267
268 {@img paging_toolbar.png Paging Toolbar}
269
270 [Paging Toolbar Example](guides/grid/examples/paging_toolbar/index.html)
271
272 ### Paging Scroller
273
274 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.
275
276     Ext.create('Ext.grid.Panel', {
277         // Use a PagingGridScroller (this is interchangeable with a PagingToolbar)
278         verticalScrollerType: 'paginggridscroller',
279         // do not reset the scrollbar when the view refreshs
280         invalidateScrollerOnRefresh: false,
281         // infinite scrolling does not support selection
282         disableSelection: true,
283         // ...
284     });
285
286 [Infinite Scrolling Example](extjs/examples/grid/infinite-scroll.html)