Sunday, June 26, 2011

Nested grids using rowexpander

As we all know Extjs is one of the powerful javascript UI frameworks which helps to achieve complex UI functionalities in an easy way. One such complex UI functionality is to show a grid within another grid i.e. having nested grids.

There could be various ways to show nested grids, but using rowexpander it is lot more easy to show nested grids. So today we will see how to show nested grids using rowexpander.

Firstly we will see how to add the rowexpander plugin to a grid. To add the rowexpander to a grid you have to follow two simple steps. 
Step 1 :  You have to add the rowexpander component into the parent grid plugins. So in your parent grid, you have to just add a plugins config and specify the rowexpander over there.
plugins : new Ext.grid.RowExpander(
{
   tpl: new Ext.XTemplate('<div style="overflow:auto;" class="detailData">', '', '</div>')
})
Step 2 : In order to collapse and show the nested grid a column needs to specified which holds the collapse/expand icons for rowexpander. For this you have to add the same rowexpander component into the parent grid columns.

Now that we have added rowexpander component into the parent grid, we will take a look at how to render nested/child grid with rowexpander.
If you have noticed within the rowexpander template a div is specified with the detailData class. This div acts as a place holder for the nested grid. To add the nested grid into this div we listen the 'expand' event of the row expander and render our nested grid into the detailData div body.
expand : function(ex, record, body, rowIndex) {
    if(Ext.DomQuery.select("div.x-panel-bwrap", body).length == 0) {
        var innerRowDiv = Ext.DomQuery.select("div.detailData", body)[0];
        //Prepare nested grid config over here and render it to innerRowDiv variable.
    }
}

Lets gather all the above pieces into an example.For our example we will define both parent and child grid as the Extjs EditorGridPanel.

Here we define the rowexpander component and define the the nested grid to be shown using rowexpander.



Now we define the parent grid and add the rowexpander plugin into it and into its columns.





Try the above example to get the nested grids using Extjs and you will realize how easy it is to show nested grids using rowexpander.

Note : wherever necessary use your custom variables/components like store etc. Also you can use normal Extjs grid for any parent and/or nested grid. If you are using rowexapnder from ux then replace Ext.grid.Rowexpander with Ext.ux.grid.RowExpander

5 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Hi Yogesh,

    How to use this code in MVC structure?? I want to create Rowexpander for Parent grid with nested grid. Values getting from JSON. parent will get value from main object. child Grid will get value from Inner JSON object. How to create 2 separate root?

    Thanks in advance.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Hi Yoghesh,

    Thanks for the detailed tutorial. I was able to get the innergrid using RowExpander.

    I have one problem though, selecting a row in innergrid is actually selecting corrsponding row in the parent grid as well, even after using stopEvent on rowClick event for innerGrid.

    Did you encounter this probelm? any info on this issue will be highly helpful..

    Thanks

    ReplyDelete
    Replies
    1. I suspect stopEvent() can really stop the invocation of row selection.
      May be you can add a hack to force an exception within the event handler.
      For e.g:
      Define id for child inner grid so that it can be fetched with id. Add an event handler on parent grid.
      rowmousedown : function(parentGrid, rowIndex, event){
      if(childGrid && event.within(childGrid.getEl())){
      fakeEvent.stopEvent(); //will cause failure as fakeEvent var. will not be defined
      }
      }

      Although this is a hack but may suffice the purpose.

      Delete