Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Ext JS Grid Grouping Tutorial

DZone's Guide to

Ext JS Grid Grouping Tutorial

· Web Dev Zone
Free Resource

Learn how to build modern digital experience apps with Crafter CMS. Download this eBook now. Brought to you in partnership with Crafter Software

This tutorial shows you how to create a grouped grid in Ext JS. Ext JS grid grouping is a common scenario in business applications where users need to analyze tabular data grouped by different attributes. The Ext JS application that you will create in this tutorial will render an Ext JS grid containing fictional data describing model cars. This article is part of a series of Ext JS tutorials that I have posted on jorgeramon.me.

grid-grouping-2

Creating an Ext JS Project from Scratch

We will get started by creating the directories for our sample Ext JS application. Let’s go ahead and create the directories as depicted in the screenshot below.

grid-grouping-files-1

This is a typical Ext JS project structure with an app directory under which we’ve placed the model, store and view directories. We will not create a controller folder because for this simple example we will use the Ext.Application instance that we will create as the only controller in the app.

Next, we will create the file that hosts our Ext JS application. Let’s name it grid-grouping.html and place it in the root directory of the project. Here’s the code that goes in the file:

<!DOCTYPE HTML >
<html>
<head>
    <title></title>
    <link href="../../../Lib/extjs/5.0.1/packages/ext-theme-neptune/build/resources/ext-theme-neptune-all.css" rel="stylesheet" />
    <script src="../../../Lib/extjs/5.0.1/ext-all.js"></script>
    <script src="../../../Lib/extjs/5.0.1/packages/ext-theme-neptune/build/ext-theme-neptune.js"></script>
    <script src="app.js"></script>
</head>
<body>
</body>
</html>

Remember to make sure that the css and script references to the Ext JS library in the head section of the html document are pointing to the correct directories in your development workstation. The references above work for my development environment.

In the head section we also have an entry for the app.js file, which we need to add to the root directory of the project, as shown below.

grid-grouping-files-2

Let’s open app.js and type the following Ext JS application definition:

Ext.application({
    name: 'App',
    autoCreateViewport: true,
    launch: function () {
    }
});

This is a super simple Ext JS application. We are using the autoCreateViewport config to instruct the app to load and instantiate the viewport, which we will create in a few minutes, before firing the launch function. We will leave the launch function empty because in this example we do not need to execute any logic within the function.

The Ext JS Model

To represent the model cars data that we will ultimately render in the grid, we will use the ModelCar Ext JS model Class. This Class goes in the ModelCar.js file that we will add to the model directory of the project.

grid-grouping-files-3

This is how we are going to define the ModelCar Model:

Ext.define('App.model.ModelCar', {
    extend: 'Ext.data.Model',
    fields: [
        { name: 'id', type: 'int' },
        { name: 'category', type: 'string' },
        { name: 'name', type: 'string' },
        { name: 'vendor', type: 'string' }
    ]
});

Back in the app.js file we need to add a models config to the Ext JS application just so the app knows that it has a dependency on the ModelCar module and it needs to load it as part of the app.

Ext.application({
    name: 'App',
    models: ['ModelCar'],
    autoCreateViewport: true,    
    launch: function () {
    }
});

Creating a Store to Feed The Ext JS Grid

Now we are going to focus on the Ext JS Store that will feed the grid. Let’s add a ModelCars.js file to the store directory of the project.

grid-grouping-files-4

We will type the following definition in the file:

Ext.define('App.store.ModelCars', {
    extend: 'Ext.data.Store',
    model: 'App.model.ModelCar',
    groupField: 'category',
    groupDir: 'ASC',
    sorters: ['name'],
    data: [
        { 'id': 1, 'category': 'Trucks and Buses', 'name': '1940 Ford Pickup Truck', 'vendor': 'Motor City Art Classics' },
        { 'id': 2, 'category': 'Trucks and Buses', 'name': '1957 Chevy Pickup', 'vendor': 'Gearbox Collectibles' },
        { 'id': 3, 'category': 'Classic Cars', 'name': '1972 Alfa Romeo GTA', 'vendor': 'Motor City Art Classics' },
        { 'id': 4, 'category': 'Motorcycles', 'name': '2003 Harley-Davidson Eagle Drag Bike', 'vendor': 'Studio M Art Models' },
        { 'id': 5, 'category': 'Motorcycles', 'name': '1996 Moto Guzzi 1100i', 'vendor': 'Motor City Art Classics' },
        { 'id': 6, 'category': 'Classic Cars', 'name': '1952 Alpine Renault 1300', 'vendor': 'Studio M Art Models' },
        { 'id': 7, 'category': 'Classic Cars', 'name': '1993 Mazda RX-7', 'vendor': 'Motor City Art Classics' },
        { 'id': 9, 'category': 'Classic Cars', 'name': '1965 Aston Martin DB5', 'vendor': 'Motor City Art Classics' },
        { 'id': 10, 'category': 'Classic Cars', 'name': '1998 Chrysler Plymouth Prowler', 'vendor': 'Unimax Art Galleries' },
        { 'id': 11, 'category': 'Trucks and Buses', 'name': '1926 Ford Fire Engine', 'vendor': 'Studio M Art Models' },
        { 'id': 12, 'category': 'Trucks and Buses', 'name': '1962 Volkswagen Microbus', 'vendor': 'Unimax Art Galleries' },
        { 'id': 13, 'category': 'Trucks and Buses', 'name': '1980’s GM Manhattan Express', 'vendor': 'Motor City Art Classics' },
        { 'id': 13, 'category': 'Motorcycles', 'name': '1997 BMW F650 ST', 'vendor': 'Gearbox Collectibles' },
        { 'id': 13, 'category': 'Motorcycles', 'name': '1974 Ducati 350 Mk3 Desmo', 'vendor': 'Motor City Art Classics' },
        { 'id': 13, 'category': 'Motorcycles', 'name': '2002 Yamaha YZR M1', 'vendor': 'Motor City Art Classics' }
    ]
})

