17 Mar 2010

Disable sort when values in Flex DataGrid change

Posted by TomeK

In a sorted Flex DataGrid/AdvancedDataGrid, rows are automatically re-sorted when you update values in the grid. This is obviously not ideal behavior when a user is trying to edit some data and rows keep rearranging themselves. The root cause of this behavior issue is ListCollectionView. This is the base class & heart of the ArrayCollection and your entire Flex grid. The solution to prevent this reordering on an already sorted list is not trivial.

There are 2 options

  1. re-implement ListCollectionView as your own (i.e. CustomListCollectionView.as)
  2. monkey patch Flex SDK ListCollectionView

The place where all the magic happens is a private method so there is no clean way to extend the class.

You can choose to make your own ArrayCollection and ListCollectionView and modify them. To do this simply copy paste those classes from Flex SDK and use as your own (rename). This is a lot of work if you want to replace them correctly so might be easier to just monkey patch them (copy paste classes exactly into your own project and make a folder structure like {PROJECT}\src\mx\collections) Google Flex monkey patch for more info.

Here is what I did.

I introduced a new variable to ListCollectionView.as

/**
* Prevents collection from reordering itself when values change, list is only re-ordered on refresh()
*/
public var enablePostSortReorder:Boolean = true; //this is what framework does by default,
// set to false to do what you want but better to specify this in a custom ArrayCollection class so that you don't change the default behavior of existing controls(AC/LCV) (see below)

In

private function handlePropertyChangeEvents(events:Array):void

Change

if (sort || filterFunction != null)

to

if (enablePostSortReorder && (sort || filterFunction != null))

You will probably also want to extend ArrayCollection. i.e.

public class CustomArrayCollection extends ArrayCollection

public function CustomArrayCollection(source:Array = null)
{
super(source);
enablePostSortReorder = false;
}

This is the new ArrayCollection you should be binding your grid to. So myGrid.dataProvider = new CustomArrayCollection(someItems). Because you are extending the standard ArrayCollection (and AC extends ListCollectionView) everything will ‘just work’.

The usage of your new CustomArrayCollection is same as before. You still set sort on it myItems.sort = someSort. And you still call myItems.refresh() after. This change will not affect default sort behavior. Notice that the method we modified is only fired when propertyChange happens. If you trace it back up the stack you will see its not connected to the refresh() method called when you change sort (be it programatically or via clicking header and having Flex grid do it for you).

Hope this helps, I’ve been using this solution for a while now in a very big ADG.

Subscribe to Comments

8 Responses to “Disable sort when values in Flex DataGrid change”

  1. [...] post: #Sharply Flexing » Blog Archive » Disable sort when values in Flex … Creating an Enterprise Flex Grid – Dynamic dataProvider properties …Edmonton's [...]

     
  2. How about using disableAutoUpdate?

     

    Alpana

  3. Yes you’re right, I should have talked about disableAutoUpdate a bit more. It is a good first option if you don’t care about propertyChanged being dispatched and updating your view.

    If you are using column footers or updating some other cells on the same row disableAutoUpdate just doesn’t cut it. You need that propertyChanged to be raised so you can update your model and consequently have that update the view.

    If you programmatically update the value of the model (your dataProvider ArrayCollection) and disableAutoUpdate=true, the Grid will not refresh.

     

    TomeK

  4. Hi Tomek..this monkey patch works with a demo app i created but when i integrated with our project, it doesnt work. We had placed traces in the ListCollectionView to see if it is getting invoked, but it doesnt. I am suspecting there might be some build time (compile time behavior difference). Can you provide some inputs?

     

    Atul

  5. 2 questions Atul:
    1) are you using RSL’s? If so, it’s a bit more complicated but doable; essentialy what you need to do is create a SWF of ONLY your monkey patch and load it before the Framework RSL’s get loaded.

    Check out James Ward’s link or google.
    http://www.jamesward.com/2009/03/10/flex-monkey-patching-and-framework-rsls/

    2) are you are patching this inside a Flex library? If you consider copying over your file to where your main Application is. Interestingly Flex won’t complain about duplicate framework files in multiple projects.

    Let me know if that helped

     

    TomeK

  6. Does this work with Flex 4? I tried using this technique, but when i run it as Web Application it always picks up from the Flex library and not the patch… i tried preloading ListCollectionView.as but did not help much… let me know how to get this working in Flex 4 Deployed Application… i am not using RSL

     

    Danjy

  7. Danjy.

    ListCollectionView class in Flex 4 is almost identical to the Flex 3 one. Unfortunately I’m still mostly working on Flex 3 and haven’t experimented with monkey patching in Flex 4. But your issue sounds like a simple case of getting monkey patching in general to work using your configuration; this a good google search can help better than I. good luck and let me know if you find something that works.

     

    TomeK

  8. For a good FlexCoders discussion on this topic with none other then the great Alex Harui check out

    http://www.mail-archive.com/flexcoders@yahoogroups.com/msg132563.html

     

    TomeK

Leave a Reply

Message: