Selecting multiple items in Flex List and DataGrid controls

The following example shows how you can have multiple selected items in a List or DataGrid control at the same time. To select multiple items at once, hold down the Shift or Control keys on your keyboard while pressing the mouse button on a list item.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/11/21/allowing-multiple-selected-items-in-flex-list-and-datagrid-controls/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="horizontal"
        verticalAlign="middle"
        backgroundColor="white">

    <mx:Array id="arr">
        <mx:Object col1="One.1" col2="One.2" col3="One.3" />
        <mx:Object col1="Two.1" col2="Two.2" col3="Two.3" />
        <mx:Object col1="Three.1" col2="Three.2" col3="Three.3" />
        <mx:Object col1="Four.1" col2="Four.2" col3="Four.3" />
        <mx:Object col1="Five.1" col2="Five.2" col3="Five.3" />
        <mx:Object col1="Six.1" col2="Six.2" col3="Six.3" />
        <mx:Object col1="Seven.1" col2="Seven.2" col3="Seven.3" />
        <mx:Object col1="Eight.1" col2="Eight.2" col3="Eight.3" />
    </mx:Array>

    <mx:ApplicationControlBar dock="true">
        <mx:Form styleName="plain">
            <mx:FormItem label="allowMultipleSelection:">
                <mx:CheckBox id="checkBox" selected="true" />
            </mx:FormItem>
        </mx:Form>
    </mx:ApplicationControlBar>

    <mx:List id="list"
            allowMultipleSelection="{checkBox.selected}"
            dataProvider="{arr}"
            labelField="col1"
            verticalScrollPolicy="on" />

    <mx:DataGrid id="dataGrid"
            allowMultipleSelection="{checkBox.selected}"
            dataProvider="{arr}"
            verticalScrollPolicy="on" />

</mx:Application>

View source is enabled in the following example.

