Nested Grid in Sencha Ext JS


Problem Statement

Ext JS grid does not have a direct plugin or component to have grid inside a grid.  This functionality will be needed when we want to show the parent and child entity data at a time.     For example : We want to show the order line items for an order under each order in an order grid. We can achieve this requirement with the help of Row Expander grid plugin, but still the grid functionality like mouseover, click, column sort, etc would not work.
In this article we will understand  the root cause for the issues and learn how to address it.

Getting Started

First get below things in place

  • Ext JS application with Ext JS 5.0 or later

Add Child Grid to Parent Grid Row with the help of RowExpander Plugin as explained below:

  • Add RowExpander Plugin to parent grid
  • Add expandbody event handler for the parent grid
  • In expandbody create a child grid instance and render it to the expanded row

With this code you will able to develop a grid as shown below:

Screen Shot 2015-05-29 at 2.40.51 pm

You can find a new plugin RowExpanderGrid extended from RowExpander plugin, which can help you add child grid to the row, more easily. It is part of the shared article code.

Now you will notice that on mouseover or click events there are lots of console errors and grid does not behave as it should. Let us see what is causing this issue.

First let us understand how the Grid inside a Grid is rendered using RowExpander plugin. The child Grid is rendered as the child of Grid Row.

Below is the HTML element structure of NestedGrid.

<table > // Every Grid row is table
<tbody>
<tr></tr> // All the columns become child td tags under this tr  tag
<tr> <grid> </tr> // This tr tag is prepared by the RowExpander plugin as row body.
 The Child grid will be rendered in side this grid.
</tbody>
</table>


Screen Shot 2015-05-27 at 6.39.28 pm

Because of this structure when mouse events fire on the child grid elements are handled by parent gridview followed by child gridview.

Ext.view.Table is the class responsible for rendering the grid view.processItemEvent is the mouse event handler for the GridView item events., Iitems here are Column Headers , Rows and cells   Now, when a mouse events fire  on child grid (i.e when the user performs any action with mouse like hovering on the child grid row element,clicking on the child grid row etc..), the processItemEvent handler of the parent grid view  is executed first followed by child gridview This handler finds the respective record from the target element and carry out the necessary operations. But, as we know, the element belongs to child grid and scope of function is parent grid. Due to this mismatch the columns and grid records are not found and it throws errors., So, the child grid processItemEvent handler is not being executed.

Let us see how to solve the issue

As discussed, the parent grid processItemEvent handler is being called., Instead, child grid processItemEvent  should be called. Our solution should avoid execution of processItemEvent handler of the parent grid. And by doing that, automatically, the child grid processItemEvent handler will be executed.

Following are the solution steps:

  1. Override Ext.view.Table class -, add a function which will figure out if the event target belongs to the same grid view or not and return the boolean value true indicating the event target belongs to the this gridview and  false indicating  event target does not belong to this gridview, as shown below
    checkTheContextIsParentGridView: function(e){
               var target = Ext.get(e.target);
               var parentGridView = target.up('.x-grid-view');
    
               if (this.getId() != parentGridView.getId()) {
                      return false;
               } else {
                      return true;
               }
        }
  2. Override processItemEvent function of Ext.view.Table Class – call the new function, that we implemented in the previous step, by passing the EventObject, call parent function if event target belong same gridview else discard the execution, as shown below.
     processItemEvent: function(record, row, rowIndex, e) {
    
            if (e.target && !this.checkTheContextIsParentGridView(e)) {
                return false;
            } else {
                return this.callParent([record, row, rowIndex, e]);
           }
    
        }
    

    With this enhancement you will be able to perform all the operation on child grid, including the roweditor for the child grid as shown below:

Screen Shot 2015-05-29 at 2.42.25 pm

You may try the code on Sencha Fiddle and let me know how did it go!

Summary

In this article we learned how to solve the issues when we add a grid inside a grid using rowexpander plugin.

References

Ext JS Docs

Ext JS Grid RowExpander plugin doc

Tagged with: , ,
Posted in Sencha ExtJS
5 comments on “Nested Grid in Sencha Ext JS
  1. Sujay says:

    Thanks for this article. Is there a way to make grid selection mutually exclusive. I mean if i select any child grid record, any previously selected record in any other child grid should be cleared and new selection should persists. Same is the case with parent & child, if i select parent row and then click on child the parent row should get dis-selected. Any suggestions would be much appreciated.

    • Phani Kiran G says:

      Hi Sujay,
      AFAIK their is not config available in the frame work to this.. We have to write code for this behavior listening select,selectionchange events on the parent and child grid and deselecting the other grid records.

  2. Sai Kumar Yerigeri says:

    how we can make this GWT ?

  3. Phani Kiran G says:

    ExtJS 6.2.0 has got rowWidget Plugin using this we can have nested grid as well.

  4. deepakpster says:

    Hi Phani,
    It’s a cool extension you have made over there and well explained. How is the behaviour on including features and plugins to either of parent or nested grids. Locked columns, summary,filtering and etc?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

We Have Moved Our Blog!

We have moved our blog to our company site. Check out https://walkingtree.tech/index.php/blog for all latest blogs.

Sencha Select Partner Sencha Training Partner
Xamarin Authorized Partner
Do More. With Sencha.

Recent Publication
%d bloggers like this: