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