Flex App Basics 2: Extending Basic View Behaviour
Following on from yesterday's post about defining Flex DataGrid columns on the server I want to take it a step further today and use the column definitions to further extend the behaviour of the grid.
Take a look at either the snapshot below or the updated demo and you'll see a PopupButton on the top right of the grid. When you click this "columns" button up pops a choice of columns to toggle on and off in the grid, as highlighted below:
To do this, the first thing I did was extend the XML at the server, by adding a "viewByDefault" attribute to the column tag.
If the viewByDefault attribute is present and set to "false" then the column won't appear unless the user chooses to show it by using the Columns button, now present.
It's a simple example of how you can start adding the R in RIA to your Notes applications. I used the above approach in a reporting app for a customer and allowed them to export to Excel only the columns they were currently viewing. They loved it.
How Is It Coded?
The first thing we need to do is add the PopupButton button. Here's the MXML (Flex code) for doing that:
<mx:PopUpButton label="Columns"> <mx:popUp> <mx:Tile backgroundColor="0xFFFFFF" backgroundAlpha="0.9"> <mx:Repeater id="columnRepeater" dataProvider="{columns}"> <mx:CheckBox data="{columnRepeater.currentItem.valueOf()}" width="120" label="{columnRepeater.currentItem.@label}" selected="{!columnRepeater.currentItem.hasOwnProperty('@viewByDefault') || columnRepeater.currentItem.@viewByDefault=='true'}" change = "toggleColumn(event)" /> </mx:Repeater> </mx:Tile> </mx:popUp> </mx:PopUpButton>
This defines the button and gives it a label of "Columns". It then defines what is the "popup" for the button. Anything you put inside the popUp child element is what then appears when the user presses the button and should be something of the container type. In our case it's a Tile (which is a bit like a clever table that has as many columns as the width of its parent container will allow - wider parent = more columns and less rows). Inside our the Tile we use a Repeater to loop all the columns produce a CheckBox for each one. The change event of the CheckBox calls the function called toggleColumn, which looks like this:
private function toggleColumn(evt:Event):void { var ch:CheckBox = evt.currentTarget as CheckBox; for each (var col:AdvancedDataGridColumn in grid.columns) { if (col.dataField==ch.data.toString()){ col.visible=ch.selected; } } }
All this does is loop all the columns on the view (id="grid") looking for one which has the same dataField as the data attribute of the CheckBox that was ticked. When it finds the right column it sets its visibility based on the checked status of CheckBox. Give it a go here.
Taking It Even Further
You might have noticed the XML for the columns contained other attributes, such as "type" and "allowGrouping". If I get chance I'll touch on these tomorrow and show what else you can do to allow view modification from the server.
Hopefully you're getting an idea not just of how powerful Flex can be, but how easy it is. It might not seem it now if you're just getting in to it, but trust me, once you've got the hang of using XML and E4X along with a knowledge of what all the MXML objects are used for there's no limit to what you can do.
Jake,
Not sure if your doing this right now but it might be worth converting your returned XML to a custom object first and then binding to that.
There is a slight overhead in making the initial code more verbose but it pays off as soon as you need to make a more complex application (as I am sure you know).
If you send me your example source code I will convert it to show you what I mean.
Mark
Reply
Nice job. One feature I thought of is saving the user configured layout. Maybe you're going to add this, but if I spend 15 minutes customizing which columns appear and the column order in a view to be exactly what I needed, I'd want to either have it stay that way when I return to the page or have a way to save that layout with a name that I can call up when I wanted.
Reply
Wasn't planning on adding that Rob. But it can be done and if I feel up to it at some point I might do.
I know Jerry (Carter) added a "save search" feature to a Flex app based on my filter-building app from ages ago. Wonder if he'd mind me ripping that off...
Reply
Hi Jake,
Just to confirm , While adding columns there should be a check like this which will add the column and keep it hidden .
if ( column.@viewByDefault=="false") {
col.visible=false;
}
So code goes like ,
for each (var column:XML in columns){
var col:DataGridColumn = new DataGridColumn(column);
col.headerText=column.@label;
if ( column.@viewByDefault=="false") {
col.visible=false;
}
cols.push(col);
}
dataGrid.columns = cols;
Reply
Hi Rishi,
Woops. I should have mentioned that the code from yesterday, which builds the view in the first place needs to change in order to use this new feature.
My code differs from yours and looks like this:
col.visible = (!column.hasOwnProperty("@viewByDefault") || column.@viewByDefault=="true");
It's important to first check the column "hasOwnProperty". If it doesn't have it then the code you've written is likely to throw an error.
Jake
Reply
Show the rest of this thread
Hi Jake,
Did you try DataGrid header rendering ? For example adding combo in the column header which can be use to filter data grid items . It will be great if you share something on this .
Rishi
Reply