- The Book of Dojo
- Quick Installation
- Hello World
- Debugging Tutorial
- Introduction
- Part 1: Life With Dojo
- Part 2: Dijit
- Part 3: JavaScript With Dojo and Dijit
- Part 4: Testing, Tuning and Debugging
- Part 5: DojoX
- The Dojo Book, 0.4
ComboBox
Submitted by simonjb on Sat, 05/05/2007 - 21:28.
The ComboBox is a hybrid between a SELECT combo box and a text field. Like a SELECT, you provide a list of acceptable values. Unlike SELECT, and like a text box, the user can ignore all the choices and type whatever they want. This is especially good for open-ended multiple choice questions. Rather than having two fields - a combo box and an Other text box - you can use just one field.
Note that SELECT's always have value/description pairs, e.g. the OPTION's value attribute and the OPTION's body text. ComboBoxes do not. They only pass their displayed text - just like a text box.
Examples
Using inlined data with the ComboBox is very much like using a native <select>
tag:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Simple ComboBox</title>
<style type="text/css">
@import "http://o.aolcdn.com/dojo/1.0.0/dijit/themes/tundra/tundra.css";
@import "http://o.aolcdn.com/dojo/1.0.0/dojo/resources/dojo.css"
</style>
<script type="text/javascript" src="http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.xd.js"
djConfig="parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dojo.parser");
dojo.require("dijit.form.ComboBox");
function setVal1(value) {
console.debug("Selected "+value);
}
</script>
</head>
<body class="tundra">
<select name="state1"
dojoType="dijit.form.ComboBox"
autocomplete="false"
value="California"
onChange="setVal1">
<option selected="selected">California</option>
<option >Illinois</option>
<option >New York</option>
<option >Texas</option>
</select>
</body></html>
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Simple ComboBox</title>
<style type="text/css">
@import "http://o.aolcdn.com/dojo/1.0.0/dijit/themes/tundra/tundra.css";
@import "http://o.aolcdn.com/dojo/1.0.0/dojo/resources/dojo.css"
</style>
<script type="text/javascript" src="http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.xd.js"
djConfig="parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dojo.parser");
dojo.require("dijit.form.ComboBox");
function setVal1(value) {
console.debug("Selected "+value);
}
</script>
</head>
<body class="tundra">
<select name="state1"
dojoType="dijit.form.ComboBox"
autocomplete="false"
value="California"
onChange="setVal1">
<option selected="selected">California</option>
<option >Illinois</option>
<option >New York</option>
<option >Texas</option>
</select>
</body></html>
Name and autocomplete are passed through to the HTML. The value attribute enables you to set the default value. The option tags do not have hidden submit values; to use a hidden value, change your ComboBoxes to FilteringSelects.
Important: IE7 only uses the selected attribute of an option tag and ignores the value attribute on the select tag. For best results, set both the selected attribute on the default option and the value attribute on the select.
dojo.Data-Enabled ComboBox
ComboBox, FilteringSelect, Tree and Grid are dojo.data-Enabled widgets. This means rather than specifying all the data in the page - the OPTION's or tree nodes - you can have dojo.data fetch them from a server-based store. The unified dojo.data architecture, can get its data from various places - databases, web services, etc.. See the dojo.data manual section for complete details.
The code:
<div dojoType="dojo.data.ItemFileReadStore" jsId="stateStore"
url="states.txt"></div>
url="states.txt"></div>
... looks like a widget, but it's not. (Only dojoTypes from the module dijit.___ are widgets). This tag takes advantage of dojo.parser, which creates JavaScript objects by using standard HTML. You can read about Dojo.parser at Understanding the Parser in Part 3.
For this example, we'll use a fixed JSON data store. You can download it from states.txt below. Here's an excerpt:
{
identifier:"abbreviation",
items: [
{name:"Alabama", label:"Alabama",abbreviation:"AL"},
{name:"Alaska", label:"Alaska",abbreviation:"AK"},
{name:"American Samoa", label:"American Samoa",abbreviation:"AS"},
{name:"Arizona", label:"Arizona",abbreviation:"AZ"},
identifier:"abbreviation",
items: [
{name:"Alabama", label:"Alabama",abbreviation:"AL"},
{name:"Alaska", label:"Alaska",abbreviation:"AK"},
{name:"American Samoa", label:"American Samoa",abbreviation:"AS"},
{name:"Arizona", label:"Arizona",abbreviation:"AZ"},
The following example makes use of our data store:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Simple ComboBox</title>
<style type="text/css">
@import "http://o.aolcdn.com/dojo/1.0.0/dijit/themes/tundra/tundra.css";
@import "http://o.aolcdn.com/dojo/1.0.0/dojo/resources/dojo.css"
</style>
<script type="text/javascript" src="http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.xd.js"
djConfig="parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dojo.parser");
dojo.require("dijit.form.ComboBox");
dojo.require("dojo.data.ItemFileReadStore");
function setVal2(value) {
console.debug("Selected "+value);
}
</script>
</head>
<body class="tundra">
<div dojoType="dojo.data.ItemFileReadStore" jsId="stateStore"
url="states.txt"></div>
<input dojoType="dijit.form.ComboBox"
store="stateStore"
value="California"
searchAttr="name"
name="state2"
onChange="setVal2" />
</body></html>
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Simple ComboBox</title>
<style type="text/css">
@import "http://o.aolcdn.com/dojo/1.0.0/dijit/themes/tundra/tundra.css";
@import "http://o.aolcdn.com/dojo/1.0.0/dojo/resources/dojo.css"
</style>
<script type="text/javascript" src="http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.xd.js"
djConfig="parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dojo.parser");
dojo.require("dijit.form.ComboBox");
dojo.require("dojo.data.ItemFileReadStore");
function setVal2(value) {
console.debug("Selected "+value);
}
</script>
</head>
<body class="tundra">
<div dojoType="dojo.data.ItemFileReadStore" jsId="stateStore"
url="states.txt"></div>
<input dojoType="dijit.form.ComboBox"
store="stateStore"
value="California"
searchAttr="name"
name="state2"
onChange="setVal2" />
</body></html>
jsId
is the name of the global variable that the store is assigned to. url
can be used to suck data out of particular URL, perhaps a web service.
Instead of using the url
attribute, you can embed your data directly (as is common in traditional server-side programming) using the data
attribute.
dijit.form.ComboBox
Auto-completing text box The drop down box's values are populated from an class called a data provider, which returns a list of values based on the characters that the user has typed into the input box. Some of the options to the ComboBox are actually arguments to the data provider.
|
||
Attributes
|
||
autoComplete | Boolean true |
If you type in a partial string, and then tab out of the <input> box, automatically copy the first entry displayed in the drop down list to the <input> field |
hasDownArrow | Boolean true |
Set this textbox to have a down arrow button |
ignoreCase | Boolean true |
True if the ComboBox should ignore case when matching possible items. |
pageSize | Integer Infinity |
Argument to data provider. Specifies number of search results per page (before hitting "next" button) |
query | Object {} |
A query that can be passed to 'store' to initially filter the items, before doing further filtering based on searchAttr and the key. |
searchAttr | String name |
Searches pattern match against this field |
searchDelay | Integer 100 |
Delay in milliseconds between when user types something and we start searching based on that value |
store | Object | Reference to data provider object used by this ComboBox. |
Accessibility
Keyboard
Action | Key |
---|---|
Open the menu of options (filtered by current input) | Down arrow |
Navigate through the options | Up and down arrows |
Pick an option | Enter |
Close the menu of options without picking one | Esc |
Known Issues (updated for 1.1)
JAWS 8 and Window-Eyes 6 may fail to read an option when it becomes highlighted. In Dojo 1.1 the Combobox was updated so that JAWS 9 will speak "editable combo" when the Combobox gets focus. However, there are some issues reading the highlighted choice. Generally JAWS 9 with Firefox 2 will only speak the part of the word that is currently selected in the textbox. For example, if you are working with a ComboBox containing the US state names and you type in an "I" to filter the list of states. If the user arrows down and highlights "Iowa" in the drop down list, "Iowa" will be displayed in the textbox with the "owa" portiion selected. JAWS 9 will speak, "owa" rather than "Iowa". This is not an issue with Firefox 3 and JAWS 9.
Attachment | Size |
---|---|
states.txt | 3.76 KB |
- Printer-friendly version
- Login or register to post comments
- Subscribe post
json schema
I'm confused about the schema of the json provided to the combobox, particularly the meaning of 'identifier'. 'name' seems to be the only one with meaning, as specified by the searchAttr (we need to doc this better. Do the other attributes play any role?
unique ID
identifier tells the DataStore what field in the dataset is the unique identifier. The others are more or less arbitrary I believe... except Label... which specifics the rootNode's label when not building a "forest" tree.
-Karl
well, that's part of my confusion
'label' appears to have no meaning to ComboBox, AFAICT. Perhaps we can provide a reference to the dojo.data docs where the identifier stuff is explained?
labelAttr?
Someone on IRC said there's a labelAttr attribute, though I don't see one. searchAttr is there, though it probably needs to be stressed how this applies to the data model. An introductory paragraph to discuss the relation to data model might be helpful.
Nope, that's FilteringSelect
As stated in the first section: "Note that SELECT's always have value/description pairs, e.g. the OPTION's value attribute and the OPTION's body text. ComboBoxes do not. They only pass their displayed text - just like a text box."
How to populate ComboBox with options programatically
options.newItem({name: 'foo'});
options.newItem({name: 'bar'});
var comboBoxFetchStrategy = new dijit.form.ComboBox(
{store: options, onChange: whatever},
dummyElement,
);
comboBoxFetchStrategy.setValue("foo");
Attach onchange
Code snippet.
value: '',
name:"myComboBox",
id:"myComboBox",
store: myStore,
searchAttr:"name",
onChange:checkCombo
}, dojo.byId("frmInput"));
dojo.connect(dojo.byId('frmInput'),'onchange','checkCombo');
function checkCombo(e)
/*
This function handles two types of events - onChange (specified in the 'new dijit.form.ComboBox' code), and onchange (from the connect statement).
When onChange fires, e is a string, and the function returns true or false to indicate valid or not.
When onchange fires, e is an event, and allows you to modify the target attribute. In this case, it corrects the input by converting & to and.
Don't call it twice - meaning in both the creation of the ComboBox and with a connect. It won't do any harm, it is just unnecessary.
*/
{
switch (typeof e)
{
case 'object':
if (e.type == 'change')
{
var invalidChars=/&/;
var dojoe=dojo.byId(e.target.id);
var v=dojoe.value;
if (!v.match(invalidChars))
return true;
var v2=v.replace(/\ ?&\ ?/g,' and ');
var dijite=dijit.byId(e.target.id);
dijite.setValue(v2);
dijite.setDisplayedValue(v2);
return false;
}
break;
case 'string':
var invalidChars=/&/;
if (!e.match(invalidChars))
return true;
return false;
break;
}
return true;
}
PS - Still a newbie, code was edited for the post, may have errors. dojo 0.9
Dynamic creation
hi,
is there a way i could create this ComboBox dynamically?
Is there a way to attach onmouseover to combobox list and show
tool tip there.
for Json
{identifier:"rsFormId",
items: [
{rsFormId:"7021366",medName:"100/Sinemet-25(Carbidopa/Levodopa)", render:"false", originalIndex:"1161", status:"Active",abbreviation:"3000260029"},
{rsFormId:"7001110", medName:"Accupril (Quinapril Hcl)",render:"true",originalIndex:"1162",status:"Active",abbreviation:"3000273940"},
{rsFormId:"520308391",medName:"Accupril (Quinapril Hcl)",render:"true",originalIndex:"120",status:"Active",abbreviation:"3000273941"}
]
}
when render = true, that element needed to red and then onmouseover there should be a tool tip to tell this is danger drug.
Please help me.
Regards,
Sagar
Error: this.onChange is not a function
I have specified onChange as one of the atttribute.
for this statement I am getting error as,
this.onChange is not a function.
I am not getting whats wrong in the statement.
Any help will be appreciated.
Thanks.
classes and styles desactivated
I'm a novice with dojo stuff, and I tried to use a dijit combo box in a form.
This form is used to create geographic subdivisions (ie a city in a region, a neighbourhood in a city). I need to put a combobox to select the "parent" of the new element.
For a better readability in the whole list, i've choosen to increase the left padding in option tags depending on the level.
It works fine without dijit (top level values are not indented, level 1 values have a 15px padding, etc).
But with dijit styles and classes are deactivated, and all the values have the same look... and in the whole list it's very hard to find the right value...
Any idea?
_bertrand
here is my solution
I couldn't wait so I've decided to edit the .js file...
first: keep class and style attributes:
by changing this:
node.style.display="none";
return { value: node.getAttribute("value"), name: String(node.innerHTML) };
by this:
var bwt= { value: node.getAttribute("value"), name: String(node.innerHTML), style:node.getAttribute("style"), class:node.getAttribute("class") };
node.style.display="none";
return bwt;
second: set the attribute style and add the class to the dijit class:
by changing this:
dojo.forEach(results, function(item){
var menuitem=_this._createOption(item, labelFunc);
menuitem.className = "dijitMenuItem";
_this.domNode.insertBefore(menuitem, _this.nextButton);
});
by this:
dojo.forEach(results, function(item){
var menuitem=_this._createOption(item, labelFunc);
menuitem.className = "dijitMenuItem"+(item.class!='' ? ' '+item.class : '');
menuitem.setAttribute("style",item.style);
_this.domNode.insertBefore(menuitem, _this.nextButton);
});
Now, everything's perfect!
using this property
dear iBEb,
your attachments looks good.i made some fixing according to your codes but how we use this property? could you explain more?
thanks your interest :)
i've changed my code,
i've changed my code, because "class" was not working on safari.
bwtS=node.getAttribute("style")?node.getAttribute("style"):'';
bwtC=node.getAttribute("class")?node.getAttribute("class"):'';
bwt={ value: node.getAttribute("value"), name: String(node.innerHTML), classe: bwtC, style: bwtS };
node.style.display="none";
return bwt;
}) : {};
and i also changed the code for the class:
var menuitem=_this._createOption(item, labelFunc);
menuitem.className = item.classe!='' ? item.classe : 'dijitMenuItem';
menuitem.setAttribute("style",item.style);
menuitem.value=item.value;
_this.domNode.insertBefore(menuitem, _this.nextButton);
});
you can have a look here : http://admin.absoludream.fr/tests/test_combo.html
padding in option tag doesn't work with ie7 (not a but surprise)... but it works fine with FF and Safari.
Readonly Mode on Input Element
In order to mimic the behaviour of a basic
<select>
element, that is - no editable text entry, you'll want to set "readonly='true'" on the<input>
element in the dijit.ComboBox template file.