Dojo's ComboBox Not Ready for Prime Time?
Posted in dojo, autocomplete, ajax, scriptaculous Sun, 04 Jun 2006 06:21:00 GMT
I've been happily developing with Prototype and Scriptaculous for a while now but was recently convinced to look at Dojo. To start, I was pretty happy with dojo.io.bind but disappointed that I wasn't able to get the Dojo scripts to load from a remote server. Having gotten dojo.io.bind to work, I was off to test my first widget, Dojo's ComboBox, which offers functionality similar to the Scriptaculous autocomplete widget. I've been using Dojo 0.3.0. The Dojo ComboBox Nightly Test is often mentioned as a good place to start so I went there first. Eventually I also spent some time reading and implementing the code at Java.net's AJAX with Dojo and JSON page. In the end I came away disappointed due to several bugs and strange behaviors listed below:
- Default value: Dojo does not let you set a default value via the HTML or any other way. To get a default value to show up, I've heard you can write it in with JavaScript but I'm not sure where or when yet due to the DOM onLoad transform issue described below.
- Single option bug: when the a resulting list only has one item, hitting the 'enter' key will not close the list. With autocomplete, the single entry will already be populated in the box but not selectable with 'enter'. You need to select the single option in the list with the down key and then hit the 'enter' key. To try this out, type in 'am' for American Samoa in the first input on the nightly test and click 'enter' to continue. I haven't found out whether this is being worked on or not.
- DOM onLoad transform: Unlike other libraries, after the page has been rendered Dojo will go back and transform the DOM, replacing dojoTypes with HTML templates. This can cause some timing problems when one wants to use DOM to modify the resulting HTML templates. Dojo provides a dojo.addOnLoad capability to specify a callback function however the new DOM elements don't seem to be available yet. Perhaps something to the effect of dojo.afterDojoOnLoad is needed?
This issue can be seen when trying to remove the ComboBox downArrowNode. The ComboBox comes with a down arrow graphic by default and is assigned dojoattachpoint="downArrowNode". With some lists, the reply possibilities are enormous and a default list isn't desirable. When nothing has been typed, it may also give the impression that the list provided is a complete list like a standard select element. I haven't found a good way to disable this yet. Setting the display property on the downArrowNode isn't a good solution because it only works after the page has been rendered. It can't be set immediately rendering the ComboBox input tag because Dojo hasn't been run yet. Setting the display property in the dojo.addOnLoad callback is also too early, i.e. the widget doesn't exist yet. Here's the JS I've been working with:
var ac = dojo.widget.byId("ac"); ac.downArrowNode.style.display="none";
I've also tried setting downArrow and downArrowNode attributes to 0, -1 and false. So far, the only solution I found that works is to delete or comment out the downArrowNode HTML in the following file:dojo/src/widget/templates/HtmlComboBox.html
Not exactly a great solution. Is there a better way to remove the arrow? - Client-side result filtering: It seems like the Dojo javascript does it's own filtering. You give it a list in the format of an Array of Arrays where each inner array has two elements. Dojo then applies it's own filtering. This is nice if you are working off a local list such as a JS file in the Nightly Test example but if you are retrieving a list from a server, the server should have filtered the list already so there's no reason to filter it a second time. This may be partially at fault for the choppy rendering. Is there any way to disable this?
- Aribitrary location match: Because Dojo does client-side result filtering, the user isn't guaranteed to see what your server delivers. One area this shows up is that it's not clear how to match any part of the string instead of just the beginning. On the nightly test page, the only results presented are ones where the input matches the start of the string so if someone types a last name and the strings have the format "$first_name $last_name" there would not be a match. The DocTool on dojo.org will match inside the string but the rendering seems choppy and I can't seem to locate it any more. I haven't gotten around to seeing how the DocTool does it. The SVN copy of the doctool.html file shows the following which does not result in the desired non-start match for me:
<input dojoType="combobox" id="search" autoComplete="false" value="" style="width: 300px;" >
- HTML result rendering: Often it's nice to show the user which part of the string matched, especially if the match is not at the beginning of the string. This is done by bolding the matching letters a la Gmail. If HTML is included in the array, it is rendered literally instead of interpreted as HTML. Because Dojo does client-side filtering, HTML mark up will also cause matching to fail. With Scriptaculous, you can add HTML mark-up to the results and it will render properly. Perhaps with Dojo, the HTML needs to be added by client-side JavaScript?
These are my initial observations of Dojo's ComboBox. It seems very difficult to get it to DWIW and very different than the Scriptaculous Autocomplete which just works and has been working. Scriptaculous autocomplete has been working like champ for me since prototype 1.3.1 and it's now on 1.5.0 rc0. Please let me know of any ways to accomplish the above Dojo ComboBox issues. Also let me know if you're using Dojo's ComboBox in production and / or your experiences with it.
Hi,
This is Alex Russell, Project Lead for the Dojo Toolkit.
A couple of things:
There are indeed a couple of places where the system needs to be improved, but in general where you think Dojo is lacking it just turns out to be a set of configuration issues.
Regards
Try using
dojo.dom.removeNode(control.downArrowNode);
where control is an element of dojo.widget.widgets filtered by control.declaredClass == “dojo.widget.ComboBox”
That just completely removes the downArrow img tag and by doing so the arrow. Very clean.
One problem i had with some of these autocompletes was that it wasn’t smart enough… ie… if my search term was missing a word, it couldn’t find what i was looking for.
For example, in a db of cameras if I was looking for a “Camera PowerShot sd800 Digital Elph” but only remember the model number, not the full name …so i’d type in “Canon SD800”...and itd give me nothing It wasn’t until i typed in “Canon PowerShot SD…” that it found something. I needed it to ignore that I had forgotten PowerShot
I found a real simple solution – which I describe in detail here – http://www.susanbuck.net/sb/words/index.asp?permanent=yes&;permKey=163
i’m choose country from first Select and then get a list of cities in that country in other Select
Dojo 0.4.3
function selectPunchLocation(location) { //called from select on first list. dojo.io.bind({ url: QUERY, load: function(type, data, evt) { var w = dojo.widget.byId(“PunchDepartment”); //is a dojotype=Select w.dataProvider.setData(data); }, mimetype: “text/json”, content: {facility:location, action:”jobcodes”} }); } Not work. Please help me…