14/04/2014

ExtJs grid panel column resize to fit data width vs. resize to fit container

It is possible to resize a grid panel column to fit the contents width and it is also possible to resize the grid panel column to fit the size of the grid panel itself. These are two different things and should not be confused.

I will use the setup from my previous post: http://extjs-intro.blogspot.com/2014/04/basic-anatomy.html.You need at least this setup if you are to repeat any of the steps.

For reference, this is the grid panel example code from the ExtJS documentation: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.grid.Panel.

Let us now increase the width of the panel to 800 pixels to see what happens:



Ext.application({
 name : 'MyApp',
 launch : function () {
 /* Put example code after this line */
  Ext.create('Ext.data.Store', {
   storeId : 'simpsonsStore',
   fields : ['name', 'email', 'phone'],
   data : {
    'items' : [{
      'name' : 'Lisa',
      "email" : "lisa@simpsons.com",
      "phone" : "555-111-1224"
     }, {
      'name' : 'Bart',
      "email" : "bart@simpsons.com",
      "phone" : "555-222-1234"
     }, {
      'name' : 'Homer',
      "email" : "home@simpsons.com",
      "phone" : "555-222-1244"
     }, {
      'name' : 'Marge',
      "email" : "marge@simpsons.com",
      "phone" : "555-222-1254"
     }
    ]
   },
   proxy : {
    type : 'memory',
    reader : {
     type : 'json',
     root : 'items'
    }
   }
  });

  Ext.create('Ext.grid.Panel', {
   title : 'Simpsons',
   store : Ext.data.StoreManager.lookup('simpsonsStore'),
   columns : [{
     text : 'Name',
     dataIndex : 'name'
    }, {
     text : 'Email',
     dataIndex : 'email',
     flex : 1
    }, {
     text : 'Phone',
     dataIndex : 'phone'
    }
   ],
   height : 200,
   width : 800,
   renderTo : Ext.getBody()
  });
 /* Put example code before this line */
 }
});

When we run this in the browser, we will get the following result:
Screenshot 1
The reason why column Email extends to the available space is the following line:
flex : 1

If we are to comment out this line, the screenshot will look like this:
Screenshot 2

Let us now increase the length of one of the names so that the first column is no longer wide enough to show it all. Lets make Lisa of Babylonian descent and rename her to "Lisa Nebuchadnezzar". This should be just long enough not to be shown entirely. And here's the screenshot:
Screenshot 3

Resizing the column to fit the contents can be achieved in the following way. The column will have to be manipulated. The docs we have to be looking at are not those of the grid panel but the columns: http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.grid.column.Column. Scrolling down, there is a method called: autoSize(). According to the description, this should do. We should be calling this method at runtime. To achieve this, we can do the following two operations:
  1. add a property to the column
    autoSizeColumn : true
  2. add the following block to the grid panel
    viewConfig : {
        listeners : {
         refresh : function (dataview) {
          Ext.each(dataview.panel.columns, function (column) {
           if (column.autoSizeColumn === true)
            column.autoSize();
          })
         }
        }
       },
    

The final result can be seen in the last screenshot:
Screenshot 4

For completeness, this is the final code:
Ext.application({
 name : 'MyApp',
 launch : function () {
  /* Put example code after this line */
  Ext.create('Ext.data.Store', {
   storeId : 'simpsonsStore',
   fields : ['name', 'email', 'phone'],
   data : {
    'items' : [{
      'name' : 'Lisa Nebuchadnezzar',
      "email" : "lisa@simpsons.com",
      "phone" : "555-111-1224"
     }, {
      'name' : 'Bart',
      "email" : "bart@simpsons.com",
      "phone" : "555-222-1234"
     }, {
      'name' : 'Homer',
      "email" : "home@simpsons.com",
      "phone" : "555-222-1244"
     }, {
      'name' : 'Marge',
      "email" : "marge@simpsons.com",
      "phone" : "555-222-1254"
     }
    ]
   },
   proxy : {
    type : 'memory',
    reader : {
     type : 'json',
     root : 'items'
    }
   }
  });

  Ext.create('Ext.grid.Panel', {
   title : 'Simpsons',
   store : Ext.data.StoreManager.lookup('simpsonsStore'),
   columns : [{
     text : 'Name',
     dataIndex : 'name',
     autoSizeColumn : true
    }, {
     text : 'Email',
     dataIndex : 'email',
     //flex : 1
    }, {
     text : 'Phone',
     dataIndex : 'phone'
    }
   ],
   height : 200,
   width : 800,
   viewConfig : {
    listeners : {
     refresh : function (dataview) {
      Ext.each(dataview.panel.columns, function (column) {
       if (column.autoSizeColumn === true)
        column.autoSize();
      })
     }
    }
   },
   renderTo : Ext.getBody()
  })
  /* Put example code before this line */
 }
});

References:
http://www.sencha.com/forum/showthread.php?262891-Auto-fit-column-widths-instead-of-having-fix-widths
http://en.wikipedia.org/wiki/Nebuchadnezzar_I
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.grid.Panel
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.grid.column.Column
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext

3 comments:

  1. nice hack... thanks for the information :)

    ReplyDelete
  2. It's amazing that the amount of news that happens in the world every day always just exactly fits the newspaper. See the link below for more info.


    #fits
    www.ufgop.org


    ReplyDelete
  3. Thanks for this article very helpful. thanks. 24 hour truck tire repair

    ReplyDelete