Sunday, April 4, 2010

DoubleClick the column seprator in AdvancedDataGrid and resize columns like Excel

Resizing not exactly like Excel, but double clickable and some intelligent resizing. Check the Flex 4 demo.

Click here for a demo
View source: Right click demo, or download from here

Note:The last 3 columns have the preferredWidth set to 40. The first 3 columns are dynamic.

Explanation:
We extend the AdvancedDataGridColumn and added a new property called preferredWidth. We do this so that some columns which show boolean values or simple icons do not get more width than they need. This also doesn't deprive other columns of the much needed width to display correctly.

You will need to set the AdvancedDataGrid's doubleClickEnabled=true. The AdvancedDataGrid class and the super class listen to the double click event and the method name is "mouseDoubleClickHandler". So override the method "mouseDoubleClickHandler" and after calling super.mouseDoubleClickHandler(), plugin the autoResize code.

How to know that the separator was clicked?

if (event.target && event.target is UIComponent) {
var uiComp:UIComponent = event.target as UIComponent;
if (uiComp.parent && uiComp.parent.name == "header") {
autoResizeColumns();
}
}

All separators are children of a UIComponent and the name given to this UIComponent is "header" (by the AdvancedDataGrid). How do I know this ... there is a wealth of information if you enjoy looking at the Flex SDK source code. You learn a lot too and that is how I have learnt my component development and a lot of other tricks. "There are 2 types of Flex developers, one who don't enjoy reading other peoples code and one who enjoy reading other peoples code. It is better to quickly switch to the latter side." Sorry for that funny line, it is a dialogue from a Bollywood movie which goes like ... THERE ARE 2 TYPES OF PEOPLE IN THIS WORLD, ONE WHO blah blah and OTHER WHO blah blah. THE SOONER YOU GET TO THE OTHER SIDE, THE BETTER IT IS FOR YOU. Start reading/understanding the SDK source code, you will learn a lot of nice tricks and will also help you extend the base controls.

In the above code we check if the double click happened on a component whose parent's name was "header", if yes, the separator was clicked hence call the autoResizeColumns() method. There is not much in this method except that it takes into account the preferredWidth and decides what the AdvancedDataGridColumn width should be. Notice the use of the "displayableColumns" variable. This is something I found when exploring the AdvancedDataGrid. It contains the list of visible AdvancedDataGridColumns.

autoResizeColumns(): The logic and algorithm for width calculation really depends on your needs. It could be equal divide or as per the itemRenderer's measuredWidth or whatever your project needs are.

I tried implementing the resizing based on the measuredWidth logic. Unfortunately, some components do not report the measuredWidth correctly and the experiment failed. If you do want to play with it than here is an important information you will want to know. The itemRenderer instances are all available in the listItems collection. The listItems collection contains array objects. One array for each row. Each row array contains instances of the itemRenderer for all the visible columns. Is this all documented? Maybe! I found it during one of the deep dive session.

Play with it, implement it in your projects and wow your managers and project managers.

Labels: , , ,

3 Comments:

At May 31, 2010 at 11:01 PM , Blogger Asian Kung Fu said...

Hi PJ, love to read your posts.
Your post explores topic like no other.

Just a little comment on your column resizing capacity.
Should the column width determine by the length of cell content?

 
At July 6, 2010 at 10:15 AM , Blogger Prashant Jain said...

Asian Kung Fu,
Sorry for the late response.

That is possible. In fact, I had the code for it. One problem with resizing based on content width is that the itemRenderer instance has to report the right measuredWidth. Some components like TileList do not report the correct measuredWidth.

I can point you in the direction for resizing based on content width. ADG has a listItems property. This contains multiple array objects. Each array contains instances of itemRenderer for the entire row. You would iterate through the entire listItem arrays and get the max measuredWidth and that would be the width for each column in the ADG.

Hope that explains.

 
At March 10, 2011 at 12:40 PM , Anonymous babu said...

Hi Prashanth,

I am getting the same problem in my application . Actually I am using itemrenderers for adg. then how exactly can we use this logic? I tried your code but not working for me.

 

Post a Comment

Subscribe to Post Comments [Atom]

<< Home