Login Register

FilteringSelect

FilteringSelect is like an HTML SELECT tag, but is populated dynamically. It works very nicely with very large data sets because it can load and page data as needed. It also resembles ComboBox, but does not allow values outside of the provided ones.

When the user tries to submit invalid input (say if they choose an option, and the legal options change) the user gets a warning message, but the Select keeps text box input as is and also keeps the last valid submit value. If the user selects the text box and presses Escape on the keyboard, the text box reverts to the last valid value, corresponding to the hidden value. This change guarantees that you will always get a valid submit value.

Examples

First, here is a FilteringSelect with inlined data:

<!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>Filter Select Example 1</title>
    <style type="text/css">
        @import "http://o.aolcdn.com/dojo/1.0/dijit/themes/tundra/tundra.css";
        @import "http://o.aolcdn.com/dojo/1.0/dojo/resources/dojo.css"
    </style>
    <script type="text/javascript" src="http://o.aolcdn.com/dojo/1.0/dojo/dojo.xd.js"
        djConfig="parseOnLoad: true">
</script>
    <script type="text/javascript">
       dojo.require("dojo.parser");
       dojo.require("dijit.form.FilteringSelect");
     </script>
</head>
<body class="tundra">
        <select dojoType="dijit.form.FilteringSelect"
        name="state3"
        autocomplete="false"
        value="CA">

                <option value="CA" selected="selected">California</option>
                <option value="IL" >Illinois</option>
                <option value="NY" >New York</option>
                <option value="TX" >Texas</option>
        </select>
</body></html>

As with ComboBox, has a value attribute. Unlike ComboBox, this value refers to the value attribute of the <option> tag. For example, if you set the value to AL, the text "Alabama" will appear in the text box on load. If you want to change the value attribute programmatically, use

dijit.byId("yourwidgetid").setValue("yourhiddenvalue")

Like ComboBox FilteringSelect is dojo.data-enabled. As with all dojo.data stores, you can add an identifier field to the top level of your data. The value of the identifier field tells the store which field in your data contains the submit value. Here's an example from states.txt:

