Persisting DataGrid column order

I found this very interesting question the Flex SDK Forum. The person, wanted to persist the users selection of the re-ordered columns across visits. A very useful addition towards a site for personalization… Here’s the scenario

The user hits your site and gets a DG(DataGrid) with multiple columns. He goes ahead and re-arranges them to his liking and leaves the app. Next time he comes back, he sees the same old screen, with his selections garbled, as the app has now re-started. Is there a way to personalize the DG for him and persist it across SWF re-loads?…

Yes… you can. I had a bit of trouble figuring it out, but got it. I first did what Rob had suggested him to do, which was to push the columns array of the DG to a shared object and to set it back when the app reloads. As he says in his code…

save it as…

var settings:SharedObject = SharedObject.getLocal(“customColumns“);
settings.data.dgColumns = dgXT.columns;

and retrieve it as…

var settings:SharedObject = SharedObject.getLocal(“customColumns“);
if (settings.data.dgColumns != null)
{
dgXT.columns = settings.data.dgColumns;
}

This doesn’t work because, trying to cast the Object to type DataGridColumn, the framework fails and throws a Run Time Error…

Then i tried to get each object from the SharedObject (which involves looping thru the SharedObject as it is of type Array) and then to cast each of the children explicitly, using the ‘as‘ operator as below, but it failed again…

var settings:SharedObject = SharedObject.getLocal(“customColumns“);
if (settings.data.dgColumns != null){
for (var i:int=0; i<settings.data.dgColumns.length; i++){
dgXT.columns[i] = settings.data.dgColumns[i] as DataGridColumn;
}
}

The third attempt was to loop through each of the items in the SharedObject array and then loop thru the object, get the properties and set it to the columns…

for (var i:int=0; i<settings.data.dgColumns.length; i++){
for (var j:* in settings.data.dgColumns[i]){
dgXT.columns[i][j] = settings.data.dgColumns[i][j]
}

}

Still it failed as some of the internal complex types (like IFactory), failed to be cast. I think, the reason is because the SharedObject , considers all the stored objects as purely Objects and does not preserve the type which they belong to.

Then Swaroop gave me an idea… why not save only those values which you require and set them back. I created an object for each of the DG columns which has details on those properties that i need to set back. Then at load-time.. I set them back.

In the method where i save the settings…

var columnArray:Array = new Array();

for(var i:int; i<dgXT.columns.length;i++){
var columnObject:Object = new Object();
columnObject.columnDataField = dgXT.columns[i].dataField as String;
columnObject.columnHeader = dgXT.columns[i].headerText as String;
columnArray.push(columnObject);
}
var settings:SharedObject = SharedObject.getLocal(“customColumns”);
settings.data.dgColumns = columnArray;

And while setting them back…

var settings:SharedObject = SharedObject.getLocal(“customColumns”);
if (settings.data.dgColumns != null)
{
var columnArray:Array = settings.data.dgColumns;
for(var i:int=0;i<columnArray.length;i++){
dgXT.columns[i].dataField = columnArray[i].columnDataField;
dgXT.columns[i].headerText = columnArray[i].columnHeader;
}
dgXT.invalidateList(); //This is to redraw the list
}

And lo… it works πŸ™‚ Feel free to add any more attributes of the column that you would like to save (for starters, may be the columnWidth). You can find the app and the source at the links below (better than the code above as it is documented πŸ˜‰ )

Application | Source

If you have a better solution… I would like to know πŸ™‚

Advertisements

12 Responses to Persisting DataGrid column order

  1. Yakov Fain says:

    I had a similar request from a client – allow users to store his preferences as to visibility of the datagrid columns. Using local SharedObject was not considered because the user could switch PC’s, and in this case the user preferences would be lost.
    I’ve created an instance of the AS3 object with user preferences, converted them into a byte array and sent it over to the server side Java to store the preferences in the database table. Next time the user logs in, the app would make a database call, retrieve the blob as a ByteArray and re-apply saved user preferences.

    One day will blog about it in more details with some code samples.

  2. Fabio Serra says:

    I would like that Flex Controls have the same features than XUL. In XUL you can insert the attribute persist and the widgets mantain his state across sessions.
    http://www.xulplanet.com/tutorials/xultu/persist.html

  3. raghunathrao says:

    yes Yakov… Good point. Using the backend storage is defenitely a good alternative to the SharedObject approach

  4. Tony Fendall says:

    Just a note that the swf you uploaded for your demo appears to be the debug version, and so it trys to connect to my debugger when I run it

    Very cool post otherwise. Thanks!

  5. raghunathrao says:

    Hey Tony… thanks for pointing this out. I have recompiled the app with Flex2.0.1, not using the debug compiler

  6. Dustin Graham says:

    I am having trouble trying to persist a column id. Has anyone experienced this?

  7. Steven Edwards says:

    Very nice example. Is it possible to preserve the column sorting as well? When you reload the state, the sorting information is not preserved.

  8. dhruv says:

    Very nice example.
    Is it possible to store datagrid column information in random order with order as field in each column information object and while setting them back they should come in order as stored in coumn information

  9. arun says:

    To Preserve the state of typed objects, say array collection of objects of type Customer, you need to use [RemoteClass(alias=”Customer”)] on each of the Customer Object and you can cache the entire collection and when you retrieve it back from the sharedcache, you will see the type “Customer” preserved.

  10. Wes says:

    Great example and posts. These methods work the same with the AdvancedDataGrid component where you could store sorting for multiple columns.

    Source and Application links are not working, but this in more than enough to get started with.

    Thanks for the great post!

  11. raghunathrao says:

    @Wes – Thankyou for bringing it to my attention. I’ve fixed the links…

  12. Chandra says:

    Thanks for the great post. But how can I preserve the Grouped Column order in ADG?

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