(For more resources on JavaScript, see here.)
The grid panel is one of the most-used components when developing an application Ext JS 4 provides some great improvements related to this component.
The Ext JS 4 Grid panel renders a different HTML than Ext JS 3 Grid did. Sencha calls this new feature Intelligent Rendering. Ext JS 3 used to create the whole structure, supporting all the features. But, what if someone just wanted to display a simple grid? All the other features not being rendered would just be wasted, because no one was using that structure. Ext JS 4 now renders only the features the grid uses, minimizing and boosting the performance.
Before we examine the grid’s new features and enhancements, let’s take a look how to implement a simple grid in Ext JS 4:
Ext.create('Ext.grid.Panel', { store: Ext.create('Ext.data.ArrayStore', { fields: [ {name: 'book'}, {name: 'author'} ], data: [['Ext JS 4: First Look','Loiane Groner']] }), columns: [ { text : 'Book', flex : 1, sortable : false, dataIndex: 'book' },{ text : 'Author', width : 100, sortable : true, dataIndex: 'author' }], height: 80, width: 300, title: 'Simple Grid', renderTo: Ext.getBody() });
As you can see in the preceding code, the two main parts of the grid are the store and the columns declarations. Note, as well, names of both store and model fields always have to match with the column’s dataIndex (if you want to display the column in the grid).
So far, nothing has changed. The way we used to declare a simple grid in Ext JS 3 is the same way we do for Ext JS 4.
However, there are some changes related to plugins and the new features property. We are going to take a closer look at that in this section.
Let’s dive into the changes!
Ext JS 4 organizes all the column classes into a single package—the Ext.grid.column package.
We will explain how to use each column type with an example. But first, we need to declare a Model and a Store to represent and load the data:
Ext.define('Book', { extend: 'Ext.data.Model', fields: [ {name: 'book'}, {name: 'topic', type: 'string'}, {name: 'version', type: 'string'}, {name: 'released', type: 'boolean'}, {name: 'releasedDate', type: 'date'}, {name: 'value', type: 'number'} ] }); var store = Ext.create('Ext.data.ArrayStore', { model: 'Book', data: [ ['Ext JS 4: First Look','Ext JS','4',false,null,0], ['Learning Ext JS 3.2','Ext JS','3.2',tr ue,'2010/10/01',40.49], ['Ext JS 3.0 Cookbook','Ext JS','3',true,'2009/10/01',44.99], ['Learning Ext JS','Ext JS','2.x',true,'2008/11/01',35.99], ] });
Now, we need to declare a grid:
Ext.create('Ext.grid.Panel', { store: store, width: 550, title: 'Ext JS Books', renderTo: 'grid-example', selModel: Ext.create('Ext.selection.CheckboxModel'), //1 columns: [ Ext.create('Ext.grid.RowNumberer'), //2 { text: 'Book',//3 flex: 1, dataIndex: 'book' },{ text: 'Category', //4 xtype:'templatecolumn', width: 100, tpl: '{topic} {version}' },{ text: 'Already Released?', //5 xtype: 'booleancolumn', width: 100, dataIndex: 'released', trueText: 'Yes', falseText: 'No' },{ text: 'Released Date', //6 xtype:'datecolumn', width: 100, dataIndex: 'releasedDate', format:'m-Y' },{ text: 'Price', //7 xtype:'numbercolumn', width: 80, dataIndex: 'value', renderer: Ext.util.Format.usMoney },{ xtype:'actioncolumn', //8 width:50, items: [{ icon: 'images/edit.png', tooltip: 'Edit', handler: function(grid, rowIndex, colIndex) { var rec = grid.getStore().getAt(rowIndex); Ext.MessageBox.alert('Edit',rec.get('book')); } },{ icon: 'images/delete.gif', tooltip: 'Delete', handler: function(grid, rowIndex, colIndex) { var rec = grid.getStore().getAt(rowIndex); Ext.MessageBox.alert('Delete',rec.get('book')); } }] }] });
The preceding code outputs the following grid:
In Ext JS 3, when we wanted to add a new functionality to a grid, we used to create a plugin or extend the GridPanel class. There was no default way to do it. Ext JS 4 introduces the Ext.grid.feature.Feature class that contains common methods and properties to create a plugin.
Inside the Ext.grid.feature packages, we will find seven classes: AbstractSummary, Chunking, Feature, Grouping, GroupingSummary, RowBody, and Summary.
A feature is very simple to use—we need to add the feature inside the feature declaration in the grid:
features: [{ groupHeaderTpl: 'Publisher: {name}', ftype: 'groupingsummary' }]
Let’s take a look at how to use some of these native grid features.
Grouping rows in Ext JS 4 has changed. Now, Grouping is a feature and can be applied to a grid through the features property.
The following code displays a grid grouped by book topic:
Ext.define('Book', { extend: 'Ext.data.Model', fields: ['name', 'topic'] }); var Books = Ext.create('Ext.data.Store', { model: 'Book', groupField: 'topic', data: [{ name: 'Learning Ext JS', topic: 'Ext JS' },{ name: 'Learning Ext JS 3.2', topic: 'Ext JS' },{ name: 'Ext JS 3.0 Cookbook', topic: 'Ext JS' },{ name: 'Expert PHP 5 Tools', topic: 'PHP' },{ name: 'NetBeans IDE 7 Cookbook', topic: 'Java' },{ name: 'iReport 3.7', topic: 'Java' },{ name: 'Python Multimedia', topic: 'Python' },{ name: 'NHibernate 3.0 Cookbook', topic: '.NET' },{ name: 'ASP.NET MVC 2 Cookbook', topic: '.NET' }] }); Ext.create('Ext.grid.Panel', { renderTo: Ext.getBody(), frame: true, store: Books, width: 350, height: 400, title: 'Books', features: [Ext.create('Ext.grid.feature.Grouping',{ groupHeaderTpl: 'topic: {name} ({rows.length} Book{[values.rows.length > 1 ? "s" : ""]})' })], columns: [{ text: 'Name', flex: 1, dataIndex: 'name' },{ text: 'Topic', flex: 1, dataIndex: 'topic' }] });
In the groupHeaderTpl attribute, we declared a template to be displayed in the grouping row. We are going to display one of the following customized strings, depending on the number of books belonging to the topic:
The string comprises of the topic name ({name}) and the count of the book for the topic ({rows.length}).
In Ext JS 3, we still had to declare a grouping field in the store; but, instead of a Grouping feature, we used to declare GroupingView, as follows:
view: new Ext.grid.GroupingView({ forceFit:true, groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Books" : "Book"]})' })
If we execute the grouping grid, we will get the following output:
The GroupingSummary feature also groups rows with a field in common, but it also adds a summary row at the bottom of each group.
Let’s change the preceding example to use the GroupingSummary feature:
Ext.create('Ext.grid.Panel', { renderTo: Ext.getBody(), frame: true, store: Books, width: 350, height: 400, title: 'Books', features: [{ groupHeaderTpl: 'Topic: {name}', ftype: 'groupingsummary' }], columns: [{ text: 'Name', flex: 1, dataIndex: 'name', summaryType: 'count', summaryRenderer: function(value){ return Ext.String.format('{0} book{1}', value, value !== 1 ? 's' : ''); } },{ text: 'Topic', flex: 1, dataIndex: 'topic' }] });
We highlighted two pieces in the preceding code. The first line is the feature declaration: in the previous example (Grouping) we created the feature using the Ext.create declaration. But if we do not want to explicitly create the feature every time we declare, we can use the ftype property, which is groupingsummary in this example.
The groupingsummary that we added to the grid’s name column is in the second line of highlighted code. We declared a summaryType property and set its value as count. Declaring the summaryType as count means we want to display the number of books in that particular topic/category; it is going to count how many records we have for a particular category in the grid. It is very similar to the count of the PL/SQL language. Other summary types we can declare are: sum, min, max, average (these are self-explanatory).
In this example, we want to customize the text that will be displayed in the summary, so we are going to use the summaryRenderer function. We need to pass a value argument to it, and the value is the count of the name column. Then, we are going to return a customized string that is going to display the count (token {0}) and the string book or books, depending on the count (if it is more than 1 we add s at the end of the string book).
Ext.String.format is a function that allows you to define a tokenized string and pass an arbitrary number of arguments to replace the tokens. Each token must be unique and must increment in the format {0}, {1}, and so on.
The preceding code will output the following grid:
The GroupingSummary feature adds a row at the bottom of each grouping. The Summary feature adds a row at the bottom of the grid to display summary information. The property configuration is very similar to that for GroupingSummary, because both classes are subclasses of AbstractSummary (a class that provides common properties and methods for summary features).
Ext.create('Ext.grid.Panel', { renderTo: Ext.getBody(), frame: true, store: Books, width: 350, height: 300, title: 'Books', features: [{ ftype: 'summary' }], columns: [{ text: 'Name', flex: 1, dataIndex: 'name', summaryType: 'count', summaryRenderer: function(value){ return Ext.String.format('{0} book{1}', value, value !== 1 ? 's' : ''); } },{ text: 'Topic', flex: 1, dataIndex: 'topic' }] });
The only difference from the GroupingSummary feature is the feature declaration itself. The summayType and summaryRenderer properties work in a similar way. The preceding code will output the following grid:
The rowbody feature adds a new tr->td->div in the bottom of the row that we can use to display additional information.
Here is how to use it:
Ext.create('Ext.grid.Panel', { renderTo: Ext.getBody(), frame: true, store: Books, width: 350, height: 300, title: 'Books', features: [{ ftype: 'rowbody', getAdditionalData: function(data, idx, record, orig) { return { rowBody: Ext.String.format( '
->topic: {0}', data.topic) }; } }, { ftype: 'rowwrap' }], columns: [{ text: 'Name', flex: 1, dataIndex: 'name' }] });
In the preceding code, we are not only displaying the name of the book; we are using the rowbody to display the topic of the book as well.
The first step is to declare the rowbody feature. One very important thing to be noted is that rowbody will be initially hidden, unless you override the getAdditionalData method.
If we execute the preceding code, we will get the following output:
I remember deciding to pursue my first IT certification, the CompTIA A+. I had signed…
Key takeaways The transformer architecture has proved to be revolutionary in outperforming the classical RNN…
Once we learn how to deploy an Ubuntu server, how to manage users, and how…
Key-takeaways: Clean code isn’t just a nice thing to have or a luxury in software projects; it's a necessity. If we…
While developing a web application, or setting dynamic pages and meta tags we need to deal with…
Software architecture is one of the most discussed topics in the software industry today, and…