{
identifier:"abbreviation",
items: [
        {name:"Alabama", label:"Alabama",abbreviation:"AL"},
        ...

This code shows an identifier set to abbreviation. The identifier instructs the dojo.data store to set the submit value of the items in this store to the value of the attribute named abbreviation. In this example, the first item has a field named abbreviation with a value of AL. If one of your users selected that item in your FilteringSelect, the form would submit AL to your server.

Here's the corresponding FilteringSelect

<!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>Data-Enabled FilteringSelect</title>
    <style type="text/css">
        @import "http://o.aolcdn.com/dojo/1.0/dijit/themes/tundra/tundra.css";
        @import "http://o.aolcdn.com/dojo/1.0/dojo/resources/dojo.css"
    </style>
    <script type="text/javascript" src="http://o.aolcdn.com/dojo/1.0/dojo/dojo.xd.js"
        djConfig="parseOnLoad: true">
</script>
        <script type="text/javascript">
       dojo.require("dojo.parser");
       dojo.require("dijit.form.FilteringSelect");
       dojo.require("dojo.data.ItemFileReadStore");
   </script>
</head>
<body class="tundra">
        <div dojoType="dojo.data.ItemFileReadStore" jsId="stateStore"
              url="states.txt">
</div>
        <form method="post">
                <input dojoType="dijit.form.FilteringSelect"
                    store="stateStore"
                        searchAttr="name"
                        name="state1"
                        autocomplete="true"
                        />

            <input type="submit" value="Go!" />
        </form>
</body></html>

The net result of the identifier is that you can easily set the submit attribute of any number of Selects using the same data without actually adding extra attributes to the Selects.

dijit.form.FilteringSelect
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/td>
ignoreCase Boolean
true
Does the ComboBox menu ignore case?
labelAttr String
searchAttr
String Searches pattern match against this field String Optional. The text that actually appears in the drop down. If not specified, the searchAttr text is used instead.
labelType String
text
"html" or "text"
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 String Reference to data provider object used by this ComboBox.
Methods
setDisplayedValue(/*String*/ label) Set label (and corresponding value) to "label"
setValue(/*String*/ value) Set value (and corresponding label) to "value"

Accessibility

Keyboard

ActionKey
Open the menu of options (filtered by current input)Down arrow
Navigate through the optionsUp and down arrows
Pick an optionEnter
Close the menu of options without picking oneEsc

Known Issues

JAWS 8 and Window-Eyes 6 may fail to read an option when it becomes highlighted.

AttachmentSize
states.txt3.76 KB

DISABLED and READONLY

Also, this widget is missing the "DISABLED" and "READONLY" attributes. Or has it been intentionally left out to bring in a new implementation that I am not aware of?

Since I am loading the option values dynamically, I want to disable the select box when the value "None" is iterated as the only choice. They can still type invalid values (e.g. "No"), and this shouldn't be allowed.

- Minh

See...

... the Common Features section of Part 2. All HTML attributes that are not widget attributes are copied over. In addition, you may set the disabled property programmatically with dijit.byId("whatever").setDisabled(true);

Has this been tested or verified by anyone?

This seems to imply that I can write

<input dojoType="dijit.form.FilteringSelect" readonly ...>

and prevent users from typing into the edit field that the control is converted to. This is not the case using Dojo 1.0.2 based on my tests.

I want a real option control in which only the options in the list can possibly be entered, which I think is a very key quality of the original HTML control.

real option conrol

I encountered the same problem. I want to use filteringSelect in a way that just it's options can be entered.
I still didn't find good solution for that.

Form with input dojoType="dijit.form.FilteringSelect"

Hi,

When it`s submited a form with widget dijit.form.FilteringSelect, are sending two parameters with the same value and distinct name.
the name one is good and other is empty.

the output server after submit is :

28-sep-2007 12:54:46 org.apache.tomcat.util.http.Parameters processParameters
WARNING: Parameters: Invalid chunk ignored.

the url generated after submit is:
http://localhost:8080/app/frameset?=All&codigo=All&__format=html&__repor...

WARNING!
(=All&Codigo=All)

i think that the problem is in generated code of FilteringSelect:

how can i avoid this behaviour?

thanks!
donkelito

The Easiest Way...

... is to use a DIV instead of an INPUT box. The only problem is this doesn't degrade well - e.g. if JS is turned off or it's run in an older browser, the user will be left with no way to select something.

Or you can get around the problem altogether by submitting the form via XHR, where you can carefully control the parameters. It may require rearchitecting the app, but it often pays dividends.

dojo/method not applyable ?!

i try to use the great feature dojo/method, but i cannot make it work in conjuntion with FilteringSelect. Is this feature not supported for FilteringSelect or do i make a mistake?

this code fragment is placed within the <_select> tag!

<_script type="dojo/method" event="onChange">
alert('change');
<_/script>
(I use the _, otherwise the script tag wont appear ...)

In comparison dojo.connect works fine!
dojo.addOnLoad(function() {
dojo.connect(dijit.byId('liniennr'), 'onChange', 'test');
});

greetings

Accless

Validating input

This code snippet can be used to alert the user that the text they entered is invalid. It then replaces their invalid entry with the previous value.

<!-- Use onblur event to trigger check -->
<select name="event_level_threshold" dojoAttachPoint="event_level_threshold" dojoType="dijit.form.FilteringSelect"
onblur="checkOptions(this)">

<option>1</option>
<option>2</option>
</select>

function checkOptions(e)
{
        if (e.isValid())
                return;
        var dojoe=dojo.byId(e.id);
        alert(dojoe.value+' is invalid');
        var dijite=dijit.byId(e.id);
        dijite.setValue(dojoe.getAttribute('valuenow'));
        dijite.setDisplayedValue(dojoe.getAttribute('valuenow'));
}


PS - I'm a newbie - comments, improvements welcome. Code was edited for the post, may have syntax errors.

Validating Input DURING (and not after) user input

Hi @ll,

a better approach for validating uers input is to connect the validate process to 'validate' instead of 'onblur'.

var myFilterWidget = dijit.byId(yourFilterSelectID);
var myOKButton   = dijit.byId(yourOkButtonID);

dojo.connect(myFilterWidget,'validate','setDisabledOKButton');

function setDisabledOKButton() {
   myOKButton.setDisabled(!(myFilterWidget.isValid());
}

The advantage is, that other depending widgets (like an OK-Button for proceeding) are already rendered during user input.

Greetings

AccLess

PS: Tested with Dojo 0.9

A Filtering select doesn't drop in Opera

A Filtering select doesn't drop in Opera. Internet Explorer and Mozilla don't have such problems. I thought it was a bug in my application, but in the examples from the site there is also such a problem.

when execute the method setDisabled, my widget disappear

When execute the method setDisabled in FilteringSelect widget, this one disappears. If i click in dissapeared widget gap the widget appears disabled. This behaviour is like the widget wasn´t painted in my firefox. In IE works fine. Dojo toolkit 0.9.0, any Idea?

Preventing FilteringSelect from disappearing

Hi @ll,

i just encountered the same problem with dojo 0.9. Just copy this line of code and put it right after invoking setDisabled()!

dijit.byId(yourWidgetId).domNode.style.display='block';

It works with FF 2.0.

Greetings

accless

Page broken

Hi,

This page is broken, it can't be viewed with IE7. It throws an "Operation aborted" error. The problem is that the Javascript is adding elements to the DOM before it is completely parsed. To fix it move this lines:

dojo.parser.parse(dojo.byId("code1"));
dojo.parser.parse(dojo.byId("code2"));

to an onLoad event:

dojo.addOnLoad( function() {
	dojo.parser.parse(dojo.byId("code1"));
	dojo.parser.parse(dojo.byId("code2"));
});

Some other pages in the Book of Dojo are also broken in the same way.

Dynamic loading of Data

Is it possible, to use a kind of dynamic datastore?
I want to have a FilteringSelect widget, that every time it is used by the user connects to url and also submit other form field values. The server than can use the values to generate adapted response. Then the FilteringSelect widget must to be refreshed.
Is there a way?

Dynamic loading example

var select = dijit.byId("selectId");
var url = "/foo/bar.php?load=23";

var store = new dojo.data.ItemFileReadStore({url:url});
select.store = store;

Hope this helps!

QueryReadStore will not work with FilteringSelect

Just a note, QueryReadStore will not work with a FilteringSelect, after each character you type it will re-fetch from the server and essentially reset your Select when you leave the field. This is also true if you Select an item from the field. I guess this is the "expected" behavior with this data store:

http://trac.dojotoolkit.org/ticket/6071

Per Manel Clos' comment above, the only way that I know of to re-fetch your data from the server is to create a new store and assign it to the widget. Trac 6073 asks if we can enhance ItemFileReadStore to be able to re-fetch from the server instead of using the cached data.

Josh

Actually I'm wrong on this -

Actually I'm wrong on this - you can use QueryReadStore with FilteringSelect as long as your server-side callback handles the paramaters on the query string correctly - see comments in the trac link.

Josh

To Destroy

//fabiohenriqueviana@hotmail.com
var myDijit = dojo.byId('mydiv');
if (myDijit != null) {myDijit.destroy();}

Disable text input

Hi,

Consultation, how disables text input, for use as an element COMBOBOX common?
Are understand?
The idea is that the user does not enter into the combobox.

Thanks!