populate datagrid from a map click in Flex

905
9
06-14-2011 09:40 PM
RhysDonoghue
New Contributor
I have a simple identify task where a user clicks on a map and wants to see the results in a datagrid.  The features being identified are address points.  When clicking on the map a buffer of say 15 metres will in most cases bring back one result but in some cases there may be multiple results.  We want to see all of the results so an info window is not really suitable.  I want to use a datagrid to show the results.  Has anyone got a sample I can look at?
Tags (2)
0 Kudos
9 Replies
KenBuja
MVP Esteemed Contributor
Here's some code in one of my applications that will populate a datagrid from a map click, putting it into a tab navigator in an InfoWindow. The portion of the code that is commented out allows you to get back the results from multiple visible layers in your layer, which are put into separate tabs. The listeners that are added allow you to highlight the features on the map when you click or roll over the entries in the datagrid.

            protected function MainMap_mapClickHandler(event:MapMouseEvent):void
            {
                var identifyParams:IdentifyParameters = new IdentifyParameters();
                var clickGraphic:Graphic = new Graphic(event.mapPoint, clickPointSymbol);
                
                identifyParams.returnGeometry = true;
                identifyParams.tolerance = 5;
                identifyParams.width = MainMap.width;
                identifyParams.height = MainMap.height;
                identifyParams.geometry = event.mapPoint;
                identifyParams.mapExtent = MainMap.extent;
                identifyParams.spatialReference = MainMap.spatialReference;
                identifyParams.layerIds = layerLIS.visibleLayers.source; //replace this with your layerID
                identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_ALL;
                clickGraphicsLayer.clear();
                MainMap.infoWindow.hide();
                
                graphicsLayer.clear();
                cursorManager.setBusyCursor();
                
                identifyTask.url = layerLIS.url; //replace this with your layer URL
                identifyTask.execute(identifyParams, new AsyncResponder(resultFunction, faultFunction, clickGraphic));
                
                function resultFunction(results:Array, clickGraphic:Graphic):void
                {
                    var myInfoRenderer:InfoRenderer = new InfoRenderer;
                    var mapPoint:MapPoint = MapPoint(clickGraphic.geometry);
                    var point:Point = MainMap.toScreen(mapPoint);
                    
                    if (results && results.length > 0)
                    {
                        var oldLayer:Number = -1;
                        var resultsArray:Array = [];
                        var result:IdentifyResult;
                        var resultGraphic:Graphic;
                        var tab:TabNavigator = new TabNavigator();
                        var newVBox:VBox = new VBox;
                        var newVBoxDG:VBox = new VBox;
                        var newText:Text = new Text;
                        var newDG:DataGrid = new DataGrid;
                        var graphic:Graphic;
                        
                        clickGraphicsLayer.add(clickGraphic);
                        
                        result = results[0];
                        oldLayer = result.layerId;
                        resultsArray.push(result.feature.attributes);
                        newText = new Text;
                        newText.text = result.layerName;
                        graphic = result.feature;
                        graphic.alpha = 0.3;
                        graphicsLayer.add(graphic);
                        tab.width = 400;
                        tab.height = 230;
                        
//                        for (var i:int = 1; i < results.length; i++)
//                        {
//                            result = results;
//                            graphic = new Graphic;
//                            graphic = result.feature;
//                            graphic.alpha = 0.3;
//                            graphicsLayer.add(graphic);
//                            if (result.layerId == oldLayer)
//                            {
//                                resultsArray.push(result.feature.attributes);
//                            }
//                            else
//                            {
//                                newDG = new DataGrid;
//                                newVBox = new VBox;
//                                newDG.dataProvider = resultsArray;
//                                
//                                newDG.addEventListener(ListEvent.ITEM_CLICK, newDG_ItemRollOver, false, 0, true);
//                                newDG.addEventListener(ListEvent.ITEM_ROLL_OUT, newDG_ItemRollOut, false, 0 ,true);
//                                newDG.addEventListener(ListEvent.ITEM_ROLL_OVER, newDG_ItemRollOver, false, 0, true);
//                                
//                                newVBox.addElement(newText);
//                                newVBox.addElement(newDG);
//                                newVBox.label = oldLayer.toString();
//                                newVBox.label = oldLayer.toString();
//                                tab.addElement(newVBox);
//                                myInfoRenderer.addElement(tab);
//                                
//                                newText = new Text;
//                                newText.text = result.layerName;
//                                resultsArray = [];
//                                resultsArray.push(result.feature.attributes);
//                            }
//                            oldLayer = result.layerId;
//                        }
                        
                        newVBox = new VBox;
                        newVBoxDG = new VBox;
                        newDG = new DataGrid;
                        newDG.addEventListener(ListEvent.ITEM_CLICK, newDG_ItemRollOver, false, 0, true);
                        newDG.addEventListener(ListEvent.ITEM_ROLL_OUT, newDG_ItemRollOut, false, 0, true);
                        newDG.addEventListener(ListEvent.ITEM_ROLL_OVER, newDG_ItemRollOver, false, 0, true);
                        newVBox.addElement(newText);
                        newDG.dataProvider = resultsArray;
                        
                        newVBox.addElement(newDG);
                        newVBox.label = oldLayer.toString();
                        tab.addElement(newVBox);
                        myInfoRenderer.addElement(tab);
                        
                        cursorManager.removeBusyCursor();
                        
                        MainMap.infoWindow.content = myInfoRenderer;
                        MainMap.infoWindow.label = "Results";
                        MainMap.infoWindow.show(MainMap.toMap(point));
                        MainMap.infoWindow.addEventListener(Event.CLOSE, infoWindow_Close, false, 0, true);
                    }
                }
            }

            protected function newDG_ItemRollOut(event:ListEvent):void
            {
                graphicLayer.clear();
            }
            
            protected function newDG_ItemRollOver(event:ListEvent):void
            {
                var highlightedGraphic:Graphic = findGraphicByAttribute(event.itemRenderer.data);
                var glowFill:SimpleFillSymbol = new SimpleFillSymbol;
                var glower:AnimateFilter = new AnimateFilter(highlightedGraphic,glow);
                
                glower.motionPaths = kf;
                glower.duration = 500;
                glower.play();
            }

            protected function faultFunction(error:Object, token:Object = null):void
            {
                cursorManager.removeBusyCursor();
                Alert.show(error.toString());
            }
            
            protected function findGraphicByAttribute(attributes:Object):Graphic
            {
                for each (var graphic:Graphic in graphicsLayer.graphicProvider)
                {
                    if (graphic.attributes == attributes)
                    {
                        return graphic;
                    }
                }
                return null;
            }

