GibboK
GibboK

Reputation: 73918

Possible bug - Event change fires after widget.set('options', [])

Currently I am using dijit/form/Select to display a list of options and I need to programmatically update content for the dijit/form/Select.

Currently I am using .set('value', ...); but I have noticed that event change is fired (which is in my case is not wanted).

I need to be able to update the widget and selecting a value without having fired change event.

The change event, afaik, it should be fired only when an user "change" the value of the Select list clicking on it.

require(["dijit/form/Select",
  "dojo/data/ObjectStore",
  "dojo/store/Memory",
  "dojo/domReady!"
], function(Select) {

  var options = [{
    label: "TN",
    value: "Tennessee"
  }, {
    label: "VA",
    value: "Virginia",
    selected: true
  }, {
    label: "WA",
    value: "Washington"
  }, {
    label: "FL",
    value: "Florida"
  }, {
    label: "CA",
    value: "California"
  }];

  var s = new Select({
    options: options
  }, "target");
  s.startup();

  s.on("change", function() {
    console.log("my value: " + s.get("value"))
  });

  // updating options
  options.push({
    label: "MI",
    value: "Milan",
    selected: true
  });
  s.set('options', options);
  s.reset();
  // issue here, the following line trigger event change
  s.set('value', 'mi');

})
<link href="//ajax.googleapis.com/ajax/libs/dojo/1.10.0/dijit/themes/claro/claro.css" rel="stylesheet" />
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<body class="claro">
<div id="target"></div>
</body>

Upvotes: 1

Views: 110

Answers (2)

GibboK
GibboK

Reputation: 73918

I found a work around to this issue using:

  myWidget.set('_onChangeActive', false); // prevent firing change
  myWidget.set('value', 'Milan', false);
  myWidget.set('_onChangeActive', true); // reset to default

which works also when using .set() consecutively on multiple widgets.

Also passing false as third argument to .set() works if you change only one widget at a time.

s.set('value', 'Milan', false);

Notes: I could not find reference in the official documentation for this third argument using .set():

Related question: Dojo Select onChange event firing when changing value programatically

require(["dijit/form/Select",
  "dojo/data/ObjectStore",
  "dojo/store/Memory",
  "dojo/domReady!"
], function(Select) {

  var options = [{
    label: "TN",
    value: "Tennessee"
  }, {
    label: "VA",
    value: "Virginia",
    selected: true
  }, {
    label: "WA",
    value: "Washington"
  }, {
    label: "FL",
    value: "Florida"
  }, {
    label: "CA",
    value: "California"
  }];

  var s = new Select({
    options: options
  }, "target");
  s.startup();

  s.on("change", function() {
    console.log("my value: " + s.get("value"))
  });

  // updating options
  options.push({
    label: "MI",
    value: "Milan",
    selected: true
  });

  s.set('options', options);
  s.reset();

  s.set('_onChangeActive', false); // prevent firing change
  s.set('value', 'Milan', false);
  s.set('_onChangeActive', true);

})
<link href="//ajax.googleapis.com/ajax/libs/dojo/1.10.0/dijit/themes/claro/claro.css" rel="stylesheet" />
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<body class="claro">
<div id="target"></div>
</body>

Upvotes: 1

barbsan
barbsan

Reputation: 3458

_setValueAttr has also second parameter - priorityChange. If you set it to false, onChange event won't be fired.

From API docs version 1.6 (see _setValueAttr in methods):

_setValueAttr
Overrides dijit.form._FormValueWidget, dijit.form._FormSelectWidget
Sets the value of the widget. If the value has changed, then fire onChange event, unless priorityChange is specified as null (or false?)

BTW. If you want to add one option there's no need to replace whole set of options - you can call s.addOption(newOption)

require(["dijit/form/Select",
  "dojo/data/ObjectStore",
  "dojo/store/Memory",
  "dojo/domReady!"
], function(Select) {

  var options = [{
    label: "TN",
    value: "Tennessee"
  }, {
    label: "VA",
    value: "Virginia",
    selected: true
  }, {
    label: "WA",
    value: "Washington"
  }, {
    label: "FL",
    value: "Florida"
  }, {
    label: "CA",
    value: "California"
  }];

  var s = new Select({
    options: options
  }, "target");
  s.startup();

  s.on("change", function() {
    console.log("my value: " + s.get("value"))
  });

  // updating options
  options.push({
    label: "MI",
    value: "Milan",
    selected: true
  });
  s.set('options', options);
  s.reset();
  // issue here, the following line trigger event change
  s.set('value', 'Milan', false);

})
<link href="//ajax.googleapis.com/ajax/libs/dojo/1.10.0/dijit/themes/claro/claro.css" rel="stylesheet" />
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<body class="claro">
<div id="target"></div>
</body>

Upvotes: 3

Related Questions