The Ext JS model config of the Store is set to the ModelCar model that we created a couple of minutes ago. No surprises there.

A couple of things that I don’t want you to miss in the Store’s definition are the groupField and groupDir configs, which tell the Store which field and in which direction to group by:

groupField: 'category',
groupDir: 'ASC',

Also note how we use the sorters config to sort the grouped records by the name field.

Finally, as the data config indicates, we are using a hard-coded array as the data for the Store. We are using hard-coded data in order to keep the example short.

Let’s make the application aware of the ModelCars Store by adding the stores config in the app.js file:

Ext.application({
    name: 'App',
    models: ['ModelCar'],
    stores: ['ModelCars'],
    autoCreateViewport: true,    
    launch: function () {
    }
});

Creating the Ext JS Viewport

The app’s Viewport is where we will define the Ext JS grouped grid. Let’s create the Viewport.js file in the project’s view directory:

grid-grouping-files-5

Here’s the code that we will add to the Viewport’s file:

Ext.define('App.view.Viewport', {
    extend: 'Ext.container.Viewport',
    requires: ['Ext.grid.Panel'],
    style: 'padding:25px',
    layout: 'vbox',
    items: [
       {
           xtype: 'gridpanel',
           width: 650,
           height: 475,
           title: 'Ext JS Grid Grouping',
           store: 'ModelCars',
           columns: [
                {
                    text: 'Id',
                    hidden: true,  
                    dataIndex: 'id'
                },
                {
                    text: 'Name',
                    sortable: true,             
                    dataIndex: 'name',
                    flex: 3                      
                },
                {
                    text: 'Vendor',
                    sortable: true,
                    dataIndex: 'vendor',
                    flex:2
                },
                {
                    text: 'Category',
                    sortable: true,
                    dataIndex: 'category',
                    flex: 2
                }
           ],
           features: [{
               ftype: 'grouping',
               // You can customize the group's header.
               groupHeaderTpl: '{name} ({children.length})',
               enableNoGroups:true
           }]
       }
    ]
});

Let’s review this Viewport definition in detail. First, we are using the Viewport’s requires config to tell the Ext JS Loader that it needs to load the Ext.grid.Panel Class as part of the application. Then, we define our Grid instance within the items config of the Viewport.

We are telling the grid to use the ModelCars Ext JS Store as its data source by setting the store config to ‘ModelCars’. This works because Ext JS components pass the value of the store config to the Ext.data.StoreManager Class, which can look up or create a Store, depending on whether the store config’s value is a store id, a store’s instance or a store’s configuration.

We are using the grid’s columns config to define four columns: Id, Name, Vendor and Category. Setting the hidden config of the Id column to true will make the column invisible to the user. The sortable config of the visible columns is true to allow users to sort by those columns.

Setting Up Ext JS Grid Grouping

The features config allows us to specify one or more features to be added to the grid. As explained in the Ext JS docs, an Ext JS Feature is a Class that provides hooks that you can use to inject functionality into the grid at different points during the grid’s creation cycle. This is a clever approach to maintaining the grid’s core as lightweight as possible, while allowing for advanced functionality to be “plugged in” as needed.

Currently, ExtJS provides the following grid features:

  • Grouping, through the Ext.grid.feature.Grouping Class.
  • Grouping Summary, though the Ext.grid.feature.GroupingSummary Class.
  • Row Body, though the Ext.grid.feature.RowBody Class.
  • Summary, through the Ext.grid.feature.Summary Class.

In our app we are only using the grouping feature. We set the ftype property to ‘grouping’ to signal the grid that we will use the grouping feature. The groupHeaderTpl config allows us to enter a template for the group headers of the grid:

groupHeaderTpl: '{name} ({children.length})'

This template will render the name of the group along with the number of records in the group, producing a result similar to this picture:

grid-grouping-3

Setting the enableNoGroups config to true will let the user turn off grouping in the grid.

Note that if we wanted to specify multiple features, we would need to add them to the features config in array notation.

One last step before we are ready to test the app. Let’s return to the app.js file and the add views config, where we will place a reference to the Viewport Class that we just created:

Ext.application({
    name: 'App',
    models: ['ModelCar'],
    stores: ['ModelCars'],
    views: ['Viewport'],
    autoCreateViewport: true,    
    launch: function () {
    }
});

Now we can test the app on a browser. Upon application load, the grid’s records are grouped by the Category field, and sorted by the Name field:

grid-grouping-2

Summary and Next Steps

In this tutorial we reviewed the steps needed to create a grouped grid in Ext JS, and we learned that this process involves attaching a “Grouping” feature to an Ext JS grid that is connected to a grouped Ext JS Store.

As next steps, I would suggest that you explore how to use the “Grouping Summary” and “Summary” features of the Ext JS grid, which are commonly used together with the “Grouping” feature. I will cover these features in future tutorials.

Don’t forget to sign up for my mailing list so you can be among the first to know when I publish the next update.

Download the Source Code

Download the Ext JS grouped grid example here: Ext JS grid grouping tutorial on GitHub

Crafter is a modern CMS platform for building modern websites and content-rich digital experiences. Download this eBook now. Brought to you in partnership with Crafter Software.

Topics:
css ,html5 ,javascript ,tips and tricks

Published at DZone with permission of Jorge Ramon, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}