Hi everyone,
I am pretty new to WAB and Javacript development with Dojo. My plan is to generate a dynamic Combobox out of feature-layer attributes. On click the widget should add that specific feature-layer with the chosen layerexpression. e.g. Country selection ComboBox: "USA" -> Zoom on USA.
I got this to work in a standalone Javascript api, but now i'd like to include this into my WAB1.2 functionality set as a widget and I ran into several Dojo issues which I am not familiar with.
Basically I started a new widget from scratch:
Widget.js
define([ 'dojo/_base/declare', 'jimu/BaseWidget', 'jimu/ConfigManager', "jimu/WidgetManager", 'esri/layers/FeatureLayer', "dijit/form/Select", "dojo/query", "dojo/ready", "dijit/form/ComboBox", "dojo/data/ItemFileReadStore", "dojo/_base/array", "dojo/on" ], function( declare, BaseWidget, ConfigManager, WidgetManager, FeatureLayer, Select, query, ready, ComboBox, ItemFileReadStore, array, on ) { return declare([BaseWidget], { baseClass: 'definition_query', onOpen: function () { function init() { queryTask = new esri.tasks.QueryTask ("https://.../MapServer/0"); query = new esri.tasks.Query(); query.returnGeometry = false; query.outFields = ["NAME"]; query.where = "NAME<> ''"; queryTask.execute(query,populateList); } function populateList(results) { //Populate the ComboBox with unique values var zone; var values = []; var testVals={}; //Add option to display all zoning types to the ComboBox values.push({name:"ALL"}) //Loop through the QueryTask results and populate an array //with the unique values var features = results.features; dojo.forEach (features, function(feature) { zone = feature.attributes.NAME; if (!testVals[zone]) { testVals[zone] = true; values.push({name:zone}); } }); //Create a ItemFileReadStore and use it for the //ComboBox's data source var dataItems = { identifier: 'name', label: 'name', items: values }; var store = new dojo.store.Memory({data:dataItems});//tried to work with ItemFileReadStore before, but couldn't get it to work either console.log(dataItems); console.log(store); dijit.byId("mySelect").set('store', store); } dojo.addOnLoad(init); }, }); });
TypeError: dijit.byId(...) is undefined
dijit.byId("mySelect").set('store', store);
My Issue is dijit.byId won't be interpreted. What kind of modules am I missing? I am unsure how to figure out which of the modules are necessary for this job.
As mentioned, pretty much the same code works on plain javascript api. There are several working examples on JS but I couldn't manage to convert them into WAB. Maybe there is already a widget that has similar functionality?
HTML:
<select id="mySelect" dojoType="dijit.form.ComboBox" style="width:300px;font-size:18px;" value="Select Zoning Type"></select>
Thanks for advice
Solved! Go to Solution.
That's OK. There just has to be something off for you not to be able to reference mySelect
Ben,
I can't believe that I missed it earlier. But here it is working:
define([ "dojo/_base/declare", "jimu/BaseWidget", "dijit/_WidgetsInTemplateMixin", "dojo/aspect", "jimu/ConfigManager", "jimu/WidgetManager", "esri/layers/FeatureLayer", "dojo/query", "esri/tasks/query", "esri/tasks/QueryTask", "dojo/store/Memory", "dojo/_base/array", "dojo/on", "dojo/_base/lang", "dijit/form/ComboBox" ], function ( declare, BaseWidget, _WidgetsInTemplateMixin, aspect, ConfigManager, WidgetManager, FeatureLayer, dojoQuery, Query, QueryTask, Memory, array, on, lang ) { return declare([BaseWidget, _WidgetsInTemplateMixin], { baseClass: "definition_query", queryTask: null, query: null, postCreate: function () { this.queryTask = new QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyOperationalLayer..."); this.query = new Query(); this.query.returnGeometry = false; this.query.outFields = ["FDNAME"]; this.query.where = "FDNAME <> ''"; }, onOpen: function () { this.queryTask.execute(this.query, lang.hitch(this, this.populateList)); }, populateList: function (results) { //Populate the ComboBox with unique values var zone; var values = []; var testVals = {}; //Add option to display all zoning types to the ComboBox values.push({ name: "ALL" }); //Loop through the QueryTask results and populate an array //with the unique values var features = results.features; array.forEach(features, function (feature) { zone = feature.attributes.FDNAME; if (!testVals[zone]) { testVals[zone] = true; values.push({ name: zone }); } }); //Create a ItemFileReadStore and use it for the //ComboBox's data source var dataItems = { identifier: "name", label: "name", items: values }; //console.log(dataItems); var store = new Memory({ data: dataItems }); //console.log(store); this.mySelect.set("store", store); } }); });
Thanks alot Robert, never thought about using lang.hitch cause of legacy...
this was alot of work for these basics...now I know where to follow up.
Robert, how can I call a JSON webservice and populate a combobox instead of using QueryTask?
I have to use ItemFileReadStore?
Thanks,
Naty
At least I found the way and I post it...Maybe someone needs it too...
Naty
postCreate: function() {
var jsonStore= new JsonRest
({
target: "lists.json",
idProperty: "Code"
});
var restStore = new JsonRest({ target: "lists.json", idProperty: "Code" });
var memoryStore = new Memory({ idProperty: "Code" });
restStore.query().then(function(response) {
memoryStore.setData(response.slice(0));
});
var combobox = new FilteringSelect(
{
id: "Code",
name: "Name",
value: "",
searchAttr:"Name",
store: memoryStore,
style: "width: 200px;",
queryExpr: "*${0}*",
labelAttr: "Name",
onChange: lang.hitch(this, '_onLoadWidgetBClick')
}
}, this.StoreItemSelect);
combobox.startup();
},