Hi,
I have an existing app that has a FeatureTable populated by a FeatureLayer that has been created client side from the results of a query. I recently migrated the app from 3.16 to 3.17 and was pleased to see that a few issues have been resolved but a new one popped up which is that I can no longer sort the table.
When I click on the column header I don't get the popup menu that allows the user to choose ascending or descending. I also don't get any console errors.
To show what I mean, I combined these two samples, Feature collection | ArcGIS API for JavaScript 3.17 and Using FeatureTable | ArcGIS API for JavaScript 3.17. That code is listed below.
Any ideas are appreciated!
Thanks!
Jill
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Using FeatureTable</title> <link rel="stylesheet" href="https://community.esri.com//js.arcgis.com/3.17/dijit/themes/claro/claro.css"> <link rel="stylesheet" href="https://community.esri.com//js.arcgis.com/3.17/esri/css/esri.css"> <script src="//js.arcgis.com/3.17/"></script> <style> html, body, #map{ width:100%; height:100%; margin:0; padding:0; } </style> <script> var map; require([ "esri/layers/FeatureLayer", "esri/dijit/FeatureTable", "esri/geometry/webMercatorUtils", "esri/map", "dojo/dom-construct", "dojo/dom", "dojo/parser", "dojo/ready", "dojo/on", "dojo/_base/lang", "dijit/registry", "dijit/form/Button", "dijit/layout/ContentPane", "dijit/layout/BorderContainer", "dijit/form/TextBox", "esri/request", "dojo/_base/array", "esri/geometry/Point", "esri/graphic" ], function ( FeatureLayer, FeatureTable, webMercatorUtils, Map, domConstruct, dom, parser, ready, on,lang, registry, Button, ContentPane, BorderContainer, TextBox, esriRequest, array, Point, Graphic ) { parser.parse(); ready(function(){ var myFeatureLayer; var map = new Map("map",{ basemap: "dark-gray" }); map.on("load", loadTable); function loadTable(){ //create a feature collection for the flickr photos var featureCollection = { "layerDefinition": null, "featureSet": { "features": [], "geometryType": "esriGeometryPoint" } }; featureCollection.layerDefinition = { "geometryType": "esriGeometryPoint", "objectIdField": "ObjectID", "drawingInfo": { "renderer": { "type": "simple", "symbol": { "type": "esriPMS", "url": "images/flickr.png", "contentType": "image/png", "width": 15, "height": 15 } } }, "fields": [{ "name": "ObjectID", "alias": "ObjectID", "type": "esriFieldTypeOID" }, { "name": "description", "alias": "Description", "type": "esriFieldTypeString" }, { "name": "title", "alias": "Title", "type": "esriFieldTypeString" }] }; //create a feature layer based on the feature collection myFeatureLayer = new FeatureLayer(featureCollection, { id: 'flickrLayer' }); //set map extent on(myFeatureLayer, "load", function(evt){ var extent = myFeatureLayer.fullExtent; if (webMercatorUtils.canProject(extent, map)) { map.setExtent( webMercatorUtils.project(extent, map) ); } }); map.addLayer(myFeatureLayer); myFeatureTable = new FeatureTable({ "featureLayer" : myFeatureLayer, "map" : map }, 'myTableNode'); myFeatureTable.startup(); requestPhotos(); } function requestPhotos() { //get geotagged photos from flickr //tags=flower&tagmode=all var requestHandle = esriRequest({ url: "https://api.flickr.com/services/feeds/geo?&format=json", callbackParamName: "jsoncallback" }); requestHandle.then(requestSucceeded, requestFailed); } function requestSucceeded(response, io) { //loop through the items and add to the feature layer var features = []; array.forEach(response.items, function(item) { var attr = {}; attr["description"] = item.description; attr["title"] = item.title ? item.title : "Flickr Photo"; var geometry = new Point(item); var graphic = new Graphic(geometry); graphic.setAttributes(attr); features.push(graphic); }); myFeatureLayer.applyEdits(features, null, null); } function requestFailed(error) { console.log('failed'); } }); }); </script> </head> <body class="claro esri"> <div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline'" style="width:100%; height:100%;"> <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center', splitter:true" style="height:50%"> <div id="map"></div> </div> <div id="bot" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'bottom', splitter:true" style="height:50%"> <div id="myTableNode"></div> </div> </div> </body> </html>
Hi Jillian,
I can reproduce the problem you are running into and thank you for reporting it. Unfortunately, I could not find a workaround. I will let you know if I find a workaround.
Thanks for your reply, Undral.
Here's a quick and dirty workaround that I came up with, in case anyone else needs this functionality. I'd be interested in hearing if someone has a more elegant solution.
After creating the feature table, I create the menu that allows the user to choose the direction of sorting. By specifying the targetNodeId and selector properties it will appear as the context menu when the user right clicks a column header.
var sortMenu = new Menu({ id: "sortMenu", targetNodeIds: [tableDiv.id], selector: ".dgrid-sortable" }); sortMenu.addChild(new MenuItem({ id: "sortAscending", label: "Sort Ascending", iconClass: "iconSortAscending", onClick: lang.hitch(this, "_onSortAscendingClick") })); sortMenu.addChild(new MenuItem({ id: "sortDescending", label: "Sort Descending", iconClass: "iconSortDescending", onClick: lang.hitch(this, "_onSortDescendingClick") })); sortMenu.startup();
The only way I could see to capture the name of the field to be sorted was to grab it from the contextmenu event of the column header.
dojo.forEach(this._resultsAttributeTable.columns, lang.hitch(this, function(column) { on(column.headerNode, 'contextmenu', lang.hitch(this, function(e) { if (e.currentTarget.hasOwnProperty("field")) { this._fieldSort = e.currentTarget.field; } })); }));
Finally, do the sorting when the menu item is clicked.
_onSortAscendingClick: function(e) { if (this._fieldSort) { this._resultsAttributeTable.grid.set('sort', this._fieldSort); this._fieldSort = null; } }, _onSortDescendingClick: function(e) { if (this._fieldSort) { this._resultsAttributeTable.grid.set('sort', [ { attribute: this._fieldSort, descending: true } ]); this._fieldSort = null; } }
Thanks!
Jill
There is nice little way mentioned over StackOverflow, have a look to it
Change default Sort order for Arcgis Javascript Feature Table - Stack Overflow