28 thoughts on “Selecting multiple items in Flex List and DataGrid controls

  1. how do you obtain the multiple selected through event on change?

    i know u can get 1 object through

    var selectedItem:Object=event.target.selectedItem;

    how do u get all the objects that are selected?

  2. Terence,

    You can use the selectedItems property instead of selectedItem.
    The selectedItems property returns an array of objects representing all the selected items.

    For more information, see the selectedItems property in the ListBase class in the Flex documentation.

    Hope that helps,
    Peter

  3. slt Peter,

    juste une truc pour selectedItems c’est un array, c’est bien, mais comment je peut tester si une valeur string exist sur ce derniers?

    ...
    if(item.Idracine == myListe.grdLigne.selectedItems.Idracine)
    ...
    

    merci d’avance pour ce site Peter :)

  4. Reda Makhchan,

    Sorry, I’m not sure I understand your question, but does this help?

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
            layout="vertical"
            verticalAlign="middle"
            backgroundColor="white">
    
        <mx:Script>
            <![CDATA[
                import mx.controls.Alert;
                import mx.events.ListEvent;
    
                private function list_change(evt:ListEvent):void {
                    var item:String = "Four";
                    var idx:int = list.selectedItems.indexOf(item);
                    if (idx > -1) {
                        Alert.show("Item was selected.", "index = " + idx);
                    } else {
                        Alert.show("Item was not selected.");
                    }
                }
            ]]>
        </mx:Script>
    
        <mx:Array id="arr">
            <mx:String>One</mx:String>
            <mx:String>Two</mx:String>
            <mx:String>Three</mx:String>
            <mx:String>Four</mx:String>
            <mx:String>Five</mx:String>
            <mx:String>Six</mx:String>
            <mx:String>Seven</mx:String>
            <mx:String>Eight</mx:String>
        </mx:Array>
    
        <mx:List id="list"
                allowMultipleSelection="true"
                dataProvider="{arr}"
                labelField="col1"
                verticalScrollPolicy="on"
                width="100"
                change="list_change(event);" />
    
    </mx:Application>
    

    Peter

  5. hello Peter,

    Sorry I spoke french, well what I want to say is :

    I’ve an two arrays :

    the first is affacted to dataprovider in a grdLigne (allowmultiSelect = true)
    so I can select ligne 11, ligne 12 … and I need to get the concerned value from a second array.

    Ithink we get the selected value 1 by 1 with:
    grdLigne.selectedItems[0].ligne,grdLigne.selectedItems[1].ligne …

    and I need to filter that array by selected lignes (filterFunc):


    arrCol2.filterFunction = processFilter;

    private function processFilter(item:Object):Boolean {
    //will not work
    if(item.ligne == grdLigne.selectedItems.ligne)
    return true;
    else return false;
    }
    any idea?

    that what I was talking about ;), sorry and thks in advance Peter

  6. Thats swell (and easy), so how can you set more than one selected item using ActionScript?

  7. Peter,

    Is it at all possible to have multiple selection without the Cntl button pressed; each item on the list when simply single-clicked toggles between being selected and not. (Imagine an array of vertically arranged checkBoxes looking like a list :) )

    Thanks for a wonderful website – used it on numerous occasions.
    -Lev

  8. Terence,

    You can use the selectedItems property instead of selectedItem.
    The selectedItems property returns an array of objects representing all the selected items.

    For more information, see the selectedItems property in the ListBase class in the Flex documentation.

    Hope that helps,
    Peter
    ________________________________________________________________________________________
    Does someone have an example of the above? I went to the Flex Documentation and looked at the ListBase and it was little help. I am new to Flex.

    I have a listbox that is being filled with an HTTPService. Once there I need the enduser to select many choices and then pass the “UID” (which is in the feed as well) to a php page that will update a table.

    I have most of this but not the part that was stated above. Are there any examples that I could look at that would help me understand this better?

    Thank you all,
    Sean

  9. I also am trying to figure out how to set more than one selected item using ActionScript. I’ve tried a few things, but not gotten the desired behavior. I’ve spent most of today searching the internet and haven’t found anything on this issue, specifically. Any help will be most appreciated.

  10. Hi Sean,
    I am new to Flex as well so I am hoping that this might be useful to you. It creates an xml string out of selected items in a grid and sends it to an http request.( grdSeanItems is your grid control.)

    It may not be suitable for your php page at all as I made it up (!) but it shows how you can get the selected items in a loop and send it. So use it freely but don’t trust too much in the syntax :)

  11. Last try with a feeling !!!!!

    private function send_to_wherever():void {
    
        var xmlRequest:String;
        xmlRequest = "<seans_items>";
    
        var selectedItems:Array = grdSeanItems.selectedItems;
    
        for each (var a_selected_item:Object in selectedItems)
        {
            xmlRequest = xmlRequest + "<seans_item>";
            xmlRequest = xmlRequest + "<item_UID>" + a_selected_item.UID + "</item_UID>";
            xmlRequest = xmlRequest + "</seans_item>";
        }
    
        xmlRequest = xmlRequest + "</seans_items>";
    
    
        xmlRpc.request.request = "seans_service";
        xmlRpc.request.xml = xmlRequest;
    
        xmlRpc.send()
    }
    

    And in your components maybe for the http request:

    .....
    <mx:HTTPService id="xmlRpc"
            url="http://seans_server/php_page.php"
            result="handleXml(event)"
            fault="handleFault(event)"
            resultFormat="xml">
                <mx:request>
                    <format>xml</format>
                </mx:request>
    </mx:HTTPService>
    .....
    
  12. Ok here is what I have so far. By the way Baris Guner thanks but I not sure what to do with the above.

    This is two days of working on this and I have only got half way.

    Once you get everything created and up and running click on one item in the list. this will bring up values in two text fields. It will look like [object Object] and below that is a number. Once you click on more than one you will see [object Object],[object Object] and only the number of the last one that you clicked on.

    I Need ALL of the “Numbers” (1,2,3 whatever the person clicks on) in a var that can be passed back through the srvDBSubmitColorandPower HTTPService. I hope this helps a bit on where I am coming from and I think a lot of other people are having the same problems. I will be checking back often to help clear up any questions.

    //PHP PAGE ACTING AS THE DATAPROVIDER.
    <?
    //USAGE:
    //$table as table name
    //$fieldList as list of fields separated by a comma
    $table="Powers";
    $fieldList="data,Power";
    
    header("Content-type: text/xml");
    session_start();
    //REMOVE LISTINGS
    $link = mysql_connect('YOURSERVER', 'YOURLOGIN', 'YOURPASSWORD');
    mysql_select_db("YOUDATABASE");
    //$table=$_SESSION['table'];
    
    $xml_output = "<?xml version=\"1.0\"?>\\n";
    $xml_output .= "\\t<$table>\\n";
    
    $resultItems=mysql_query("select * from $table");
    while ($rowItems=mysql_fetch_array($resultItems))
    {
        //////////////////////////////////////////////////////////
        $xml_output .= "<item>\\n";
        //Looping through each <item></item>
        $resultFields=mysql_query("show columns from $table");
    
        $fieldArray=explode(",",$fieldList);
        foreach ($fieldArray as $fieldname)
        {
            $xml_output .= "\\t\\t<$fieldname>" . htmlentities($rowItems[$fieldname]) . "</$fieldname>\\n";
        }
    
        $xml_output .= "</item>\\n";
         ////////////////////////////////////////////////////////////
     }
    
    $xml_output .= "\\t</$table>\\n";
    echo $xml_output;
    ?>
    

    ——————————————————————————————————————————————————–

    //XML VIA PowerList.php
    
    <Powers>
    −
    <item>
        <data>1</data>
        <Power>ASTRAL PROTECTION</Power>
    </item>
    −
    <item>
        <data>2</data>
        <Power>BEAUTY</Power>
    </item>
    −
    <item>
        <data>3</data>
        <Power>CHASTITY</Power>
    </item>
    −
    <item>
        <data>4</data>
        <Power>COURAGE</Power>
    </item>
    −
    <item>
        <data>5</data>
        <Power>DEAD</Power>
    </item>
    −
    <item>
        <data>6</data>
        <Power>DIVINATION</Power>
    </item>
    −
    <item>
        <data>7</data>
        <Power>EMPLOYMENT</Power>
    </item>
    −
    <item>
        <data>8</data>
        <Power>EXORCISM</Power>
    </item>
    −
    </Powers>
    

    ———————————————————————————————————————————————————
    //MXML APP

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="{srvPowerName.send()}">
    
        <mx:Script>
            <![CDATA[
                import mx.collections.ArrayCollection;
                import mx.rpc.events.ResultEvent;
                import mx.controls.Alert;
    
                [Bindable]
                public var powers: ArrayCollection;
    
                // Checks to see if it submitted to the DataBase.
                private function checkSubmit(event:ResultEvent):void
                {
                    if(event.result.submitsuccess == "yes")
                    {
                        Alert.show('Record Added');
                    }
    
                    if(event.result.submitsuccess == "no")
                    {
                        Alert.show('Did NOT Add. Please Try Again!');
                    }
                }
    
                // This is for the line items to make the first item "Select..."
                public function PowerHandler(event:ResultEvent):void {
                    powers = event.result.Powers.item;
                }
    
                public function changeEvt(event:Event):void {
                    listoutputchange.text=event.target.selectedItems;
                }
            ]]>
        </mx:Script>
    
        <!--This is what supplies the list in the Listbox for the Power Name-->
        <mx:HTTPService id="srvPowerName" url="http://www.YOURSITE.com/PowerList.php" result="PowerHandler(event)"/>
    
        <mx:HTTPService id="srvDBSubmitColorandPower" result="checkSubmit(event)" showBusyCursor="true" method="POST" url="http://www.www.YOURSITE.com/PowerSubmit.php">
            <mx:request>
                <liPowers>{liPowers.value}</liPowers>
            </mx:request>
        </mx:HTTPService>
    
        <mx:List change="changeEvt(event)" allowMultipleSelection="true" id="liPowers" dataProvider="{powers}" labelField="Power" x="10" y="4"  width="200"/>
        <mx:Text id="listoutputchange" x="128" y="170"/>
        <mx:Text id="listout" text="{liPowers.value}" x="128" y="198"/>
        <mx:Button id="Submit" click="srvDBSubmitColorandPower.send()"  x="10" y="168" label="Click to Submit"/>
    </mx:Application>
    
  13. Anyone else having problems with multiple selection not working when StageDisplayState is set to FULL_SCREEN?

    I have a list control that works great in normal mode, but when in full screen I can only select 1 item at a time.

  14. Jeremy Hicks,

    You could try filing a bug, but I think that is the “expected” behavior since keyboard input is disabled while in full screen mode. Therefore, while in full screen mode the Ctrl+Shift keys cannot be used to select multiple DataGrid/List items. I’m not sure if you could create a custom item renderer which would allow you to click list items to toggle their selected-ness, that may allow you to do multi-select while in full screen. Regardless, if you want to file a bug/enhancement request for this, you can file it in the public Flash Player bug base at http://bugs.adobe.com/flashplayer/.

    Peter

  15. Sean :

    Baris Guner’s code does work for what to do, basically it just serializes it as XML and sends it. I mod’d his option a bit to shorten it and so I could use it in PHP with split() and process it in query. Here is how I handled it:

    ActionScript

              private function sendSelected():void {
        		var xmlRequest:String;
        		var selectedItems:Array = myDataGrid.selectedItems;
    
    		xmlRequest = "";
        		for each(var item:Object in selectedItems){
            		xmlRequest += item.id + "|";
        		}
        		xmlRequest = xmlRequest.substr(0,(xmlRequest.length-1));
        		myService.request.items = xmlRequest;
        		myService.send()
    	   }
    

    ———————————
    There is no need for the added requests either. Like in his HTTPService component. So just fire the func off and process in your normal HTTPService comp. with URL and such..

  16. Bryan S and Baris,

    I really don’t understand what you guys are doing here I tried this in about 15 different ways and I just don’t understand on how to include it in what I posted above. Could you please look through what I posted and try to put whatever you are doing in code. I get that you are sending a xml page to the php file however I am not in need of something like this.

    I think I posted everything that one would need for the testing of the app. If you could please try it out and then post back the complete view so I can start to understand how this works would help me better. Thank you

  17. Asked earlier and to anyone who comes after: How do you create a List that (de)selects items without the user holding down the cntl key?

    <?xml version="1.0" encoding="utf-8"?>
    <mx:List xmlns:mx="http://www.adobe.com/2006/mxml">
        <mx:Script>
            <![CDATA[
                import mx.controls.listClasses.IListItemRenderer;
                override protected function selectItem(item:IListItemRenderer, shiftKey:Boolean, ctrlKey:Boolean, transition:Boolean = true):Boolean {
                    return super.selectItem(item, false, true, transition);
                }
            ]]>
        </mx:Script>
    </mx:List>
    
  18. I would like to reiterate Monica’s question. I cannot, for the life of me, after a couple hours searching on the Internet, find a way to programmatically select multiple items (i.e. from within Actionscript). I set someListObject.selectedItems = [blah, blah]. Nothing happens. There has to be a simple solution, but it appears not to be so simple.

  19. @Brian: Thanks a ton, you saved my day.. this is answer to “How do you create a List that (de)selects items without the user holding down the cntl/ctrl/control key?”

    There is just one thing I need to add it, to allow the multiple selection that we need:

    Another thing, for other people like me who are new to Flex and rusty with OOP/programming – this is a class defintion and is not an instantation – declare a separate component using this code and create an instance of this within your own code, otherwise you will get an error that says something different: “1020: Method marked override must override another” – basically this code tells the Flex runtime that Ctrl is pressed all the time

  20. Oops… the blog ate up my code (and I was too myopic to see the big red writing) – in Brian’s code above, add the property in the XML tag allowMultipleSelection=”true” – or set the property when instatiating this object

  21. Hi,
    How can I limit the selection. I have a combo box and depending on the value selected in the combo box I want to limit the multiple selection..

    Thanks in advance.

    Tamil

  22. Hi,

    I would like to say thank you very much for all these answers. This blog is so great. I searched a lot time to find the answer how I can select items in a list without holding down the ctrl key and Brian’s answer is exactly what I needed! Thank you Brian and thank you all for helping answers!!!

    Matze

Comments are closed.