Hello,
In my app, I have a query set up that selects parcels from a feature layer. After the query is executed, I loop through the selected features that are returned and populate a list showing basic attribute information of the selected features (2 fields for now). In the created list, I am trying to make a button for each feature that would fire a function (searchParcelDetail) that takes the selected feature's OBJECTID and passes it into another query. From here I can zoom to the parcel and show more attributes. I am creating the button in line 51, for each selected parcel in the first query:
var parcel3Url = "http://summitmaps.summitoh.net/arcgis/rest/services/Fiscal_Mercator/MapServer/6"; featureLayerParcelFor = new esri.layers.FeatureLayer(parcel3Url, { mode: esri.layers.FeatureLayer.MODE_SELECTION, visible: true, id: "Selected Parcels", outFields: ["PARID", "ALT_ID", "ADDR", "OWN1"] }); var symbol2 = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_NULL, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new dojo.Color([100, 100, 100]), 2), new dojo.Color([0, 0, 255, 0.20])); featureLayerParcelFor.setSelectionSymbol(symbol2); map.addLayer(featureLayerParcelFor); featureLayerParcelDetail = new esri.layers.FeatureLayer(parcel3Url, { mode: esri.layers.FeatureLayer.MODE_SELECTION, visible: true, id: "Selected Parcels - Detailed", outFields: ["PARID", "ALT_ID", "ADDR", "OWN1", "OWNADDR1", "OWNZIP1", "CITYNAME", "STATECODE", "OWN2", "OWNADDR2", "OWNZIP2", "NBHD", "CLASS", "LUC", "ACRES", "DESC_"] }); var symbol2 = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_NULL, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new dojo.Color([100, 100, 100]), 2), new dojo.Color([0, 0, 255, 0.20])); featureLayerParcelDetail.setSelectionSymbol(symbol2); map.addLayer(featureLayerParcelDetail); function queryParcels2() { var queryParcels = new esri.tasks.Query(); queryParcels.where = "PARID LIKE '" + "%" + dom.byId("parcelText2").value + "'"; featureLayerParcelFor.selectFeatures(queryParcels, esri.layers.FeatureLayer.SELECTION_NEW, function(features, selectionMethod) { map.setExtent(graphicsUtils.graphicsExtent(featureLayerParcelFor.getSelectedFeatures()), true); }); } featureLayerParcelFor.on("selection-complete", function(fset) { console.log("Selection Complete"); var resultFeatures = fset.features; var details, number; details = "Number of parcels found: " + resultFeatures.length + "<br /><hr><table>"; for (var i = 0, il = resultFeatures.length; i < il; i++) { number = i + 1; details = details + "<tr><td><b> PARID:</b> " + resultFeatures.attributes.PARID + "</td></tr>"; details = details + "<tr><td><b> ALT_ID:</b> " + resultFeatures.attributes.ALT_ID + "</td></tr>"; details = details + "<tr><td><button onClick=searchParcelDetail('" + resultFeatures.attributes.OBJECTID + "')>More Details</button></td></tr>"; details = details + "<tr><td></td></tr>"; details = details + "<tr><td><hr /></td></tr>"; } details = details + "</table>"; document.getElementById("parcelSearchResults").innerHTML = details; }); function searchParcelDetail(objectid){ var queryParcels = new esri.tasks.Query(); queryParcels.where = "OBJECTID = '" + objectid + "'"; featureLayerParcelDetail.selectFeatures(queryParcels, esri.layers.FeatureLayer.SELECTION_NEW, function(features, selectionMethod) { map.setExtent(graphicsUtils.graphicsExtent(featureLayerParcelDetail.getSelectedFeatures()), true); }); dijit.byId("leftPane2").selectChild(dijit.byId("propertyDetails3")); }
Everything works until I try to click the button to fire the searchParcelDetail function. I get the error:
"Uncaught ReferenceError: searchParcelDetail is not defined"
Can anyone see what I am doing wrong? To be honest I'm not sure if this is the best way to accomplish this. Any ideas?
Any help is appreciated!
Thanks,
Ryan
Total shot in the dark, but I wonder if you need to define the function before you call it, e.g. move it above the 'on' event...wondering this because you use the function in defining the button html, so maybe it is treated sequentially?
Ryan,
It is a scope issue. It is referencing a function outside the scope of button created. Create a unique id for each button in your loop and add an on event for it:
details = details + "<tr><td><button id='button" + i + "'>More Details</button></td></tr>"; on(dom.byId("button"+i), "click", searchParcelDetail(resultFeatures.attributes.OBJECTID));
Regards,
Tom
Hi Tom,
Thanks for the response. That makes good sense but when I implement the code you supplied, I am still running into an issue. My query executes but something is breaking in the loop. The HTML is not inserted into the assigned div and I get the the error:
"TypeError: Cannot read property 'on' of null"
Any thoughts? Do I need to insert this line in a different location?
on(dom.byId("button"+i), "click", searchParcelDetail(resultFeatures.attributes.OBJECTID));
Ryan
Ryan,
Have you added a reference to dojo/on? That may be what is breaking your loop.
Regards,
Tom
Tom,
I wondered the same thing, but I do have it referenced in my require statement.
Ryan
Ryan,
It might be good to see the rest of your code to get some context. I am missing something, but without seeing the rest of the code, I am a bit lost.
Regards,
Tom
Ryan,
Thanks. I will have a look at it.
Regards,
Tom
Ryan,
How about this:
var parcelButton = new Button({ label: "More Details", onClick: searchParcelDetail(resultFeatures.attributes.OBJECTID) }, "button"+i).startup();
Regards,
Tom