Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / examples / grid / binding-with-classes.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 Ext.require([
16     'Ext.grid.*',
17     'Ext.data.*',
18     'Ext.panel.*',
19     'Ext.layout.container.Border'
20 ]);
21 Ext.Loader.onReady(function() {
22     Ext.define('Book',{
23         extend: 'Ext.data.Model',
24         fields: [
25             // set up the fields mapping into the xml doc
26             // The first needs mapping, the others are very basic
27             {name: 'Author', mapping: 'ItemAttributes > Author'},
28             'Title',
29             'Manufacturer',
30             'ProductGroup',
31             'DetailPageURL'
32         ]
33     });
34
35
36     /**
37      * App.BookStore
38      * @extends Ext.data.Store
39      * @cfg {String} url This will be a url of a location to load the BookStore
40      * This is a specialized Store which maintains books.
41      * It already knows about Amazon's XML definition and will expose the following
42      * Record defintion:
43      *  - Author
44      *  - Manufacturer
45      *  - ProductGroup
46      *  - DetailPageURL
47      */
48     Ext.define('App.BookStore', {
49         extend: 'Ext.data.Store',
50         constructor: function(config) {
51             config = config || {};
52
53             config.model = 'Book';
54             config.proxy = {
55                 type: 'ajax',
56                 url: 'sheldon.xml',
57                 reader: Ext.create('Ext.data.reader.Xml', {
58                     // records will have an "Item" tag
59                     record: 'Item',
60                     id: 'ASIN',
61                     totalRecords: '@total'
62                 })
63             };
64
65             // call the superclass's constructor
66             this.callParent([config]);
67         }
68     });
69
70
71     /**
72      * App.BookGrid
73      * @extends Ext.grid.Panel
74      * This is a custom grid which will display book information. It is tied to
75      * a specific record definition by the dataIndex properties.
76      *
77      * It follows a very custom pattern used only when extending Ext.Components
78      * in which you can omit the constructor.
79      *
80      * It also registers the class with the Component Manager with an xtype of
81      * bookgrid. This allows the application to take care of the lazy-instatiation
82      * facilities provided in Ext's Component Model.
83      */
84     Ext.define('App.BookGrid', {
85         extend: 'Ext.grid.Panel',
86         // This will associate an string representation of a class
87         // (called an xtype) with the Component Manager
88         // It allows you to support lazy instantiation of your components
89         alias: 'widget.bookgrid',
90
91         // override
92         initComponent : function() {
93             // Pass in a column model definition
94             // Note that the DetailPageURL was defined in the record definition but is not used
95             // here. That is okay.
96             this.columns = [
97                 {text: "Author", width: 120, dataIndex: 'Author', sortable: true},
98                 {text: "Title", flex: 1, dataIndex: 'Title', sortable: true},
99                 {text: "Manufacturer", width: 115, dataIndex: 'Manufacturer', sortable: true},
100                 {text: "Product Group", width: 100, dataIndex: 'ProductGroup', sortable: true}
101             ];
102             // Note the use of a storeId, this will register thisStore
103             // with the StoreManager and allow us to retrieve it very easily.
104             this.store = new App.BookStore({
105                 storeId: 'gridBookStore',
106                 url: 'sheldon.xml'
107             });
108             // finally call the superclasses implementation
109             this.callParent();
110         }
111     });
112
113
114     /**
115      * App.BookDetail
116      * @extends Ext.Panel
117      * This is a specialized Panel which is used to show information about
118      * a book.
119      *
120      * This demonstrates adding 2 custom properties (tplMarkup and
121      * startingMarkup) to the class. It also overrides the initComponent
122      * method and adds a new method called updateDetail.
123      *
124      * The class will be registered with an xtype of 'bookdetail'
125      */
126     Ext.define('App.BookDetail', {
127         extend: 'Ext.Panel',
128         // register the App.BookDetail class with an xtype of bookdetail
129         alias: 'widget.bookdetail',
130         // add tplMarkup as a new property
131         tplMarkup: [
132             'Title: <a href="{DetailPageURL}" target="_blank">{Title}</a><br/>',
133             'Author: {Author}<br/>',
134             'Manufacturer: {Manufacturer}<br/>',
135             'Product Group: {ProductGroup}<br/>'
136         ],
137         // startingMarup as a new property
138         startingMarkup: 'Please select a book to see additional details',
139
140         bodyPadding: 7,
141         // override initComponent to create and compile the template
142         // apply styles to the body of the panel and initialize
143         // html to startingMarkup
144         initComponent: function() {
145             this.tpl = Ext.create('Ext.Template', this.tplMarkup);
146             this.html = this.startingMarkup;
147
148             this.bodyStyle = {
149                 background: '#ffffff'
150             };
151             // call the superclass's initComponent implementation
152             this.callParent();
153         },
154         // add a method which updates the details
155         updateDetail: function(data) {
156             this.tpl.overwrite(this.body, data);
157         }
158     });
159
160
161     /**
162      * App.BookMasterDetail
163      * @extends Ext.Panel
164      *
165      * This is a specialized panel which is composed of both a bookgrid
166      * and a bookdetail panel. It provides the glue between the two
167      * components to allow them to communicate. You could consider this
168      * the actual application.
169      *
170      */
171     Ext.define('App.BookMasterDetail', {
172         extend: 'Ext.Panel',
173         alias: 'widget.bookmasterdetail',
174
175         frame: true,
176         title: 'Book List',
177         width: 540,
178         height: 400,
179         layout: 'border',
180
181         // override initComponent
182         initComponent: function() {
183             this.items = [{
184                 xtype: 'bookgrid',
185                 itemId: 'gridPanel',
186                 region: 'north',
187                 height: 210,
188                 split: true
189             },{
190                 xtype: 'bookdetail',
191                 itemId: 'detailPanel',
192                 region: 'center'
193             }];
194             // call the superclass's initComponent implementation
195             this.callParent();
196         },
197         // override initEvents
198         initEvents: function() {
199             // call the superclass's initEvents implementation
200             this.callParent();
201
202             // now add application specific events
203             // notice we use the selectionmodel's rowselect event rather
204             // than a click event from the grid to provide key navigation
205             // as well as mouse navigation
206             var bookGridSm = this.getComponent('gridPanel').getSelectionModel();
207             ('selectionchange', function(sm, rs) {
208             if (rs.length) {
209                 var detailPanel = Ext.getCmp('detailPanel');
210                 bookTpl.overwrite(detailPanel.body, rs[0].data);
211             }
212         })
213             bookGridSm.on('selectionchange', this.onRowSelect, this);
214         },
215         // add a method called onRowSelect
216         // This matches the method signature as defined by the 'rowselect'
217         // event defined in Ext.selection.RowModel
218         onRowSelect: function(sm, rs) {
219             // getComponent will retrieve itemId's or id's. Note that itemId's
220             // are scoped locally to this instance of a component to avoid
221             // conflicts with the ComponentManager
222             if (rs.length) {
223                 var detailPanel = this.getComponent('detailPanel');
224                 detailPanel.updateDetail(rs[0].data);
225             }
226
227         }
228     });
229 // do NOT wait until the DOM is ready to run this
230 }, false);
231
232
233 // Finally now that we've defined all of our classes we can instantiate
234 // an instance of the app and renderTo an existing div called 'binding-example'
235 // Note now that classes have encapsulated this behavior we can easily create
236 // an instance of this app to be used in many different contexts, you could
237 // easily place this application in an Ext.Window for example
238 Ext.onReady(function() {
239     // create an instance of the app
240     var bookApp = new App.BookMasterDetail({
241         renderTo: 'binding-example'
242     });
243     // We can retrieve a reference to the data store
244     // via the StoreManager by its storeId
245     Ext.data.StoreManager.get('gridBookStore').load();
246 });
247