[Dojo-checkins] toonetown - r17740 - in dojox/trunk/form: . tests
dojo-checkins-admin at dojotoolkit.org
dojo-checkins-admin at dojotoolkit.org
Fri Jun 5 16:59:19 EDT 2009
Author: toonetown
Date: Fri Jun 5 13:59:15 2009
New Revision: 17740
Modified:
dojox/trunk/form/DropDownSelect.js
dojox/trunk/form/_FormSelectWidget.js
dojox/trunk/form/tests/test_CheckedMultiSelect.html
dojox/trunk/form/tests/test_DropDownSelect.html
Log:
Fixes #6652 Add support for dojo.data stores to _FormSelectWidget (which, in turn, enables that support in DropDownSelect and CheckedMultiSelect). Also update the test cases for DDS and CMS. !strict
Modified: dojox/trunk/form/DropDownSelect.js
==============================================================================
--- dojox/trunk/form/DropDownSelect.js (original)
+++ dojox/trunk/form/DropDownSelect.js Fri Jun 5 13:59:15 2009
@@ -151,7 +151,10 @@
this.attr("disabled", (len === 0));
delete this._iDisabled;
}
- this._setValueAttr(this.value);
+ if(!this._loadingStore){
+ // Don't call this if we are loading - since we will handle it later
+ this._setValueAttr(this.value);
+ }
},
_setValueAttr: function(value){
Modified: dojox/trunk/form/_FormSelectWidget.js
==============================================================================
--- dojox/trunk/form/_FormSelectWidget.js (original)
+++ dojox/trunk/form/_FormSelectWidget.js Fri Jun 5 13:59:15 2009
@@ -1,6 +1,7 @@
dojo.provide("dojox.form._FormSelectWidget");
dojo.require("dijit.form._FormWidget");
+dojo.require("dojo.data.util.sorter");
/*=====
dojox.form.__SelectOption = function(){
@@ -21,6 +22,12 @@
=====*/
dojo.declare("dojox.form._FormSelectWidget", dijit.form._FormValueWidget, {
+ // summary:
+ // Extends _FormValueWidget in order to provide "select-specific"
+ // values - i.e., those values that are unique to <select> elements.
+ // This also provides the mechanism for reading the elements from
+ // a store, if desired.
+
// multiple: Boolean
// Matches the select's "multiple=" value
multiple: "",
@@ -34,6 +41,38 @@
// the html <option> tag.
options: null,
+ // store: dojo.data.api.Identity
+ // A store which, at the very least impelements dojo.data.api.Identity
+ // to use for getting our list of options - rather than reading them
+ // from the <option> html tags.
+ store: null,
+
+ // query: object
+ // A query to use when fetching items from our store
+ query: null,
+
+ // queryOptions: object
+ // Query options to use when fetching from the store
+ queryOptions: null,
+
+ // onFetch: Function
+ // A callback to do with an onFetch - but before any items are actually
+ // iterated over (i.e. to filter even futher what you want to add)
+ onFetch: null,
+
+ // sortByLabel: boolean
+ // Flag to sort the options returned from a store by the label of
+ // the store.
+ sortByLabel: true,
+
+
+ // loadChildrenOnOpen: boolean
+ // By default loadChildren is called when the items are fetched from the
+ // store. This property allows delaying loadChildren (and the creation
+ // of the options/menuitems) until the user opens the click the button.
+ // dropdown
+ loadChildrenOnOpen: false,
+
getOptions: function(/* anything */ valueOrIdx){
// summary:
// Returns a given option (or options).
@@ -150,9 +189,98 @@
this._loadChildren();
},
+ setStore: function(/* dojo.data.api.Identity */ store,
+ /* anything? */ selectedValue,
+ /* Object? */ fetchArgs){
+ // summary:
+ // Sets the store you would like to use with this select widget.
+ // The selected value is the value of the new store to set. This
+ // function returns the original store, in case you want to reuse
+ // it or something.
+ // store: dojo.data.api.Identity
+ // The store you would like to use - it MUST implement Identity,
+ // and MAY implement Notification.
+ // selectedValue: anything?
+ // The value that this widget should set itself to *after* the store
+ // has been loaded
+ // fetchArgs: Object?
+ // The arguments that will be passed to the store's fetch() function
+ var oStore = this.store;
+ fetchArgs = fetchArgs || {};
+ if(oStore !== store){
+ // Our store has changed, so update our notifications
+ dojo.forEach(this._notifyConnections||[], dojo.disconnect);
+ delete this._notifyConnections;
+ if(store && store.getFeatures()["dojo.data.api.Notification"]){
+ this._notifyConnections = [
+ dojo.connect(store, "onNew", this, "_onNewItem"),
+ dojo.connect(store, "onDelete", this, "_onDeleteItem"),
+ dojo.connect(store, "onSet", this, "_onSetItem")
+ ];
+ }
+ this.store = store;
+ }
+
+ // Turn off change notifications while we make all these changes
+ this._onChangeActive = false;
+
+ // Remove existing options (if there are any)
+ if(this.options && this.options.length){
+ this.removeOption(this.options);
+ }
+
+ // Add our new options
+ if(store){
+ var cb = function(items){
+ if(this.sortByLabel && !fetchArgs.sort && items.length){
+ items.sort(dojo.data.util.sorter.createSortFunction([{
+ attribute: store.getLabelAttributes(items[0])[0]
+ }], store));
+ }
+
+ if(fetchArgs.onFetch){
+ items = fetchArgs.onFetch(items);
+ }
+ // TODO: Add these guys as a batch, instead of separately
+ dojo.forEach(items, function(i){
+ this._addOptionForItem(i);
+ }, this);
+
+ // Set our value (which might be undefined), and then tweak
+ // it to send a change event with the real value
+ this._loadingStore = false;
+ this.attr("value", (("_pendingValue" in this) ? this._pendingValue : selectedValue));
+ delete this._pendingValue;
+
+ if(!this.loadChildrenOnOpen){
+ this._loadChildren();
+ }else{
+ this._pseudoLoadChildren(items);
+ }
+ this._fetchedWith = opts;
+ this._lastValueReported = this._multiValue ? [] : null;
+ this._onChangeActive = true;
+ this.onSetStore();
+ this._handleOnChange(this.value);
+ };
+ var opts = dojo.mixin({onComplete:cb, scope: this}, fetchArgs);
+ this._loadingStore = true;
+ store.fetch(opts);
+ }else{
+ delete this._fetchedWith;
+ }
+ return oStore; // dojo.data.api.Identity
+ },
+
_setValueAttr: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){
// summary: set the value of the widget.
// If a string is passed, then we set our value from looking it up.
+ if(this._loadingStore){
+ // Our store is loading - so save our value, and we'll set it when
+ // we're done
+ this._pendingValue = newValue;
+ return;
+ }
var opts = this.getOptions() || [];
if(!dojo.isArray(newValue)){
newValue = [newValue];
@@ -217,6 +345,7 @@
// summary:
// Loads the children represented by this widget's optiosn.
// reset the menu to make it "populatable on the next click
+ if(this._loadingStore){ return; }
dojo.forEach(this._getChildren(), function(child){
child.destroyRecursive();
});
@@ -274,6 +403,55 @@
return "";
},
+ // Internal functions to call when we have store notifications come in
+ _onNewItem: function(/* item */ item, /* Object? */ parentInfo){
+ if(!parentInfo || !parentInfo.parent){
+ // Only add it if we are top-level
+ this._addOptionForItem(item);
+ }
+ },
+ _onDeleteItem: function(/* item */ item){
+ var store = this.store;
+ this.removeOption(store.getIdentity(item));
+ },
+ _onSetItem: function(/* item */ item){
+ this.updateOption(this._getOptionObjForItem(item));
+ },
+
+ _getOptionObjForItem: function(item){
+ // summary:
+ // Returns an option object based off the given item. The "value"
+ // of the option item will be the identity of the item, the "label"
+ // of the option will be the label of the item. If the item contains
+ // children, the children value of the item will be set
+ var store = this.store, label = store.getLabel(item),
+ value = (label ? store.getIdentity(item) : null);
+ return {value: value, label: label, item:item}; // dojox.form.__SelectOption
+ },
+
+ _addOptionForItem: function(/* item */ item){
+ // summary:
+ // Creates (and adds) the option for the given item
+ var store = this.store;
+ if(!store.isItemLoaded(item)){
+ // We are not loaded - so let's load it and add later
+ store.loadItem({item: item, onComplete: function(i){
+ this._addOptionForItem(item);
+ },
+ scope: this});
+ return;
+ }
+ var newOpt = this._getOptionObjForItem(item);
+ this.addOption(newOpt);
+ },
+
+ constructor: function(/* Object */ keywordArgs){
+ // summary:
+ // Saves off our value, if we have an initial one set so we
+ // can use it if we have a store as well (see startup())
+ this._oValue = (keywordArgs||{}).value || null;
+ },
+
postMixInProperties: function(){
this._multiValue = (this.multiple.toLowerCase() === "true");
this.inherited(arguments);
@@ -317,6 +495,32 @@
this._setValueAttr(this.value, null);
},
+ startup: function(){
+ // summary:
+ // Connects in our store, if we have one defined
+ this.inherited(arguments);
+ var store = this.store, fetchArgs = {};
+ dojo.forEach(["query", "queryOptions", "onFetch"], function(i){
+ if(this[i]){
+ fetchArgs[i] = this[i];
+ }
+ delete this[i];
+ }, this);
+ if(store && store.getFeatures()["dojo.data.api.Identity"]){
+ // Temporarily set our store to null so that it will get set
+ // and connected appropriately
+ this.store = null;
+ this.setStore(store, this._oValue, fetchArgs);
+ }
+ },
+
+ destroy: function(){
+ // summary:
+ // Clean up our connections
+ dojo.forEach(this._notifyConnections||[], dojo.disconnect);
+ this.inherited(arguments);
+ },
+
_addOptionItem: function(/* dojox.form.__SelectOption */ option){
// summary:
// User-overridable function which, for the given option, adds an
@@ -348,6 +552,18 @@
// summary: hooks into this.attr to provide a mechanism for getting the
// option items for the current value of the widget.
return this.getOptions(this.attr("value"));
+ },
+
+ _pseudoLoadChildren: function(/* item[] */ items){
+ // summary: a function that will "fake" loading children, if needed, and
+ // if we have set to not load children until the widget opens.
+ // items: item[]
+ // An array of items that will be loaded, when needed
+ },
+
+ onSetStore: function(){
+ // summary: a function that can be connected to in order to receive a
+ // notification that the store has finished loading and all options
+ // from that store are available
}
-
});
Modified: dojox/trunk/form/tests/test_CheckedMultiSelect.html
==============================================================================
--- dojox/trunk/form/tests/test_CheckedMultiSelect.html (original)
+++ dojox/trunk/form/tests/test_CheckedMultiSelect.html Fri Jun 5 13:59:15 2009
@@ -10,9 +10,30 @@
dojo.require("dojox.form.CheckedMultiSelect");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.Form");
+ dojo.require("dojo.data.ItemFileWriteStore");
+
+ var data = {
+ identifier: "value",
+ label: "label",
+ items: [
+ {value: "AL", label: "Alabama"},
+ {value: "AK", label: "Alaska"},
+ {value: "AZ", label: "Arizona"},
+ {value: "AR", label: "Arkansas"},
+ {value: "CA", label: "California"},
+ {value: "CO", label: "Colorado"},
+ {value: "CT", label: "Connecticut"}
+ ]
+ };
+
+ var readStore = new dojo.data.ItemFileReadStore({data:dojo.clone(data)});
+ var writeStore = new dojo.data.ItemFileWriteStore({data:dojo.clone(data)});
- var perfNum = 100;
var numOptions = 0;
+ var addNum = 10;
+ var testType;
+ // Uncomment below line to run perf tests - note SLOW to run
+ //testType = "perf";
dojo.addOnLoad(function(){
doh.register("tests",
@@ -34,20 +55,6 @@
ms1.invertSelection();
t.is(["TN","CA"], form.attr("value").ms1);
},
- function test_performance(t){
- var i, start, add, del, opts = [];
- for(i = 0; i < perfNum; i++){
- opts.push({value: i + "", label: "Option " + (i + 1)});
- }
- start = new Date();
- ms3.addOption(opts);
- add = new Date();
- ms3.removeOption(opts);
- del = new Date();
- console.log("Create (" + perfNum + "): " + (add.getTime() - start.getTime()) +
- "ms, Remove: " + (del.getTime() - add.getTime()) + "ms");
- t.t(true);
- },
function delete_selected(t){
t.is(["TN","CA"], ms1.getValue());
var d = new doh.Deferred();
@@ -59,6 +66,141 @@
}catch(e){ d.errback(e); }
}, 100);
return d;
+ },
+ function test_storeBased(t){
+ t.is([], ms4.attr("value"));
+ ms4.attr("value", ["CA","AL"]);
+ t.is(["AL","CA"], ms4.attr("value"));
+ },
+ function test_changeSelected(t){
+ t.is([], ms5.attr("value"));
+ ms5.attr("value", ["AL", "AK"]);
+ var d = new doh.Deferred();
+ var cb = function(item){
+ try{
+ writeStore.setValue(item, "label", "North Pole");
+ try{
+ t.is(["AL","AK"], ms5.attr("value"));
+ t.is(writeStore.getValue(item, "label"),
+ dojo.filter(ms5._getChildren(), function(n){return n.option.value==="AK";})[0].labelNode.innerHTML);
+ d.callback(true);
+ }catch(e){ d.errback(e);}
+ }
+ catch(e){
+ d.errback(e);
+ }
+ }
+ writeStore.fetchItemByIdentity({identity: "AK", onItem: cb});
+ return d;
+ },
+ function test_deleteNonSelected(t){
+ t.is(["AL","AK"], ms5.attr("value"));
+ var d = new doh.Deferred();
+ var cb = function(item){
+ try{
+ t.is(7, ms5._getChildren().length);
+ writeStore.deleteItem(item);
+ try{
+ t.is(["AL","AK"], ms5.attr("value"));
+ t.is(6, ms5._getChildren().length);
+ d.callback(true);
+ }catch(e){ d.errback(e);}
+ }catch (e){
+ d.errback(e);
+ }
+ }
+ writeStore.fetchItemByIdentity({identity: "AZ", onItem: cb});
+ return d;
+ },
+ function test_deleteSelected(t){
+ t.is(["AL","AK"], ms5.attr("value"));
+ var d = new doh.Deferred();
+ var cb = function(item){
+ try{
+ t.is(6, ms5._getChildren().length);
+ writeStore.deleteItem(item);
+ try{
+ t.is(["AL"], ms5.attr("value"));
+ t.is(5, ms5._getChildren().length);
+ d.callback(true);
+ }catch(e){ d.errback(e);}
+ }catch (e){
+ d.errback(e);
+ }
+ }
+ writeStore.fetchItemByIdentity({identity: "AK", onItem: cb});
+ return d;
+ },
+ function test_newItem(t){
+ t.is(["AL"], ms5.attr("value"));
+ t.is(5, ms5._getChildren().length);
+ ms5.attr("value", ["AL","NY"]);
+ t.is(["AL"], ms5.attr("value"));
+ var d = new doh.Deferred();
+ writeStore.newItem({value: "NY", label: "New York"});
+ try{
+ t.is(6, ms5._getChildren().length);
+ ms5.attr("value", ["AL","NY"]);
+ t.is(["AL","NY"], ms5.attr("value"));
+ d.callback(true);
+ }catch(e){d.errback(e);}
+ return d;
+ },
+ {
+ name: "test_performance_single",
+ testType: testType,
+ trialDuration: 100,
+ trialIterations: 100,
+ trialDelay: 100,
+ runTest: function(t){
+ var opt = {value: "Test", label: "Test Option"};
+ ms3.addOption(opt);
+ ms3.removeOption(opt);
+ }
+ },
+ {
+ name: "test_performance_separate",
+ testType: testType,
+ trialDuration: 100,
+ trialIterations: 100,
+ trialDelay: 100,
+ setUp: function(t){
+ var opts = t.options = [];
+ for(var i = 0; i < addNum; i++){
+ opts.push({value: i + "", label: "Option " + (i + 1)});
+ }
+ },
+ runTest: function(t){
+ dojo.forEach(t.options, function(opt){
+ ms3.addOption(opt);
+ });
+ dojo.forEach(t.options, function(opt){
+ ms3.removeOption(opt);
+ });
+ },
+ tearDown: function(t){
+ delete t.options;
+ }
+ },
+ {
+ name: "test_performance_batch",
+ testType: testType,
+ trialDuration: 100,
+ trialIterations: 100,
+ trialDelay: 100,
+ setUp: function(t){
+ var opts = t.options = [];
+ for(var i = 0; i < addNum; i++){
+ opts.push({value: i + "", label: "Option " + (i + 1)});
+ }
+ },
+ runTest: function(t){
+ ms3.addOption(t.options);
+ ms3.removeOption(t.options);
+ },
+ tearDown: function(t){
+ delete t.options;
+ }
}
]
);
@@ -124,6 +266,12 @@
<select jsId="ss3" name="ss3" dojoType="dojox.form.CheckedMultiSelect">
</select>
<hr>
+ <h4 class="testSubtitle">Store-based</h4>
+ <select jsId="ms4" multiple="true" size="5" name="ms4" store="readStore" dojoType="dojox.form.CheckedMultiSelect">
+ </select>
+ <select jsId="ms5" multiple="true" size="5" name="ms5" store="writeStore" dojoType="dojox.form.CheckedMultiSelect">
+ </select>
+ <hr>
<button dojoType="dijit.form.Button">
<script type="dojo/method" event="onClick">
console.dir(form.attr("value"));
Modified: dojox/trunk/form/tests/test_DropDownSelect.html
==============================================================================
--- dojox/trunk/form/tests/test_DropDownSelect.html (original)
+++ dojox/trunk/form/tests/test_DropDownSelect.html Fri Jun 5 13:59:15 2009
@@ -21,6 +21,7 @@
dojo.require("dijit.form.Button");
dojo.require("dijit.form.Form");
dojo.require("dojox.form.CheckedMultiSelect");
+ dojo.require("dojo.data.ItemFileWriteStore");
var numOptions = 0;
var numChanges = 0;
@@ -29,6 +30,42 @@
// Uncomment below line to run perf tests - note SLOW to run
// testType = "perf";
+ // Data and stores here for store-based selects
+ var data = {
+ identifier: "value",
+ label: "label",
+ items: [
+ {value: "AL", label: "Alabama"},
+ {value: "AK", label: "Alaska"},
+ {value: "AZ", label: "Arizona"},
+ {value: "AR", label: "Arkansas"},
+ {value: "CA", label: "California"},
+ {value: "CO", label: "Colorado"},
+ {value: "CT", label: "Connecticut"}
+ ]
+ };
+ var data2 = {
+ identifier: "value",
+ label: "label",
+ items: [
+ {value: "DE", label: "Deleware"},
+ {value: "FL", label: "Florida"},
+ {value: "GA", label: "Georgia"},
+ {value: "HI", label: "Hawaii"},
+ {value: "ID", label: "Idaho"},
+ {value: "IL", label: "Illinois"},
+ {value: "IN", label: "Indiana"}
+ ]
+ };
+
+ var readStore = new dojo.data.ItemFileReadStore({data:dojo.clone(data)});
+ var store2 = new dojo.data.ItemFileReadStore({data:dojo.clone(data2)});
+ var writeStore = new dojo.data.ItemFileWriteStore({data:dojo.clone(data)});
+
+ function wrapLabel(expected){
+ return ("<span class=\"dijitReset dijitInline dojoxDropDownSelectLabel\">" + expected + "</span>").toLowerCase().replace(/ */g, "");
+ }
+
dojo.addOnLoad(function(){
dojo.connect(s1, "onChange", function(val){
console.log("First Select Changed to " + val);
@@ -37,13 +74,110 @@
doh.register("tests",
[
function test_setValue(t){
- t.is({s1:"VA", s2:"CA", s3:"AL", s4: "AK", s5: "move", s7:"NY", s8:"AL"}, form.attr("value"));
+ t.is({s1:"VA", s2:"CA", s3:"AL", s4: "AK", s5: "move", s7:"NY", s8:"AL",
+ s9:"CT", s10:"AL", s11:"AL", s12: "AL"}, form.attr("value"));
s1.attr("value", "WA");
t.is("WA", s1.value);
s1.attr("value", "UT");
t.is("TN", s1.value);
t.is(2, numChanges);
},
+ function test_changeSelected(t){
+ t.is("AL", s11.value);
+ t.is(wrapLabel("Alabama"), s11.containerNode.innerHTML.toLowerCase().replace(/ */g, ""));
+ s11.attr("value", "AK");
+ t.is("AK", s11.value);
+ t.is(wrapLabel("Alaska"), s11.containerNode.innerHTML.toLowerCase().replace(/ */g, ""));
+ var d = new doh.Deferred();
+ var cb = function(item){
+ try{
+ writeStore.setValue(item, "label", "North Pole");
+ s11.loadDropDown(function(){
+ try{
+ t.is("AK", s11.value);
+ t.is(wrapLabel("North Pole"), s11.containerNode.innerHTML.toLowerCase().replace(/ */g, ""));
+ d.callback(true);
+ }catch(e){ d.errback(e);}
+ });
+ }
+ catch(e){
+ d.errback(e);
+ }
+ }
+ writeStore.fetchItemByIdentity({identity: "AK", onItem: cb});
+ return d;
+ },
+ function test_deleteNonSelected(t){
+ t.is(7, s11._getChildren().length);
+ t.is("AK", s11.value);
+ var d = new doh.Deferred();
+ var cb = function(item){
+ try{
+ t.is(7, s11._getChildren().length);
+ writeStore.deleteItem(item);
+ s11.loadDropDown(function(){
+ try{
+ t.is("AK", s11.value);
+ t.is(6, s11._getChildren().length);
+ d.callback(true);
+ }catch(e){ d.errback(e);}
+ });
+ }catch (e){
+ d.errback(e);
+ }
+ }
+ writeStore.fetchItemByIdentity({identity: "AZ", onItem: cb});
+ return d;
+ },
+ function test_deleteSelected(t){
+ t.is(6, s11._getChildren().length);
+ t.is("AK", s11.value);
+ var d = new doh.Deferred();
+ var cb = function(item){
+ try{
+ writeStore.deleteItem(item);
+ window.setTimeout(function(){
+ try{
+ t.is("AL", s11.value);
+ d.callback(true);
+ }catch(e){d.errback(e);}
+ }, 100);
+ }catch (e){
+ d.errback(e);
+ }
+ }
+ writeStore.fetchItemByIdentity({identity: "AK", onItem: cb});
+ return d;
+ },
+ function test_newItem(t){
+ t.is(5, s11._getChildren().length);
+ t.is("AL", s11.value);
+ s11.attr("value", "NY");
+ t.is("AL", s11.value);
+ var d = new doh.Deferred();
+ writeStore.newItem({value: "NY", label: "New York"});
+ window.setTimeout(function(){
+ try{
+ t.is(6, s11._getChildren().length);
+ s11.attr("value", "NY");
+ t.is("NY", s11.value);
+ d.callback(true);
+ } catch (e) {
+ d.errback(e);
+ }
+ }, 100);
+ return d;
+ },
+ function test_setStore(t){
+ t.is("AL", s12.value);
+ s12.setStore(store2, "FL");
+ t.is("FL", s12.value);
+ s12.setStore(readStore, "CA");
+ t.is("CA", s12.value);
+ s12.setStore(store2);
+ t.is("DE", s12.value);
+ t.is(7, s12._getChildren().length);
+ },
{
name: "test_performance_single",
testType: testType,
@@ -99,7 +233,7 @@
tearDown: function(t){
delete t.options;
}
- },
+ }
]
);
doh.run();
@@ -214,13 +348,24 @@
<option value="WI">Wisconsin</option>
<option value="WY">Wyoming</option>
</select>
+ <hr>
+ <h4 class="testSubtitle">Store-based</h4>
+ <select jsId="s9" name="s9" store="readStore" value="CT" dojoType="dojox.form.DropDownSelect">
+ </select>
+ <select jsId="s10" name="s10" store="readStore" dojoType="dojox.form.DropDownSelect">
+ </select>
+ <select jsId="s11" name="s11" store="writeStore" dojoType="dojox.form.DropDownSelect">
+ </select>
+ <select jsId="s12" name="s12" store="readStore" dojoType="dojox.form.DropDownSelect">
+ </select>
+ <hr>
<h4 class="testSubtitle">Inlined with text (all IE modes except for IE8 Standards)</h4>
Text Prompt:
<select dojoType="dojox.form.DropDownSelect">
<option value="SEL" selected="selected">DropDownSelect</option>
<option value="OTHER">Other</option>
</select>
-
+ <hr>
<h4 class="testSubtitle">DropDownSelect.updateOptions</h4>
<div>Click on the DropDownSelect to open the DropDown. While the DropDown is opened, click on a checkbox.</div>
<select id="updateOptions" dojoType="dojox.form.DropDownSelect">
@@ -238,8 +383,7 @@
<option value="FL">Florida</option>
<option value="CA">California</option>
</select>
-
- <hr>
+ <hr>
<button dojoType="dijit.form.Button">
<script type="dojo/method" event="onClick">
console.dir(form.getValues());
More information about the Dojo-checkins
mailing list