0 Kudos
RhysDonoghue
New Contributor
Hi Ken

Thanks for that.  I have managed to come up with a result but my Flex skills aren't that great.  I can get the identify results back into an Array and get the Array items to highlight on the map by using a loop.  There are only ever going to be around 1-6 results coming up in the array so a loop is nice and fast.  Within the same loop, I want to add a row into the datagrid for each item in the array.  This should be easy but I am having difficulty as I am a Flex beginner.  Any ideas?
0 Kudos
KenBuja
MVP Esteemed Contributor
You can see this code in action in this application. Click a point on the map near the corner of one of the grids. Is this the type of results you're looking for?
0 Kudos
RhysDonoghue
New Contributor
Yes, that's what I'm after.  I don't need the tabs though
0 Kudos
KenBuja
MVP Esteemed Contributor
You should be able to do this by removing the references to tab and changing

                        newVBox.addElement(newDG);
                        newVBox.label = oldLayer.toString();
                        tab.addElement(newVBox);
                        myInfoRenderer.addElement(tab);

to

                        newVBox.addElement(newDG);
                        newVBox.label = oldLayer.toString();
                        myInfoRenderer.addElement(newVBox);
0 Kudos
RhysDonoghue
New Contributor
very helpful thanks Ken, I have made some progress - will send you a link when to the finished product when I am done
0 Kudos
jerrysalinas
New Contributor
Hi Ken,
I saw your example for populating a datagrid by clicking a point on the map.  I am in the process of creating a very vanilla non-sfv application with just minimal tools.  Your site is what I am striving for with just a few basic features. I am also using one of Roberts�??s examples as a starting point, I have also incorporated the navigation tool to the application and got it working, but I would like to add your �??clicking a point on the map�?� and  legend/toc to my application.  In the process, I am receiving a ton of �??Type was not found or was not a compile-time constant. I am probably missing quite a few components. I�??ve narrowed down the number of errors, but I think I hit a bump in the road.  Is there any additional code I might need to incorporate your code. I am using Flex 4 and arcgis_api 2.2.

Thanks in advance,
Jerry
0 Kudos
jerrysalinas
New Contributor
Hi,
I am making some progress in creating a non-sfv web app. I added the TOC, legend, search and I also got the sample identify task to work. But I would like to incorporate Ken's point and click datagrid example, but I am still experiencing issues when I attempt to use the code example. I attached the code, hopefully someone a bit more experienced can help me troubleshoot. The code is a little messy. I am having issues/errors with InfoRenderer, TabNavigator and the graphics layer. 
Thanks again, Jerry
0 Kudos
KenBuja
MVP Esteemed Contributor
Hi Jerry,

Here are the files I'm using with my application.
0 Kudos