However, there is a limitation to this that has caused me problems, even though it's documented and I've run into it a couple times: Selects do not play nicely with stores that have non-string IDs (like integers). To quote from a Dojo tutorial:
dijit.form.Select possesses an important limitation: it is implemented in such a way that it does not handle non-string item identities well. Particularly, setting the current value of the widget programmatically via select.set("value", id) will not work with non-string (e.g. numeric) identities.To drive this point home, I'll give a concrete example illustrating the problem. You can also see the example in action on OrionHub or download the source code and run it yourself.
The goal
We're going to create a pair of Selects that will display a list of ships: one backed by a store with String IDs, and one backed by a store with numeric IDs. The generated page will look like this:
The data
Our store will be a dojo/data/ItemFileReadStore, which will load JSON from a given file. The String ID JSON looks like this:
{ "identifier": "shipId", "label": "shipName", "items": [ { "shipId": "1", "shipName": "Constitution" }, { "shipId": "2", "shipName": "Enterprise" }, // You get the point... { "shipId": "6", "shipName": "Yorktown" } ] }
And the numeric ID JSON looks like this:
{ "identifier": "shipId", "label": "shipName", "items": [ { "shipId": 1, "shipName": "Constitution" }, { "shipId": 2, "shipName": "Enterprise" }, // You get the point... { "shipId": 6, "shipName": "Yorktown" } ] }
The HTML
The HTML is pretty uninteresting; it basically loads the JavaScript files and throws in some DIV placeholders for the widgets:
<html> <head> <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.7/dijit/themes/claro/claro.css"> <script src="//ajax.googleapis.com/ajax/libs/dojo/1.7.2/dojo/dojo.js" data-dojo-config="async: true"></script> <script src="//ajax.googleapis.com/ajax/libs/dojo/1.7.2/dijit/dijit.js" data-dojo-config="async: true"></script> <script src="selectStoreExample.js" data-dojo-config="async: true"></script> </head> <body class="claro"> <h1>Using String IDs</h1> <div> shipSelectString: <div id="shipSelectString"></div> <div id="selectStringEnterpriseButton"></div> <div id="selectStringYorktownButton"></div> </div> <h1>Using Numeric IDs</h1> <div> shipSelectNumber: <div id="shipSelectNumber"></div> <div id="selectNumberEnterpriseButton"></div> <div id="selectNumberYorktownButton"></div> </div> </body> </html>
The JavaScript
Here's where all the Dijit bindings happen. For both the String and numeric ID stores, we create a Select and a couple buttons that call select.set("value", [the ID]):
require(["dojo", "dijit", "dojo/data/ItemFileReadStore", "dijit/form/Select", "dijit/form/Button", "dojo/domReady!" ], function(dojo, dijit, ItemFileReadStore, Select, Button) { //****** Using Strings for IDs ****** //Create the data store using a JSON file var shipStoreString = new ItemFileReadStore({ url: "ships-string.json" }); //Create and start the Select, using the ItemFileReadStore as its store var selectString = new Select({ name: "shipSelectString", store: shipStoreString }, "shipSelectString"); selectString.startup(); //Create buttons that will use the Select widget's set() function to set the value new Button({ label: "Set shipSelectString to Enterprise", onClick: function() { selectString.set("value", "2"); } }, "selectStringEnterpriseButton"); new Button({ label: "Set shipSelectString to Yorktown", onClick: function() { selectString.set("value", "6"); } }, "selectStringYorktownButton"); //****** Using numbers for IDs ****** //Create the data store using a JSON file var shipStoreNumber = new ItemFileReadStore({ url: "ships-number.json" }); //Create and start the Select, using the ItemFileReadStore as its store var selectNumber = new Select({ name: "shipSelectNumber", store: shipStoreNumber }, "shipSelectNumber"); selectNumber.startup(); //Create buttons that will use the Select widget's set() function to set the value new Button({ label: "Set shipSelectNumber to Enterprise", onClick: function() { selectNumber.set("value", 2); } }, "selectNumberEnterpriseButton"); new Button({ label: "Set shipSelectNumber to Yorktown", onClick: function() { selectNumber.set("value", 6); } }, "selectNumberYorktownButton"); });
Now if you fire up the HTML page in your browser, you'll see the screen shown above in your browser. Click on the buttons, and you'll see that the Select with Strings as IDs changes when you click the buttons, but nothing happens to the Select with numeric IDs. This is the limitation (bug?) that prevents you from using numeric IDs in a store that's backing a Select.