How do I get the value of selected <option> in dojo/Form/select?

3437
10
Jump to solution
02-04-2020 08:48 AM
Arne_Gelfert
Regular Contributor

So I had always hoped to avoid the whole dojo universe. The JSAPI 4.x seems to more and more inoculate against the inner workings of whatever dojo its using. But now, I'm trying to build some custom WAB widgets and see myself having unscramble some of this dojo stuff. i got a 2-part question, and question subject refers to only part 2.

Part 1

Robert Scheitlin, GISP‌ had some advice suggesting to work with dojo attachments points, as in ...

<input data-dojo-attach-point="myButton" type="button" value="Click Here">

so that in my code I could refer to this element in widget.html simply as this.myButton.

But I'm still not sure when to use the above or - provided I have added id = 'myButton', use this;

dom.byId("myButton")‍‍

I see folks using them almost interchangeably through this forum and elsewhere. Are there some simple guiding principles?

Part 2

Now for the Select. I'm making a call to a web service, ignoring geometry and just returning the feature's name. Then I populate a <select> with that, which I have called:

<select id='results' data-dojo-attach-point='results' data-dojo-type="dijit/form/Select"></select>

The following code populates a bunch of entries (or <option>'s) in that <select> with records from the service.

//Interate over features in featureset
//find desired feature attribute's value
{
var c = document.createElement('option');
c.innerHTML = myAttributeValue;
c.value = i;
this.results.appendChild(c);   // 'results' being my dojo attach point
}‍‍‍‍‍‍‍‍

Next, I would like to use the dijit's event listener to watch if one of those <options>'s is selected. Again, ...

on(this.results,"change",lang.hitch(this, function(evt){
    console.log(this.results);‍‍‍‍

The above gets me a reference to the <select> but no attempt - such as ".value",".displayValue", "_getDisplayedValueAttr()" or ".selected" has been successful in getting me the value that's selected, and I've scoured the Dojo site for info. I can iterate over this.results.options and check the attribute selected for each one, but is there a simpler way? Thanks.

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Esteemed Contributor

Arne,

  1.  The proper way is always use dojo attach points in lieu of dom ids when building widgets. The only time you really see ids used is people unfamiliar with widget development or some just being lazy / in a hurry.
  2. The question would be is your select an actual dijit/form/Select or it just being rendered as a html select. For it be an actual dijit/form/Select then you have to have dijit/form/Select in your define array and have sure you have dijit/_WidgetsInTemplateMixin also in your define array and the declare array of your widget.js. to get a dijit/form/Select value you use 
this.bufferUnits.get('value')

to add the options in code you use code like this:

        var options = [];
        var len = this.config.bufferDefaults.bufferUnits.bufferUnit.length;
        for (var i = 0; i < len; i++) {
          var option = {
            value: this.config.bufferDefaults.bufferUnits.bufferUnit[i].name,
            label: this.config.bufferDefaults.bufferUnits.bufferUnit[i].label
          };
          options.push(option);
          if (i === 0) {
            options[i].selected = true;
          }
        }
        this.bufferUnits.addOption(options);

View solution in original post

0 Kudos
10 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

Arne,

  1.  The proper way is always use dojo attach points in lieu of dom ids when building widgets. The only time you really see ids used is people unfamiliar with widget development or some just being lazy / in a hurry.
  2. The question would be is your select an actual dijit/form/Select or it just being rendered as a html select. For it be an actual dijit/form/Select then you have to have dijit/form/Select in your define array and have sure you have dijit/_WidgetsInTemplateMixin also in your define array and the declare array of your widget.js. to get a dijit/form/Select value you use 
this.bufferUnits.get('value')

to add the options in code you use code like this:

        var options = [];
        var len = this.config.bufferDefaults.bufferUnits.bufferUnit.length;
        for (var i = 0; i < len; i++) {
          var option = {
            value: this.config.bufferDefaults.bufferUnits.bufferUnit[i].name,
            label: this.config.bufferDefaults.bufferUnits.bufferUnit[i].label
          };
          options.push(option);
          if (i === 0) {
            options[i].selected = true;
          }
        }
        this.bufferUnits.addOption(options);
0 Kudos
Arne_Gelfert
Regular Contributor
  1. The only reason I asked after having good success with the dojo-attach was because I keep coming across code snippets from you that use the dom,.byId - haha.
  2. I do have "dijit/form/Select" in my defines. But I suspect, I'm not setting up the dijit correctly, i.e. not creating it programmatically like I should.
define(['dojo/_base/declare', 
      'jimu/BaseWidget',
      'dijit/_WidgetsInTemplateMixin',
      [...]
      "dojo/_base/lang",
      "dojo/on", 
      "dojo/dom",
      "dijit/form/Select"],
function(declare, 
      BaseWidget,
      _WidgetsInTemplateMixin,
      [...]
      lang,
      on,
      dom,
      Select) 
0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor
  1.  Hopefully those threads are JS API threads or I was just not wanting to try spend a lot of time explaining the ins and out of it (Like I said Lazy...).
  2. So that all looks good, expect to you have
return declare([BaseWidget, _WidgetsInTemplateMixin], {
0 Kudos
KenBuja
MVP Honored Contributor

The way I have my Selects set up is like this on the html page:

<div data-dojo-attach-point="sourceLayerFieldSelect" class="esriCTDownloadTabTextbox"
  data-dojo-type="dijit/form/Select" data-dojo-props="required:true,trim:true,disabled:true">
</div>‍‍‍‍

This Select is populated with fields from a feature layer using information stored in an array of field infos (availableCategoryFieldInfos). This code first empties the Select of previous fields, adds the fields, then sets the display to empty so it doesn't have a field already selected.

this.sourceLayerFieldSelect.removeOption(
  this.sourceLayerFieldSelect.getOptions()
);

array.forEach(availableCategoryFieldInfos, lang.hitch(this, function (fieldInfo) {
  const option = {
    value: fieldInfo.name,
    label: fieldInfo.alias
  };
  this.sourceLayerFieldSelect.addOption(option);
}));
this.sourceLayerFieldSelect._setDisplay("");‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I set up a listener for its change event like this:

this.own(
  on(this.sourceLayerFieldSelect, "change", lang.hitch(this, this._onPrioritizationFieldSelectChange))
);

And I get the selected option using this syntax:

this._priorityField = this.sourceLayerFieldSelect.value;
Arne_Gelfert
Regular Contributor

Thanks for sharing, Ken. At first glance, it looks very similar to what I had.

You have a <div> with a dojo-attach point. I had a <select>. If I drop mine for the div, I love my scrollbar.

I was setting up my options like this:

var c = document.createElement('option');
this.results.appendChild(c);

You used removeOption(), I had:

while (this.results.firstChild) {
    this.results.removeChild(this.results.firstChild);
 };

If I try

option = {value: myAttrVal,
          label: myAttr}
this.results.addOption(option);

I get 

init.js:115 TypeError: this.results.addOption is not a function

if I keep my createElement/appendChild,instead of addOption, I end up with:

init.js:115 TypeError: this.results._setDisplay is not a function

I'll take another look at Robert's to make sure I am working with a "real' dojo dijit. -- I have a stack of dojo books on my desk...I think I need to spend a week just reading them. haha.

0 Kudos
KenBuja
MVP Honored Contributor

Where do you lose your scrollbar? In the Select dijit itself? Or somewhere else?

Can you post your html?

0 Kudos
Arne_Gelfert
Regular Contributor

Ken,

Here is my very stripped down HTML.

<input data-dojo-type="dojox/mobile/SearchBox" data-dojo-attach-point="siteSearch" type="search" placeHolder="Search">
<input data-dojo-attach-point="searchBtn" type="button" value="Search for this Wellsite ">
<select data-dojo-attach-point="results" class="text-box-scroll" data-dojo-type="dijit/form/MultiSelect"></select>

It is working fine until l make Robert's suggested change of adding _WidgetsInTemplateMixin to the declare. I suspect I'm still not setting my dojo elements up correctly and just adding that dojo-attach point is not sufficient. Time to read up on Dojo, I guess.

0 Kudos
KenBuja
MVP Honored Contributor

So you're using MultiSelect rather than Select?

0 Kudos
Arne_Gelfert
Regular Contributor

I had to back several iterations after jacking up all my widiget code. Originally, I had MultiSelect in there. But I've switched again to Select.

I spent a lot of time yesterday reading up on dojo vs dom ways to interact with the page elements. For example,..

  • document.getElementById()
  • dojo.byId()
  • dijit.byId()

That cleared up some misunderstanding. Now, I have figured out how to create my elements programmatically and placing them inside elements identified with data-dojo-attach-point. The question I'm trying to answer now is whether i can create a new elements and set a data-dojo-attach-point programmatically. But I'll move that line of questioning into a more focused thread. Thanks to both of you for chiming in so patiently.

0 Kudos