Friday, June 19, 2009

Deleting multiple records in datagrid in Adobe Flex

Although it sound simple, I had a really hard time finding the solution to delete multiple records in datagrid in one of my projects. I was using XMLListCollection as a dataprovider and a single record could be deleted with removeItemAt(index) method. However, for the multiple selection, Flex stores the indices of the selected rows in an array. If I iterate through these indices and start removing item using the index, as soon as the first record is removed, XMLListCollection re-arrange itself and remaining items get the new index which is not valid against the existing indices in the array. Also, there is no way that we can find if the row is selected just by iterating through the collection of rows. The frustrating part was that Google was not able to provide any answer. So, after spending few hours with couple of failed attempts, something suddenly came to my mind. What-if I start removing item from the bottom of the collection, instead from the top. This will not change the indices of existing items. This worked for items selected in an order. However, if I select items in the datagrid randomly, it fails. Flex pushes the indices of the items to an array as they are selected. That means the indices are not in order. So, there is a method Array.sort() to sort an array. Also, this method accept sortOption to consider the values in the array as numeric. Finally it worked. Below is the sample code;

//get the selected indices in the array
var sIndices:Array = myGrid.selectedIndices; 
                
//since the indices are pushed as they selected, we need to sort them in ascending order
sIndices.sort(Array.NUMERIC)
                
//get the highest index first and remove the item
// i.e. start removing items from the bottom so that change in index won't give any problem
for(var index:int = sIndices.length-1; index>=0; index--
    xmlListCollection.removeItemAt(sIndices[index]);


What amazed me the most is that I didn't find a single discussion in any of the websites, forums, blogs about this. Is it only me who want to have this kind of feature in the datagrid or the solution was so simple that people easily implemented it? :-)

21 comments:

Jack said...

Thanks Milan. you are my hero.

Crazy Rambler. said...

Thanks man.. i have been browsing the web for few hours but finally found your blog..

John Zimmatore said...

Awesome...I've been trying this for days.

Sjaakie said...

Thanks dude, it certainly is a weird phenomenon. Fortunately i didn't have to search for days. your blog came right up!

Anonymous said...

How do you iterate selectedItems (or selectedIndices) and de-select the item?

yabel said...

Hi!
I'm not sure about XMLCollection (in my case there is an ArrayCollection instead as dataprovider) but it seems this code works:

for(var i:int = 0, e:int = mygrid.selectedIndices.length; i < e; ++i) {
mygrid.dataProvider.removeItemAt(mygrid.selectedIndices[0]);
}

Dimitris said...

Great piece of code thanks a lot.

Please forgive my ignorance but I have a question.
I have used the code in two functions, changed the datagrid provider, but the second function does not work, what else do I have to change?

Thanks in advance Dimitris

yabel said...

Could you please provide your functions?

Doug said...

This is EXACTLY what I've been struggling with EXCEPT, I have a HTTPService in the middle of this that adds a level of complexity. You can do what you've proposed, but what if one service call comes back out of order of sending it? Then you've got an issue of deleting the wrong item at the wrong time. Any suggestions on how to tackle that animal?

Rehan Azher said...

What if users has sorted the gird after selection.

srikanth said...

How to retrieve selected values from multiple selection datagrid flex and store into array

Thanks in advance

Gurmeet said...

Thanks a lot for your example

Unknown said...

This is an even simpler way that I found:

while(myGrid.selectedItem != null) {
myGrid.dataProvider.removeItemAt(myGrid.selectedIndex);
}

Anonymous said...

Thanks man, I've been trying to do this for few hours, first search your blog came in...that would save me days :) didn't try do I will just after posting this comment...but It will work for two reasons you did it and you are reliable (you're welcome) and what you say make perfect sense....goshh I talk (type) too much

Mario said...

Many thanks Milan. Very good and simple example.

Anonymous said...

Many thanks!!!

Unknown said...

Hi Milan

Thanks A lot ,good work.

Unknown said...

Hi Thanks,you did a great job

Anonymous said...

Thank you very much for sharing.I spent hours trying to find a solution.This worked like a charm.

Ahmad A.L. Yahya said...

Thanks a lot...

Binj said...

Thanks a lot