22 October 2008

Refresh a Flex DataGrid

To force a Flex DataGrid to refresh its data (say, after you've updated it), you can call the invalidateDisplayList() method. This causes Flex to in turn execute the component's updateDisplayList() method. This came in handy while writing an image-upload app; after the image is uploaded, I needed the DataGrid's selectedItem to show the image it was associated with; in the overridden set data() method of the itemRenderer, there's code to do a load() of the image from the server.


Alex C said...

The above method sometimes worked and sometimes didn't; found a solution to the problem,

* Changed the Java servlet to concatenate the time in milliseconds to the filename, ensuring it will be unique. Earlier, the filename for that record was the same as its ID; this increased the likelihood of caching.
* Modified the Flex app to refresh the dataProvider for the grid with each upload. Based on a tip by a blog (http://joelhooks.com/2008/02/07/flex-preventing-datagrid-scrolling-when-the-dataprovider-is-updated/),
I'm able to put the user back at the same record again after the refresh.

Alex C said...

It appears that the filename was the issue all along. Just setting the filename of the image to something unique on the server can fix the issue without having to refresh the grid's dataprovider.

On the UPLOAD_COMPLETE_DATA event handler, call the invalidateDisplayList() method on your datagrid. Then the overriden set data() method of your itemRenderer should handle the rest correctly.

molaro said...

Per the initial post, if your dataprovider is an ArrayCollection, then the invalidateDisplayList() will work.

However, if it's an Array, it seems that invalidateList() is the method for that.

My DG uses an Array as the dataProvider, and once I added myDGid.invalidateList(), it updated in real time as expected. Hope this helps.

Alex C said...

Thanks, molaro. After much trial-and-error, I discovered that it is the myADG.invalidateDisplayList(). It uses an ArrayCollection, so this makes sense.

mandy said...

Hey guy, may i know where shud i insert the invalidatelist()?It is not a define methos in datagrid. Or i shud write my own function?Thanks

mandy said...

May I know where to insert the invalidateList()?It shud be written or it is a define method?

Alex C said...

Hi, Mandy. In my case, I was uploading a file to the server via Flex; in the DataEvent.UPLOAD_COMPLETE_DATA event handler, I have the following code:

public function doUploadComplete(event:DataEvent):void
//... other code

As molaro pointed out, you'd want to call the invalidateDisplayList() on your datagrid (or advanced datagrid) if it's using ArrayCollection. If it's using an Array, use the invalidateList() method on your datagrid.

Hope this helps.

mandy said...

Hey Alex,

It seems like cant work in my application. I think the main rpoblem is I call me php page inside a mx:xml tag.On initapp(), I assign the xml into an arraycollection and then bind it to the datagrid. Do u hv any suggestion for me to refresh the datagrid?I have try the invalidatedisplaylist on timerComplete() event. It cant work. However, still thanks for your help.

Alex C said...

Correction to earlier post: You'd call the invalidateList() without using the datagrid. It's called by itself.

Alex C said...

Hi, Mandy. What event occurs that will need the datagrid to be refreshed? You should put the myDataGrid.invalidateDisplayList() (if you're using an ArrayCollection) in the event handler code for that;

In my app, I'm uploading a file to the server and need to refresh the grid once the upload has completed successfully. In its event handler, I've got the myDataGrid.invalidateDisplayList() as the last line of code in the method.

Steve H said...

worked perfectly - thanks!

Alex C said...

You're welcome. Glad it helped.

brad said...

What if the dataprovider is an object comin in from ZendAMF? These approaches do not seem to work in that case

Alex C said...

Hi, Brad. Have you tried calling grid.dataProvider.refresh()?

Pedro varela said...

Hey, it isn't working for me..

My problem is this, I got a mailbox UI, on replying a message I have to change the icon as it correspond.. i'm doing whene all the process finish,

but it doesn't work, any idea?

Alex C said...

Hi, Pedro. You need to use an itemRenderer. Inside that, you must override the set data() method:

override public function set data(value:Object):void {
super.data = value;
// code here to check the
// column value that determines
// icon image, such as this:
if (value.messageStatus == 'sent'){
// set your itemRenderer's
// image tag source to a
// different graphic
else {
// set your itemRenderer's
// image source to the
// default graphic

Hope this helps.

Pedro varela said...

Alex thanks for your response..

Well I don't know if that works for my code, the type icon class is asigned inside the Message core class, the IR is just the Image class.. but I'm gonna try something.. thanx again..

Alex C said...

Don't forget the Flex Coders Yahoo Group: http://groups.yahoo.com/phrase/flexcoders

And also the Adobe Flex Forum: http://forums.adobe.com/community/flex/flex_general_discussion;jsessionid=FA2FA0A56E26B1D8780D01083E4D179A.node0

Bartosz Kosarzycki said...

In my case just calling invalidateList() on DataGrid is not enough. I had my DataGrid bound to an ArrayList that was downloaded from MySQL data table. I had to refresh the table and then call invalidateList(). Details here

Karthik said...

Alex, I had the same issue as Peter. Your solution dated August 20, 2009 8:35 AM worked for me!

Thanks a ton!

Alex C said...

You're welcome, Karthik. Glad you found it useful :)

Tushar said...

Hi Alex,
I need your help, I have a data Grid and each row contain the combo box, each of grid row's are different color. Now i want to change the grid row color using combo box, means suppose grid row have golden color and i select blue color from combo box then blue color applies to particular grid row


Anonymous said...

I need your help i want to set the selction back after editing the datgrid also the soring should be maintained. while in case of adding the selected item should be newly added itemm...please help me...mail me to vivek.shukla.csit@gmail.com


Alex C said...

Hi, Anonymous. My recommendation is to post your question to http://stackoverflow.com. They've helped me a lot in doing this sort of thing.

Anonymous said...

I'm using a AdvancedDataGrid with xmlListCollection. Also using a item renderer for the items in the AdvancedDataGrid. When I resize the browser(specially IE8), the items are overlapping with each others. Any Solution?

Alex C said...

On the browser resize issue, try this: http://stackoverflow.com/q/3816299/177416

Anonymous said...

How to refresh a dataGrid view when the data source is a xmlListCollection?? I tried with xmlListCollection.refresh().

Anonymous said...

I have post a query on March 9, 2012 9:43 AM and Alex replied to view http://stackoverflow.com/q/3816299/177416. I give the AdvancedDataGrid width 100% and also its parent container, but the problem remain the same.

Tameem said...

i have a datagrid that is populated from a SQL database with the PHP back end. i am using HTTPService to call the PHP file.

my datagrid dataProvider is like this

how can i update the datagrid instantly when a new data is inserted in the SQL database. Please help me on this...