Dojo 0.9 is the future of Dojo. It is backwards-incompatible with all previous Dojo releases. This guide outlines all public API changes between 0.4.x and 0.9. In some cases, functions or modules might have been removed. In these cases, alternative ways to achieve the same goal with 0.9 APIs is outlined.
This porting guide is a living thing. If you're a Dojo committer and you're working on a module, please get your changes listed here so that others can benefit from them. If you're porting an application and discover things that aren't yet documented (or documented well) in this guide, don't hesitate to ping me (alex at dojotoolkit.org) for editing permissions on the guide to help improve it. In the mean time, please file comments on the guide pages so we don't lose your discoveries and hard-won helpful hints to your fellow Dojo users.
One of the Dojo contributors wrote a very useful blog on this subject you may find helpful, as well: http://wolfram.kriesing.de/blog/index.php/2007/dojo-migration-04-to-09
dojo.* namespace is now djConfig.
The following changes have been made:
dj_currentContext and dojo.global() have been replaced with the property dojo.globaldojo.doc() has been replaced with the property dojo.docdj_undef has been removed without replacementdojo.findModule has been removed without public replacement. Private users may reference dojo._loadedModulesdojo.getModuleSymbols has been made private without replacment.dojo.raise() has been removed without replacement; use throw new Error() insteaddojo.debug(), dojo.debugShallow(), and dojo.debugDeep() have been replaced by the appropriate console.* methods.dojo.errorToString() has been removed without replacementdojo.evalObjPath has been replaced with dojo.getObjectdojo.parseObjPath has been replaced with dojo.getObjectdojo.exists(obj, name) syntax has been removed. Used dojo.exists(name, obj)dojo.evalProp() has been removed without replacementdojo.unimplemented() has been removed without replacementdj_eval() has been moved to dojo.eval()dojo.hostenv.* is being entirely removed. Configuration and internal functions that once lived there are either being removed wholesale or being moved up a level to the root dojo object. Look for environment-detection variables and methods there.dojo.render.* is being entirely removed. Configuration and internal functions that once lived there are either being removed wholesale or being moved up a level to the root dojo object.dojo.render.html.ie moved to the root: dojo.isIE. This property returns a version number rather than a boolean.dojo.kwCompoundRequire() has been moved to dojo.platformRequire()dojo.experimental() has been moved from a separate module to a built-in method. It is now always available to call.dojo.hostenv.getBaseScriptUri() has been removed in favor of dojo.dojoUrl("")dj_addNodeEvtHdlr() has been moved to dojo._handleNodeEvent()dojo.makeWidgets has been removed. All responsibility for load-time widget creation is the exclusive purview of Dijit.dojo.getXmlhttpObject has been made private. It now lives at dojo._xhrObjdjConfig attribute on the script tag which is used to include dojo.js. This new configuration mode is always available in browser environments. The djConfig.allowQueryConfig option has been removed.The following platform support files are no longer provided in 0.9:
hostenv_svg.jshostenv_adobesvg.jshostenv_jsc.jshostenv_dashboard.jshostenv_wsh.jsBrowser environments, Rhino, and Spidermonkey are still supported "out of the box" in 0.9 and the Apple Dashboard platform support may be re-instated if demand is sufficient.
The following configuration options have been removed or no longer affect system behavior:
djConfig.allowQueryConfigdjConfig.iePreventClobberdjConfig.ieClobberMinimaldjConfig.searchIdsdjConfig.parseWidgetsdjConfig.baseUrl:
djConfig.baseRelativePathdjConfig.baseScriptUridjConfig.libraryScriptUridojo.hostenv.getBaseScriptUri() and in it's place is the variable dojo.baseUrl.This chapter lists general information on changes to the widget subsystem, as well as a migration path for each widget in Dojo 0.4, where available.
The 0.9 release has a number of improvements over 0.4:
But, there are a number of Dojo 0.4 features that haven't made it into Dijit or Dojox yet. Some people may even want to defer upgrading until some more of these features are added. Some of the things that are missing (but we plan to port eventually):
Here are a few things that aren't missing but that I get questions on often:
By the way, here are some Dojo core features missing:
Commonly asked questions about migration:
Where is Widget.show()/hide() and the wipe/explode/fade toggle animation?
The goal of Dijit is to provide a set of basic widgets which support theming, accessibility, and globalization. The widgets and widget infrastructure have been moved into a separate subproject called "Dijit" and vastly streamlined and with a new directory structure.
Widget code is found at dijit.* now (compared to dojo.widget.* in 0.4). Widgets live in various points in the hierarchy, including dijit.*, dijit.form.*, dijit.layout.*, etc. The actual list of supported widgets differs from 0.4, and the function set and API choices have generally been simplified in favor of usability and quality. The parser has been redesigned and removes some significant performance bottlenecks from the previous release. Widgets and their style sheets are no longer loaded automatically, so the method of instantiating widgets has changed substantially.
To use markup in a page, you must require the Dojo parser along with any widgets referenced, and enable a page scan using the "parseOnLoad" setting:
<script type="text/javascript" src="../../dojo/dojo.js"
djConfig="parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dijit.form.Button");
dojo.require("dojo.parser");
</script>
References to widgets use the dojoType attribute on some HTML tag. The name must be fully qualified using the Javascript package, and references are case-sensitive. XHTML-style namespaces and Dojo-specific tags are no longer supported. These two styles of declaration in 0.4
<button dojoType="button">...
<dojo:button>...are replaced by
<button dojoType="dijit.form.Button">...
In place of dojo.widget.createWidget(), simply use the Javascript "new" constructor:
var button1 = new dijit.form.Button(params, srcNodeRef);
where srcNodeRef is a reference to an existing DOM node or id string.
Many widgets now have a startup() method that you must call after the widget is created and you have done addChild() for all of it's children
accordion = new dijit.layout.AccordionContainer({}, dojo.byId("accordionShell"));
accordion.addChild(new dijit.layout.ContentPane());
accordion.addChild(new dijit.layout.ContentPane());
accordion.addChild(new dijit.layout.ContentPane());
accordion.startup();
Dijit ships with a default theme called "Tundra". The widget implementations no longer bootstrap with their own CSS. The style sheets for Dijit must now be loaded by the developer in the HTML page. For example:
<style type="text/css"> @import "../dijit/themes/tundra/tundra.css"; </style>
And then on the <body> tag add class=tundra:
<body class="tundra">
Please see the manual for more details on theming, about using different themes or even multiple themes on the same page.
Notable changes since 0.9 beta:
* lists within dojoAttachPoint, dojoAttachEvent, waiRole, and waiState are now comma-separated (not separated by semi-colons)
* enable()/disable() → setDisabled(boolean)
* onValueChanged() → onChange() (called for value changes for most widgets but state changes for toggle widgets like checkbox)
* setSelected() → setChecked()
* dijit.util.manager.byNode() → dijit.byNode()
* dijit.util.manager.getAllWidgets() replaced by dijit.registry.forEach(), filter(), etc.
* Dialog::closeNode attribute deleted. Dialog now extends _FormMixin, which means that you need a dijit.form.Button type="submit" button to close the Dialog. Ideally all the controls in your form should be widgets, and then the execute() method of your form will get all the data from the widgets. See test_Dialog.html for an example.
* all custom widgets with children (and templates) must declare dojoAttachPoint=containerNode. It doesn't default to domNode anymore
This page contains information for people writing their own widgets. If you are just using the dijit widgets out of the box, you can skip this section.
dojo.defineWidget() has been replaced by plain dojo.declare()
Widget creation method call sequence:
Note that those functions' (postCreate, etc) call signatures have changed. No arguments are passed.
To get the source dom Node, just reference this.srcNodeRef
In 0.4 there were three main base classes (Widget, DomWidget, and HtmlWidget), but everyone used HtmlWidget so we can think of that as one class. 0.9 split up things by functionality, into:
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dijit._Container");
dojo.require("dijit.layout._LayoutWidget");
dojo.require("dijit.form._FormWidget");
| 0.4 | 0.9 | Comments |
|---|---|---|
| children | deleted | Mixin dijit._Container and call getChildren() |
| parent | deleted | Mixin dijit._Contained and call getParent() |
| extraArgs | deleted | declare all parameters to your widget as attributes in the widget |
| disabled | disabled | in _FormWidget |
| widgetId | id | |
| widgetType | declaredClass | |
| ns | deleted | No namespaces anymore; use full path to widget like dijit.form.Button |
| templateString, templatePath | Mix in dijit._Templated | |
| templateCssPath | deleted | Include CSS rules directly |
| toggle, toggleDuration | deleted | Use dojo functions (fadeIn, wipeIn) on widget.domNode directly. Some widgets like Dialog still support these attributes (or similar ones) but it's not builtin to every widget. |
| isContainer | deleted | No longer necessary; all widgets can be containers. |
| 0.4 | 0.9 | Comments |
|---|---|---|
| enable, disable | setDisabled | |
| onResized | layout | when layout is called size is in this._contentBox |
| create | constructor calls lifecycle code | |
| fillInTemplate | deleted | use postCreate() instead |
| postInitialize | deleted | use postCreate() instead |
| postCreate | when postCreate() is called children don't yet exist. If you need to access them, use startup() | |
| destroy | destroyRecursive | destroy() doesn't destroy child widgets |
| getChildrenOfType | deleted | use dojo.filter(this.getChildren(), function(child){...}) |
| addChild, removeChild | mix in dijit._Container | |
| isShowing, toggleShowing | deleted | Reference this.domNode directly |
| show, onShow, hide, onHide | deleted | Some widgets support these functions but not all widgets. Reference this.domNode directly if necessary. |
| resizeTo(w, h) | resize({w: 10, h: 20}) | Now you can just change height or width (each argument is optional) |
| resizeSoon | deleted | shouldn't be necessary; layout algorithms were changed |
Removed support for multiple renderers (svg & vml & a11y) for a single widget. If a widget wants to render differently on different platforms, there must be branching code inside the widget, or it needs to call a library that branches based on the browser type (like dojo.gfx or dojo.charting).
"this." is no longer used within ${} substitution notation. Just say ${foo} to access the foo attribute. dojoRoot,buildScriptBase,dojoModuleUrl are no longer supported, but any JavaScript properties on the widget's 'this' may be referenced with dotted notation.
The attributes dojoOn* are desupported (including dojoOnBuild); also can't use id attribute to affect a dojoAttachPoint.
dojoAttachEvent is case sensitive, so capitalization matters. You will probably have to change
dojoAttachEvent="onClick"to
dojoAttachEvent="onclick: onClick"(given that the event name is lowercase, and assuming that the method name is camel case)
Lists within dojoAttachPoint, dojoAttachEvent, waiRole, and waiState are now comma-separated (not separated by semi-colons)
By default widgets exist as islands, not knowing about their parent widget or children widgets. The exception is the destroyDescendants() function which will also delete all descendant widgets. Some widgets like Tree and SplitContainer know about their children, but those widgets will use the special mixins from Container.js
All custom widgets with children (and templates) must declare dojoAttachPoint=containerNode in the template. It doesn't default to domNode anymore.
Layout widgets mixin _LayoutWidget, and support a resize() method.
onResized() removed.
Many functions were removed from dojo core but added back into dijit. See HTML Utilities migration guide for details.
Also:
dojo.require("dijit.util.manager");
| 0.4 | 0.9 | Comments |
|---|---|---|
| dojo.widget.byId() | dijit.byId() | |
| dojo.widget.getWidgetsByNode() | dijit.registry.byNode() | |
| dojo.widget.getAllWidgets() | dijit.registry.forEach(func) | |
| dojo.widget.getWidgetsByType() | dijit.registry.byClass() | iterate over results using dijit.registry.byClass(...).forEach(func) |
| dojo.widget.getWidgetsByFilter | dijit.registry.filter(...) | iterate over results using dijit.registry.filter(...).forEach(func) |
The children of AccordionContainer must now be AccordionPane widgets only (see dijit.layout.AccordionPane) The label of each AccordionPane is specified by its title attribute, and the initial selected state is determined by the pane with selected="true". The contents of each AccordionPane may be any combination of widgets or HTML markup. There are still some bugs relating to rendering of scrollbars on hidden panes in Firefox 2.0.
| 0.4 | 0.9 | Comments |
|---|---|---|
| child.label | AccordionPane.title | Now specified on AccordionPane widget |
| 0.4 | 0.9 | Comments |
|---|---|---|
| onShow/onHide | deleted | Use onSelected instead |
Not ported to Dijit or Dojox. No immediate plans to port it.
This widget is useful to get an animated PNG on IE6, which is better than an animated GIF because it supports gradient transparency.
But it's not popular enough to be supported in Dijit. (Also not an issue for IE7.)
dojo.require("dijit.form.Button");
| 0.4 | 0.9 | Comments |
|---|---|---|
| caption | label | Users are encouraged to write content as innerHTML rather than an attribute. |
| iconClass | For buttons with icons, you should specify the icon in CSS and then include it in the button via iconClass attribute |
| 0.4 | 0.9 | Comments |
|---|---|---|
| enable/disable | setDisabled(boolean) | |
| setCaption | setLabel |
dojo.require("dijit.form.Button");
| 0.4 | 0.9 | Comments |
|---|---|---|
| caption | label | Users are encouraged to write content as innerHTML rather than an attribute. |
| iconClass | For buttons with icons, you should specify the icon in CSS and then include it in the button via iconClass attribute | |
| menuid | deletedMenus are embedded in the button, see example for details. | |
| toggle, toggleDuration | deletedControlled by dijit.util.popup |
| 0.4 | 0.9 | Comments |
|---|---|---|
| enable/disable | setDisabled(boolean) | |
| setCaption | setLabel |
The biggest change is that drop down menus are embedded in the button tag.
Old:...New:
EditCutCopyPaste
dojo.require("dijit.form.Button");
| 0.4 | 0.9 | Comments |
|---|---|---|
| caption | label | Users are encouraged to write content as innerHTML rather than an attribute. |
| iconClass | For buttons with icons, you should specify the icon in CSS and then include it in the button via iconClass attribute | |
| menuid | deletedMenus are embedded in the button, see example for details. | |
| toggle, toggleDuration | deletedControlled by dijit.util.popup |
| 0.4 | 0.9 | Comments |
|---|---|---|
| enable/disable | setDisabled(boolean) | |
| setCaption | setLabel |
The biggest change is that drop down menus are embedded in the button tag.
Old:...New:...
SaveSave to file
We aren't porting this to Dijit, but you can look at the noir theme for some examples of fancy looking buttons using the existing infrastructure.
From Tom: [SvgButton was a] proof of concept dealing with pure SVG environments. What happened is that during the course of my research to create the first iteration of the charting engine, I discovered that it is almost *never* that someone will work solely in an SVG environment, particularly in this day and age of browsers supporting mixed XML namespaces. It took a lot of convincing, but eventually we decided to change the original rendering structure of Dojo (from 0.4 to 0.9), and we were able to remove a lot of cruft that we'd had there trying to support those pure environments.
Charting widgets will be ported to dojox. Stay tuned.
Actual input fields are used for the checkbox and radio but themed version is displayed above the input in the z-order. User is actually interacting with the input field and look and feel is being updated to match. This provides the correct grouping behavior for radios because the grouping behavior is being handled by the browser.
dijit.form.CheckBox
dijit.form.CheckBox (form/CheckBox.js)
| Dojo 0.4 | Dojo 0.9 | Notes |
|---|---|---|
| Dojo 0.4 | Dojo 0.9 | Notes |
|---|---|---|
| setValue() | setChecked() | sets checkbox checked/unchecked state |
| setValue() | sets actual input value parameter; consistent with other form element APIs | |
| setDisabled() | inherited via _FormWidget to enable/disable input field |
Old:
New:
dijit.form.RadioButton
dijit.form.CheckBox (form/CheckBox.js)
| Dojo 0.4 | Dojo 0.9 | Notes |
|---|---|---|
| Dojo 0.4 | Dojo 0.9 | Notes |
|---|---|---|
| setValue() | setChecked() | sets radio checked state |
| setValue() | sets actual input value parameter; consistent with other form element APIs | |
| setDisabled() | inherited via _FormWidget to enable/disable input field |
Old:
Radio group #1:
New:
Radio group #1:
Not ported and no immediate plans to, but see dojox/gfx/demos/clock.html.
Reason: more of a fun app than anything 'useful' ... could be ported to dojox.widget without problem, but again, i believe it was svg-based ...
dijit.ColorPalette
dijit.ColorPalette (ColorPalette.js)
| Dojo 0.4 | Dojo 0.9 | Notes |
|---|---|---|
| onColorSelect | onChange | in addition, can use value attribute |
No plans to port this to Dijit or Dojox. You should use ColorPalette instead.
From Tom: [HslColorPicker was a] proof of concept dealing with pure SVG environments. What happened is that during the course of my research to create the first iteration of the charting engine, I discovered that it is almost *never* that someone will work solely in an SVG environment, particularly in this day and age of browsers supporting mixed XML namespaces. It took a lot of convincing, but eventually we decided to change the original rendering structure of Dojo (from 0.4 to 0.9), and we were able to remove a lot of cruft that we'd had there trying to support those pure environments.
dojo.require("dijit.form.ComboBox");
| 0.4 | 0.9 | Comments |
|---|---|---|
| dataProvider | store | Specify the jsId attribute of a dojo.data store from which to read your data |
| dataUrl | deleted | Use a dojo.data store to load data from a url |
| dropdownToggle | deleted | |
| fadeTime | deleted | |
| maxListLength | pageSize | List now has next and previous page buttons if the number of results can exceed the pageSize. |
| mode | deleted | |
| searchType | deleted | |
| selectedResult | deleted | Use getValue to get the value of the ComboBox |
| searchAttr | When using a store, the value of this field determines what field in the data contains the values to display in the menu. |
| 0.4 | 0.9 | Comments |
|---|---|---|
| setSelectedValue | setValue | "Hidden" value removed from 0.9 ComboBox |
| setAllValues | setValue | "Hidden" value removed from 0.9 ComboBox |
This section shows you how to migrate your 0.4 ComboBoxes to 0.9. To better understand the steps necessary to migrate a Web page using a ComboBox, you will take the widgets in the 0.4 test_ComboBox.html and rewrite them in a format suited to 0.9.
As with the 0.4 ComboBox, using inlined data with the 0.9 ComboBox is very much like using a native <select> tag. Listings 1 and 2 give the syntax for 0.4 ComboBox and 0.9 ComboBox respectively:
<select name="state" dojoType="combobox" autocomplete="false" onValueChanged="setVal1" > <option value="CA" selected>California</option> ... </select>
<select name="state1" dojoType="dijit.form.ComboBox" autocomplete="false" value="California" onChange="setVal1" > <option selected>California</option> ... </select>
Only the dojoType and onValueChanged→onChange actually changed here; name, and autocomplete still apply to ComboBox. 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.
0.9 uses the new unified dojo.data architecture. Consequently, the old dataProvider architecture for ComboBox is no longer part of the 0.9 ComboBox.
In 0.4, instead of creating your own dataProvider, you might have instead used one of the built in JavaScript array dataProviders, dojo.widget.basicComboBoxDataProvider or dojo.widget.incrementalComboBoxDataProvider. This section gives you a general idea of how to apply the 0.9 dojo.data architecture to the 0.9 ComboBox and also details the specific case of porting your ComboBox from dojo.widget.basicComboBoxDataProvider JavaScript arrays to the 0.9 dojo.data.ItemFileReadStore and its unique format.
In 0.9 you create a new tag in the HTML for the dojo.data store. Listing 3 shows a store that would load an item file called comboBoxData.js:
<div dojoType="dojo.data.ItemFileReadStore" jsId="stateStore" url="comboBoxData.js">
jsId is the name of the global variable that the store is assigned to. url is just like the dataUrl from the 0.4 ComboBox. Instead of using the url attribute, you can embed your data directly (as is common in traditional server-side programming) using the data attribute. Refer to the next section for details on the 0.9 ItemFileReadStore format.
This section is specific to the case that you wrote JavaScript arrays to your ComboBox using the default dateProviders.
Whether you had a static file of JavaScript arrays, a database Web proxy dedicated to returning JavaScript arrays, or a dynamic Web page that wrote the JavaScript arrays to the client on load, you need to migrate the format in which these applications wrote so that they will be compatible with the 0.9 ItemFileReadStore. Listings 4 and 5 visually demonstrate the differences in the 0.4 array syntax and the 0.9 item file syntax:
[ ["Alabama","AL"], ["Alaska","AK"], ["American Samoa","AS"], ["Arizona","AZ"], ... ]
{
identifier:"abbreviation",
items: [
{name:"Alabama", abbreviation:"AL"},
{name:"Alaska", abbreviation:"AK"},
{name:"American Samoa", abbreviation:"AS"},
{name:"Arizona", abbreviation:"AZ"},
...
]
}
Notice how the item format has changed. The data is encapsulated by an outer set of curly braces {}, and is further encapsulated in a named array called items. The data set has an identifier attribute whose value is the name of the attribute that distinguishes each item. In 0.9, each item is further encapsulated by {} instead of [], enabling you to name your attributes and write them in any order.
Now that you have created the appropriate dojo.data store, you can migrate the ComboBox's attributes. Compare the old ComboBox with its 0.9 equivalent in Listings 6 and 7:
<input dojoType="ComboBox" value="this should never be seen - it is replaced!" dataUrl="comboBoxData.js" style="width: 300px;" name="foo.bar" onValueChanged="setVal2" >
<div dojoType="dojo.data.ItemFileReadStore" jsId="stateStore" url="comboBoxData.js"> <input dojoType="dijit.form.ComboBox" store="stateStore" value="California" searchAttr="name" name="state2" onChange="setVal2" >
dojo.require("dijit.form.FilteringSelect");
0.9 introduced reverse lookup capabilities to setValue and setDisplayedValue in the Select API. If you have been changing the value of your Selects programmatically with setAllValues by keeping your own reverse lookup arrays, you should revisit your code and take advantage of the reverse lookup capability.
Concerning the UI, Select also handles invalid input differently. In 0.4 Select cleared the textbox and submit value on invalid input. Now the user gets a warning message, but the Select keeps textbox input as is and also keeps the last valid submit value. If the user selects the textbox and presses Escape on the keyboard, the textbox reverts to the last valid value, corresponding to the hidden value. This change guarantees that you will always get a valid submit value from your 0.9 FilteringSelects. Keep this UI change in mind as you migrate your applications.
Migrating a Web page with a 0.4 Select to 0.9 is very similar to migrating a ComboBox, with these differences:
| 0.4 | 0.9 | Comments |
|---|---|---|
| searchAttr | When using a store, the value of this field determines what field in the data contains the values to match user input against ("California"). | |
| labelAttr | Optional. When using a store, the value of this field determines what field in the data contains the values to display in the menu. Can be rich text ("<img
src='california.jpg'>") | |
| labelType | Parse labels as text or html. |
| 0.4 | 0.9 | Comments |
|---|---|---|
| getLabel | getDisplayedValue | Returns the text in the input box. |
| getValue | getValue | Returns the current form submit value. |
| setAllValues | setValue/setDisplayedValue | Reverse lookup happens automatically. |
| setLabel | setDisplayedValue | Sets the text in the input box ("California"). Does a reverse lookup on the form submit value automatically. |
| setValue | setValue | Sets the hidden value that the form submits ("CA"). Does a reverse lookup on the text automatically. |
This section shows you how to migrate your 0.4 Selects to 0.9. To better understand the steps necessary to migrate a Web page using a Select, you will take the widgets in the 0.4 test_Select.html and rewrite them in a format suited to 0.9.
Building a 0.9 FilteringSelect from inline <option> tags is almost identical to building a 0.9 ComboBox. Listings 8 and 9 show the differences:
<select dojoType="Select" name="state3" autocomplete="false" onValueChanged="setVal1" style="width: 300px;"> <option value="AL">Alabama</option> ... </select>
<select dojoType="dijit.form.FilteringSelect"
name="state3"
autocomplete="false"
onChange="setValue('value1', arguments[0]);" value="CA"
>
<option value="AL">Alabama</option>
...
</select>
As with 0.9 ComboBox, 0.9 FilteringSelect adds 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 textbox on load. If you want to change the value attribute programmatically, use dijit.byId("yourwidgetid").setValue("yourhiddenvalue").
Important: do not confuse setValue with the onChange setValue in Listing 9: that setValue refers to a global setValue in the 0.9 test_FilteringSelect.html, in line with the setVal1 in the 0.4 test, and is not part of the widget.
You will want to follow the steps for creating a dojo.data store in the markup and migrating your JSON data, mentioned in the ComboBox #2 section, before continuing.
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. Listing 10 gives an example from dijit/tests/form/comboBoxData.json:
{
identifier:"abbreviation",
items: [
{name:"Alabama", label:"<img width='97px' height='127px' src='images/Alabama.jpg'/>Alabama",abbreviation:"AL"},
...
Listing 10 demonstrates an identifer set to abbreviation. The identifer 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.
Important: unlike FilteringSelect, ComboBox does not have a hidden submit value, so ignores the identifier attribute.
Listing 11 and 12 show how to migrate a 0.4 Select with a dataUrl to a 0.9 FilteringSelect that takes advantage of the identifier attribute:
input dojoType="Select" value="this should never be seen - it is replaced!" dataUrl="comboBoxData.js" style="width: 300px;" name="state1" onValueChanged="setVal2" >
<div dojoType="dojo.data.ItemFileReadStore" jsId="stateStore" url="comboBoxData.js">
<input dojoType="dijit.form.FilteringSelect"
searchAttr="name"
name="state1"
autocomplete="true"
onChange="setValue('value2', arguments[0]);"
>
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.
dojo.require("dijit.layout.ContentPane");
The ContentPane in Dijit is a stripped version of the 0.4.
There is a Dojox ContentPane with more the more advanced features.
| 0.4 | 0.9 | Comments |
|---|---|---|
| label | title | For ContentPanes (or other widgets) that are children of TabContainer or StackContainer (nee PageContainer), use "title" to specify the title rather than "label" |
| cacheContent | preventCache | |
| parseContent | parseOnLoad | Create widgets within content |
| adjustPaths | deleted | Fix relative paths within content |
| handler | deleted | |
| executeScripts | deleted | But /* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */
.html4strict .imp {font-weight: bold; color: red;}
.html4strict .kw1 {color: #b1b100;}
.html4strict .kw2 {color: #000000; font-weight: bold;}
.html4strict .kw3 {color: #000066;}
.html4strict .coMULTI {color: #808080; font-style: italic;}
.html4strict .es0 {color: #000099; font-weight: bold;}
.html4strict .br0 {color: #66cc66;}
.html4strict .st0 {color: #ff0000;}
.html4strict .nu0 {color: #cc66cc;}
.html4strict .sc0 {color: #00bbdd;}
.html4strict .sc1 {color: #ddbb00;}
.html4strict .sc2 {color: #009900;}
<script type="dojo/method">...</script> available in dojo.parser are supported |
| scriptScope | deleted | |
| scriptSeparation | deleted | |
| bindArgs | deleted | |
| href | same | For the uncommon case when you have a ContentPane with an href that's *not* inside a TabContainer etc. you need to set preload=true. |
| 0.4 | 0.9 | Comments |
|---|---|---|
| setUrl(url) | setHref(url) | Get content in url |
| abort | cancel | Abort a download |
| setHandler(function) | deleted | |
| addOnLoad(function) | deleted | onLoad event still exists for setContent/setHref - while you cant call addOnLoad() you can connect to this event to achieve similiar goals |
| addOnUnload(function) | deleted | onUnLoad event still exists for setContent/setHref - while you cant call addUnOnload() you can connect to this event to achieve similiar goals |
| show | deleted | |
| hide | deleted | |
| loadContents | deleted | |
| splitAndFixPaths | deleted | |
| onExecError | deleted | |
| Inherited methods (the commonly used ones) | ||
| addChild | deleted | |
| removeChild | deleted | |
| onClose | deleted | |
| onShow | deleted | |
| onHide | deleted | |
| 0.4 | 0.9 | Comments |
|---|---|---|
| extractContent default true | extractContent default false | Grab content within ... throw away the rest. Prevents DOM fault when content includes tags that belongs to /* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .html4strict .imp {font-weight: bold; color: red;} .html4strict .kw1 {color: #b1b100;} .html4strict .kw2 {color: #000000; font-weight: bold;} .html4strict .kw3 {color: #000066;} .html4strict .coMULTI {color: #808080; font-style: italic;} .html4strict .es0 {color: #000099; font-weight: bold;} .html4strict .br0 {color: #66cc66;} .html4strict .st0 {color: #ff0000;} .html4strict .nu0 {color: #cc66cc;} .html4strict .sc0 {color: #00bbdd;} .html4strict .sc1 {color: #ddbb00;} .html4strict .sc2 {color: #009900;} <head> |
Create a ContentPane dynamically: in 0.4
var cpane = dojo.widget.createWidget({properties...});
dojo.body().appendChild(cpane.domNode);
in 0.9
var cpane = new dijit.layout.ContentPane({properties...}, dojo.doc.createElement('div'));
dojo.body().appendChild(cpane.domNode);
cpane.startup(); // start loading href if href is set
NOTE! You must include a sourcenode when creating a ContentPane, the auto create element feature in 0.4 is deletedTabs sample, creation from markup: in 0.4 /* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #b1b100;} .geshifilter .kw2 {color: #000000; font-weight: bold;} .geshifilter .kw3 {color: #000066;} .geshifilter .coMULTI {color: #808080; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #ff0000;} .geshifilter .nu0 {color: #cc66cc;} .geshifilter .sc0 {color: #00bbdd;} .geshifilter .sc1 {color: #ddbb00;} .geshifilter .sc2 {color: #009900;}
Adding a ContentPane to a TabContainer
// create a ContentPane
var newChild = new dijit.layout.ContentPane({
href:'remotepage',
title:'newChild',
refreshOnShow:true
}, dojo.doc.createElement('div'));
// find my tabContainer and add our new ContentPane
dijit.byId('myTabContainer').addChild(newChild);
// find parent Container and subscribe to selectChild event
// without it refreshOnShow and href load wont work.
newChild.startup();
NOTE! you must call .startup() after you have addChild() it to your parent
Connecting a callback to a widget within content
Although scripts handling have been removed from ContentPane, you can still attach a callback to some widgets within your content because the dojo.parser in 0.9 supports makes it possible.
Imagine this content:
/* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */
.geshifilter {font-family: monospace;}
.geshifilter .imp {font-weight: bold; color: red;}
.geshifilter .kw1 {color: #b1b100;}
.geshifilter .kw2 {color: #000000; font-weight: bold;}
.geshifilter .kw3 {color: #000066;}
.geshifilter .coMULTI {color: #808080; font-style: italic;}
.geshifilter .es0 {color: #000099; font-weight: bold;}
.geshifilter .br0 {color: #66cc66;}
.geshifilter .st0 {color: #ff0000;}
.geshifilter .nu0 {color: #cc66cc;}
.geshifilter .sc0 {color: #00bbdd;}
.geshifilter .sc1 {color: #ddbb00;}
.geshifilter .sc2 {color: #009900;}
dojo.require("dijit.layout.LinkPane");
dijit.layout.LinkPane has no LinkPane specific changes, just the one introduced in the baseclass ContentPane.
LinkPane is usefull when you want a degradable page, that still lets the user read the content even if JS is turned of.
DropDownDatePicker has been replaced by dijit.form.DateTextBox. The API and functionality have been simplified, and the widget is now fully accessible, globalized, and skinnable. DateTextBox is a subclass of dijit.form.ValidationTextbox and behaves like other subclasses of that widget. It is intended to be used in forms. The date is now always submitted to the server using a profile of ISO8601 -- see dojo.date.stamp for details.
| Dojo 0.4 | Dojo 0.9 | Notes |
|---|---|---|
| iconURL | deleted | presentation of dropdown is customizable via CSS theming instead |
| formatLength | deleted | use constraints.formatLength instead |
| displayFormat | use constraints.datePattern + selector | |
| saveFormat | deleted | No longer a choice. See dojo.date.stamp for specifications |
| value | value | now contains a Javascript Date object only |
| displayWeeks, adjustWeeks | deleted | no longer customizable |
| startDate/endDate | deleted | use constraints.min/max instead |
| weekStartsOn | deleted | must use locale default |
| staticDisplay | deleted | no longer an option |
| Dojo 0.4 | Dojo 0.9 | Notes |
|---|---|---|
| getDate() | use value attribute instead | |
| getValue() | use serialize instead | |
| setValue()/setDate() | use Date object for argument only | |
| onValueChanged(), onInputChange() | use onChange instead -- see dijit.form._FormWidget |
Besides the changes made to ValidationTextbox, the biggest change to the DateTextBox API is the universal value format. Listings 1 and 2 demonstrate the new 0.9 date syntax:
<input type="text" name="date1" class="medium" value="12/30/05" lang="en-us" dojoType="DateTextBox" required="true" invalidMessage="Invalid date. Use M/d/yy format." />
<input id="q14b" type="text" name="date1" value="2005-12-30" dojoType="dijit.form.DateTextBox" lang="en-us" required="true" promptMessage="mm/dd/yyyy" invalidMessage="Invalid date. Use mm/dd/yyyy format." />
DatePicker has been replaced by dijit._Calendar but this widget is not meant to be used standalone because it does not provide accessibility to the visually or mobility impaired individual. Using the widget standalone is not currently supported because of this restriction. To provide access for all users, it is recommended that dijit.form.DateTextBox be used for input of dates.
DebugConsole won't be ported to Dojo 0.9. Instead just set isDebug: true in your djConfig parameters and use console.log to print debugging messages, which will go to the Firebug console on FF, or a custom <div> on your page on other browsers.
<script type="text/javascript" src="../../dojo/dojo.js"
djConfig="parseOnLoad: true, isDebug: true"></script>
...
console.log("hello world");
More Information:
http://dojotoolkit.org/book/dojo-book-0-9/part-4-meta-dojo/debugging-fac...dojo.require("dijit.Dialog");
Please think about using TooltipDialog rather than Dialog. Dialog is only/mainly meant to be used for messages that popup out of the blue, like "lost server connection". TooltipDialog is meant for dialogs triggered by pushing a link/button, such as the Editor's "Add URL" dialog.
| 0.4 | 0.9 | Comments |
|---|---|---|
| closeNode | deleted | Dialog now extends _FormMixin, which means that you need a dijit.form.Button type="submit" button to close the Dialog. Ideally all the controls in your form should be widgets, and then the execute() method of your form will get all the data from the widgets. See test_Dialog.html for an example. |
| focusElement | deleted | on dialog close, focus is returned to the element that had focus before the dialog opened, so you don't need this parameter anymore |
| bgColor | deleted | controlled via CSS now |
| bgOpacity | deleted | controlled via CSS now |
| followScroll | deleted | this is always true now; there's no parameter to adjust it. (although since the dialog is now draggable, the meaning is a bit different.) |
| closeOnBackgroundClick | deleted | you have to close the dialog by pressing the specified button, or via the X icon in the upper right. |
| toggle, toggleDuration | deleted | predecided with the widget (always fades in) |
| title | this is a newly required parameter since the dialog now has a title section (like the old floating panes) |
| 0.4 | 0.9 | Comments |
|---|---|---|
| setBackgroundColor | deleted | controlled via CSS |
| setBackgroundOpacity | deleted | controlled via CSS |
New:Editor2, Editor2Toolbar, RichText
TODO: Alex, write porting doc
Editor2 is being stripped down and rewritten as the Dijit Editor. Editor2 was a nice piece of code but the way it was written made it *very* difficult to incorporate and modify. Current code is in a beta state.
FilteringTable
FilteringTable will be replaced in Dijit 1.0 by a Table widget that reads it's data from a dojo.data Store, doing lazy loading, etc.
In the meantime, you can get the same functionality by following the DemoDataTable example in dojox/data/demos/demo_DataDemoTable.html
From Tom:
FilteringTable:
Will be replaced with a Grid widget. Parts of Filtering have already made its way into other parts of Dojo, particularly in Dojo Data (they lifted the sorting code almost verbatum, IIRC).The problem with Filtering is that it anticipated many of the things that are being more fully fleshed out in other parts of the Toolkit, such as data binding mechanisms, data stores, and more. What it really was was a widget I'd written for other projects which we slammed into Dojo because so many people were screaming for a grid. I never really wanted to add it, but there you have it.
We do recognize that a Grid is ridiculously important. I was on deck to write it but I simply don't have the time, and it's better if others who are more involved with the Dijit project take it on (I don't have anything to do with this project other than advice about rendering and layout).
FisheyeList
Looking for a volunteer to port this widget to Dojox.
FloatingPane, TaskBar
FloatingPane and TaskBar won't be ported to Dijit.
Dijit.Dialog provides a modal draggable closable dialog (like an alert or confirm box), that auto-sizes to the data it holds. However, there is no taskbar, no minimize/maximize/restore functionality, and no resize functionality. These features won't be ported because Dijit isn't interested in implementing a windowing system inside a browser.
There is a dojox.layout.FloatingPane widget which is a draggable TitlePane (non-modal). Though it doesn't support resizing yet, it has basic themeable minimize/maximize/docking controls. (and is in an experimental state)
Form, Repeater
Planning to port a slimmed down version of Form and Repeater to Dijit 1.0, but project hasn't been started yet.
GoogleMap, YahooMap
There was talk of porting these widgets to a dojox.map project but it hasn't been done yet.
From Tom:
I wrote both of these widgets as proof of concept in about a day. I have a plan in the works for a much more extensive geo project in DojoX (probably called DojoX Geo) that will incorporate the functionality of both of these widgets and more (probably do one on the new MapQuest API, maybe Live Earth as well). In fact, as soon as I come up for air after the rewrite of DojoX Charting, I'm going to start soliciting wants and needs for that project--so if you have any ideas, feel free to post them in the DojoX Discussion forum.
InlineEditBox
InlineEditBox Migration Guide
InlineEditBox → dijit.form.InlineEditBox
dojo.require("dijit.form.InlineEditBox");In 0.4, InlineEditBox had two modes of operation: text input, and text area. If you wanted more complex behaviors (for example, an InlineEditDateTextbox) you had to extend InlineEditBox with the DateTextbox behavior.
The 0.9 InlineEditBox is a completely rewritten widget. In fact, the 0.9 InlineEditBox is better described as a widget wrapper, which takes a child widget declared in markup and makes it inline-editable. The examples in this guide will show you how you can add inline-edit behavior to any widget using the 0.9 InlineEditBox and HTML.
Name changes
Properties 0.4 0.9 Comments mode deleted Add a child widget (like TextBox or TextArea) in the HTML instead. renderAsHTML If yout widget returns rich text, InlineEditBox will display rich text with renderAsHTML set to true. autoSave If true, hides the save button. Defaults to true. If you want to retain the save and cancel buttons in your application, you will have to add this attribute and set it to false. Examples
InlineEditBox, basic text input
InlineEditBox now supports basic text input through the TextBox widget. By simply adding a Textbox inside the InlineEditBox HTML tag, you add inline-editing to the Textbox widget. Listings 1 and 2 compare the 0.4 mode syntax to the 0.9 widget syntax:
Listing 1. 0.4 InlineEditBox syntax
<h1 id="editable" dojoType="inlineEditBox">Edit me - I trigger the callbacks onSave,onCancel,onChange</h1>Listing 2. 0.9 InlineEditBox syntax
<span id="editable" style="font-size:larger;" dojoType="dijit.form.InlineEditBox" onChange="myHandler(this.id,arguments[0])"> <input dojoType="dijit.form.Textbox" value="Edit me - I trigger the onChange callback"> </span>The outermost span in Listing 2 is the InlineEditbox. The inner input tag is the Textbox widget. When a user loads the page, they see the text "Edit me - I trigger the onChange callback". If the user clicks the text, a Textbox widget containing the text "Edit me - I trigger the onChange callback" appears. When the user changes the value and clicks away, the Textbox disappears and the Textbox's contents appear inline.
InlineEditBox, rich text TextArea
InlineEditBox now supports the textarea mode through the TextArea widget. By simply adding a TextArea inside the InlineEditBox HTML tag, you add inline-editing to the TextArea widget. Furthermore, by adding renderHTML=true, users can enter HTML into the TextArea and have it appear inline as rich text. Listings 3 and 4 compare the 0.4 mode syntax to the 0.9 widget syntax:
Listing 3. 0.4 InlineEditBox syntax
<p id="areaEditable" dojoType="inlineEditBox" mode="textarea"> I'm one big paragraph. Go ahead and edit me. I dare you. The quick brown fox jumped over the lazy dog. Blah blah blah blah blah blah blah ... </p>Listing 4. 0.9 InlineEditBox syntax
<span id="areaEditable" dojoType="dijit.form.InlineEditBox" renderHTML="true" autoSave="false"> <textarea dojoType="dijit.form.Textarea">I'm one big paragraph. Go ahead and <i>edit</i> me. <b>I dare you.</b> The quick brown fox jumped over the lazy dog. Blah blah blah blah blah blah blah ...</textarea> </span>The outermost span in Listing 4 is the InlineEditbox. The inner textarea tag is the TextArea widget. When a user loads the page, they see the paragraph of rich text. If the user clicks the text, a TextArea widget containing the paragraph in plain text form appears. When the user changes the value and clicks away, the TextArea disappears and the TextArea's contents appear inline.
InlineEditBox, DateTextbox
InlineEditBox can make any arbitrary widget that has a text value, or has the methods get/setDisplayedValue, inline. DateTextbox is an example of such a widget. Listing 5 shows a DateTextbox made inline in HTML:
Listing 5. 0.9 InlineEdtBox with a DateTextbox
<p id="backgroundArea" dojoType="dijit.form.InlineEditBox" > <input name="date" value="2005-12-30" dojoType="dijit.form.DateTextbox" constraints={datePattern:'MM/dd/yy'} lang="en-us" required="true" promptMessage="mm/dd/yy" invalidMessage="Invalid date. Use mm/dd/yy format."> </p >By using the 0.9 InlineEditBox API, you can greatly reduce the size of your applications that used to duplicate the code of other widgets in order to make them inline.
LayoutContainer
LayoutContainer → dijit.layout.LayoutContainer
dojo.require("dijit.layout.LayoutContainer");In particular, note that now the layoutAlign=client child must be the last element in the list. Example:
Old code
top...bottomNew code
topbottom...Name changes
Properties 0.4 0.9 Comments layoutChildPriority deleted control priority by the order of the children Example
Old code:
top barleft...New code:
(note how children were rearranged to put left child first so it gets "priority")lefttop bar...Menu2, MenuBar2
PopupMenu2 → dijit.Menu
dojo.require("dijit.Menu");Name changes
Properties 0.4 0.9 Comments eventNaming deleted Menu doesn't publish events when you click a menu item anymore; only the onClick handler on each MenuItem is supported subMenuOverlap deleted Submenu is always next to the menu, never overlapping. (The overlapping thing was a nice touch though; but if we add it back it will probably be specified via CSS.)
Methods 0.4 0.9 Comments open _openMyself Users are meant to open menus via dijit.popup.open() MenuItem2 → dijit.MenuItem
dojo.require("dijit.Menu");Name changes
Properties 0.4 0.9 Comments caption label accelKey deleted accelerator keys were never supported so no reason to have a parameter iconSrc iconClass icons paths are specified in CSS now; see example below for details subMenuId deleted the sub menu is a child of the a PopupMenuItem; see example below for details. eventNaming deleted Menu doesn't publish events when you click a menu item anymore; only the onClick handler on each MenuItem is supported disabledClass, highlightClass deleted class names are hardcoded now; see theming documentation for info on customizing themes
Methods 0.4 0.9 Comments enable, disabled setDisabled(/*boolean*/) MenuSeparator2 → dijit.MenuSeparator
dojo.require("dijit.Menu");MenuBar2, MenuBarItem2
These haven't been implemented yet, although you might be able to get by with using Toolbar and buttons instead of a MenuBar. See the Toolbar tests for examples.
Examples
The biggest is that menus are structured hierarchically rather than using links by id.
Old code:
New code:
CSS:
.myIcon { background-image: url(...) 0 -16 0 0; width: 16px; height: 16px; }HTML:
MonthlyCalendar
There are no plans to port MonthlyCalendar to Dijit. However, the new dijit._Calendar template is flexible enough to allow for content for each day cell in the table and can probably be subclassed to provide similar behavior.
From Tom:
Dustin wrote it as part of an effort to be able to create and manipulate iCal data within a client--and frankly I think this will end up as part of a more extensive DojoX project.
PageContainer
dojo.widget.PageContainer → dijit.layout.StackContainer
PageContainer was renamed to StackContainer to reinforce the concept of overlapping items in a container. It is now the basis for the AccordionContainer and TabContainer widgets. Also renamed was PageController, now StackController.
Properties 0.4 0.9 Comments child.label child.title ProgressBar
ProgressBar → dijit.ProgressBar
The operation of the ProgressBar is now driven primarily by the update() method and by CSS. The number of accessor methods and overall complexity of this widget has been reduced. There is no more polling feature. The polling feature in 0.4 assumed a very specific messaging scheme and added to the footprint of the widget. Instead, for indeterminate states, an animated graphic is used, driven by user code, allowing for messaging not only by server "push" but also by consuming other data or connecting to client-side events..
Properties 0.4 0.9 Comments progressValue progress May be a percentage or a number maxProgressValue maximum width, height deleted use CSS instead *Class deleted CSS class names are fixed now hasText deleted can be achieved by setting 'display' properties on CSS classes dijitProgressBarFullLabel and dijitProgressBarEmpty Label to 'none' isVertical deleted showOnlyIntegers places you can now specify the number of decimal places, or override the report() method to customize the text display dataSource, pollInterval, duration indeterminate animation feature removed. See summary above.
Methods 0.4 0.9 Comments get/setProgressValue update pass progress property get/setMaxProgressValue update pass maximum property get/setProgressPercentValue update pass progress property with "%" at end of string setDataSource, setPollInterval, start, startAnimation, stopAnimation indeterminate + update see summary render deleted rendering is now an implementation detail, called during initialization and during updates RadioGroup
No plans to port this to Dijit, or to Dojox, AFAIK.
Can get similar functionality from dijit.layout.StackContainer.
From Tom:
This widget is the sole result of me being very frustrated at the way the older TabPane widget was written, and was written by Jesse Kuhnert under my direction as a proof of concept to show some of the other widget developers exactly what we meant by a very light-weight widget. Because of that lineage, we decided to drop it. Maybe it will show up in DojoX, I don't know. It should be very easy to port.
It's called RadioGroup because that's really what it is: it takes an HTML list and adds radio button functionality to it. It could be used for that or for tabs--or for anything else that might need a single selection out of a group of things. But it's really aimed more at the JQuery/Prototype-like crowd--people who are looking for very lightweight things they can layer on top of straight up HTML.
ResizableTextArea
ResizableTextArea Migration Guide
ResizableTextArea → dijit.form.TextArea
dojo.require("dijit.form.TextArea");Examples
TextArea did not change much in 0.9, except that now the text area sizes automatically rather than the user manually setting the size. Listings 1 and 2 demonstrate the changes.
Listing 1. 0.4 ResizableTextArea syntax
<textarea dojoType="resizabletextarea" rows="15" cols="40">Listing 2. 0.9 TextArea syntax
<div dojoType="dijit.form.Textarea" rows="15" cols="40">ResizeHandle
ResizeHandle (and resizable panes in general) are not supported in Dijit.
the Module ResizeHandle appears in dojox.layout.ResizeHandle, though is still experimental after port.
Changes Include:
- targetElmId [0.4] → targetId [0.9] - id of a node you wish to resize with handle
- targetContainer [new] - over-ride targetId and use a dom node ref passed in this var
- resizeAxis - [new] one of x, y, or xy [default] - limit resizing to a single axis or both
Show
dojo.widget.Show → dojox.presentation
dojox.presentation is in an 'experimental' state. It has been rewritten [as opposed to porting], so the API is almost entirely different. [and it hardly works, atm ... ] progress is being made.
/* GeSHi (C) 2004 - 2007 Nigel McNie (http://qbnz.com/highlighter) */ .geshifilter {font-family: monospace;} .geshifilter .imp {font-weight: bold; color: red;} .geshifilter .kw1 {color: #000066; font-weight: bold;} .geshifilter .kw2 {color: #003366; font-weight: bold;} .geshifilter .kw3 {color: #000066;} .geshifilter .co1 {color: #009900; font-style: italic;} .geshifilter .coMULTI {color: #009900; font-style: italic;} .geshifilter .es0 {color: #000099; font-weight: bold;} .geshifilter .br0 {color: #66cc66;} .geshifilter .st0 {color: #3366CC;} .geshifilter .nu0 {color: #CC0000;} .geshifilter .me1 {color: #006600;} .geshifilter .re0 {color: #0066FF;}
dojo.require("dojox.presentation");Structure:
[ and so on ]no toggling just yes, but the part/action relationship will be similar to the on/as relationship in dojo.widget.Show
TODO: dojox.presentation.Tooltip - will show a tooltip for a presentation.Part on hover
presentation.Slides are extensions on dijit.layout.ContentPane, so the normal href="" and other basic methods are there as well.
Parts and Actions are children of Slides, and are limited to affecting nodes within their Slide, Though can be grouped and [TODO] chained for action->multiple parts or multiple actions->single part
please refer to the tests and API documentation for details on all available methods and current structure.
Unfortunately, there is no ETA on a stable Presentation class.
Slider
Slider Migration Guide
SliderHorizontal → dijit.form.HorizontalSlider
dojo.require("dijit.form.Slider");The 0.9 Slider code is significantly more lightweight than the 0.4 Slider. The old
backgroundStyle, handleStyleetc. attributes have been absorbed into the 0.9 CSS themes. Also, in 0.4 you had to use a background image to create ruler marks on the side of the slider. In 0.9 final, you use dijit.form.HorizontalRule to create your ruler marks. If you want to change the style of a slider, make your own CSS theme.Name changes
Properties 0.4 0.9 Comments activeDrag intermediateChanges In 0.9 final buttonStyle deleted backgroundSize deleted backgroundStyle deleted backgroundSrc deleted Use dijit.form.HorizontalRulein 0.9 final to create ruler marks.flip deleted handleStyle deleted initialValue value progressBackgroundSrc deleted snapValues discreteValues Defaults to Infinity(continuous values) instead of ""
Methods 0.4 0.9 Comments onValueChanged onChange Examples
Horizontal slider, value appears in a textbox
One way you could show the user the value of your Slider is to create a textbox that the Slider fills when the user moves the Slider. Listings 1 and 2 show a Slider that fills in a simple textbox called
horizontalSliderValue.Listing 1. 0.4 SliderHorizontal syntax
<div id="horizontalSlider" dojoType="SliderHorizontal" initialValue="5" minimum="-10" maximum="10" snapValues="11" activeDrag="true" onValueChanged="dojo.byId('horizontalSliderValue').value = arguments[0];" buttonStyle="top:1px;" backgroundStyle="padding:8px 4px 8px 4px;border:1px solid red;" backgroundSize="width:100px;height:5px;" backgroundSrc="src/widget/templates/images/blank.gif" progressBackgroundSrc="src/widget/templates/images/slider-bg.gif" handleStyle="top:0px;width:13px;height:18px;" handleSrc="src/widget/templates/images/slider.gif" ></div>Listing 2. 0.9 HorizontalSlider syntax
<div id="horizontalSlider" dojoType="dijit.form.HorizontalSlider" value="5" minimum="-10" maximum="10" discreteValues="11" intermediateChanges="true" onChange="dojo.byId('horizontalSliderValue').value = arguments[0];" handleSrc="dijit/themes/tundra/images/preciseSliderThumb.png" ></div>You can point the handleSrc image to wherever you want. If you want to use the default handle image, just remove the handleSrc.
Horizontal slider, ruler marks values
In 0.4 you had to create a background image to create rule marks and labels. In 0.9 you can use the HorizintalRule and HorizontalRuleLabels to create your ruler marks programmatically, reducing the amount of data being transferred over the wire. Listings 3 and 4 compare two horizontal sliders with ruler marks. Listing 3 from 0.4 uses a background image and Listing 4 from 0.9 final uses HorizontalRule.
Listing 3. 0.4 SliderHorizontal syntax
<div id="horizontalSlider" dojoType="SliderHorizontal" initialValue="5" minimum="-10" maximum="10" snapValues="11" activeDrag="true" buttonStyle="top:1px;" backgroundStyle="padding:8px 4px 8px 4px;border:1px solid red;" backgroundSize="width:100px;height:5px;" backgroundSrc="src/widget/templates/images/blank.gif" progressBackgroundSrc="src/widget/templates/images/slider-bg.gif" handleStyle="top:0px;width:13px;height:18px;" handleSrc="src/widget/templates/images/slider.gif" ></div>Listing 4. 0.9 final HorizontalSlider syntax
<div id="horizontalSlider" dojoType="dijit.form.HorizontalSlider" value="5" minimum="-10" maximum="10" discreteValues="11" intermediateChanges="true" showButtons="true"> <div dojoType="dijit.form.HorizontalRuleLabels" container="topDecoration" labels=" ,20%,40%,60%,80%, " style="height:1.2em;font-size:75%;color:gray;"></div> <div dojoType="dijit.form.HorizontalRule" container="topDecoration" count=11 style="height:5px;"></div> <div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count=5 style="height:5px;"></div> <div dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" labels="0%,50%,100%" style="height:1em;font-size:75%;color:gray;"></div> </div>SliderVertical → dijit.form.VerticalSlider
dojo.require("dijit.form.Slider");The 0.9 VerticalSlider API is identical to the 0.9 HorizontalSlider API. Also, in 0.9 final you can use the VerticalRule class to create vertical ruler marks.
Slider (2D)
The 0.4 2D Slider has been discontinued in 0.9.
SlideShow
dojo.widget.SlideShow → dojox.presentation.SlideShow
SlideShow is no part of the dojox.presentation class. It is an extended port of the 0.4.x SlideShow code, with many aesthetic improvements, and functionality. Though it is in an experimental state, it is relatively stable. There are some minor known bugs in IE and Safari, but no show-stoppers.
All old methods and parameters are the same.
NEW parameters include:
(refer to API for full rundown)
- navIconPlay/navIconPause/navIconDirUp/navIconDirDown - url's for images used for basic navigation
- toggleAnimation - basic transition code for images, one of "fade" or "scale" atm
- showDialog - true/false for a non-customizable [x of N] overlay
- useNav - true/false for a prevent visual navigation
- hideNavAfterEvent - true/false - hides nav after a
- navDur - Integer - how long the nav takes to toggle in ms
- direction - one of 'forwards' or 'backwards'
- isPausable
- navOpacity/navOpacityMin - overall opacity of nav images overlay settings
NEW public methods:
- removeImgUrl - pop the last element from the slideshow
- shuffleImgUrls - randomized slideshow image order
- toggleNav/showNav/hideNav
- setGallery(jsonData) - replaces the current loaded gallery with a new list of images
- addImgUrl - push a url into the playlist
- toggleNav / hideNav / showNav - obvious?
- toggleDirection / togglePaused
SpanSelect
No plans to port SpanSelect to Dijit, but you will be able to get a similar effect by embedding a FilteringSelect widget (or Select widget, when that is written) into an InlineEditBox with autoSave=true.
Spinner
Spinner Migration Guide
IntegerSpinner → dijit.form.NumberSpinner
dojo.require("dijit.form.NumberSpinner");In 0.9, IntegerSpinner became NumberSpinner, a NumberTextbox with up and down buttons. All of the changes going from 0.4 IntegerTextbox to 0.9 NumberTextbox apply to IntegerSpinner.
Name changes
Properties 0.4 0.9 Comments delta smallDelta Amount spinner changes while clicking and holding the up and down buttons bigDelta Amount spinner changes while holding the page up and page down keys Examples
initial value=1000, delta=10, min=9 max=1550
Migrating a 0.4 IntegerSpinner is a two step process because you have to migrate the IntegerTextbox code to the 0.9 NumberTextbox syntax in additon to migrating the spinner code. Listings 1 and 2 demonstrate the differences between a 0.4 IntegerSpinner and the equivalent 0.9 NumberSpinner:
Listing 1. 0.4 IntegerSpinner syntax
<input dojoType="IntegerSpinner" value="+1,000" delta="10" min="9" max="1550" signed="always" separator="," maxlength="20" widgetId="integertextbox1">Listing 2. 0.9 NumberSpinner syntax
<input dojoType="dijit.form.NumberSpinner" value="1000" smallDelta="10" constraints="{min:9,max:1550,places:0}" maxlength="20" id="integerspinner2">
deltabecamesmallDelta.min, max, signed, separator,and the number of decimalplacescollapsed into the constraints object.RealNumberSpinner → dijit.form.NumberSpinner
dojo.require("dijit.form.NumberSpinner");See the IntegerSpinner migration guide. Because 0.9 NumberSpinner supports all real numbers implicitly, there is no need for a separate RealNumberSpinner.
TimeSpinner
TimeSpinner will not be in 0.9. However, 0.9 will contain a TimeTextbox, possibly with a graphical dropdown.
SplitContainer
dojo.widget.SplitContainer → dijit.layout.SplitContainer
TabContainer
TabContainer → dijit.layout.TabContainer
dojo.require("dijit.layout.TabContainer");
Properties 0.4 0.9 Comments labelPosition tabPosition selectedChild deleted Use the "selected" attribute on the child instead Changes for children of TabContainer:
Properties 0.4 0.9 Comments label title TextBox widgets (IntegerTextBox, CurrencyTextBox, etc.)
TextBox Migration Guide
CurrencyTextBox → dijit.form.CurrencyTextBox
dojo.require("dijit.form.CurrencyTextBox");Name changes
Properties 0.4 0.9 Comments fractional moved Now a property of the ValidationTextBox constraints object currency ISO4217 currency code for this CurrencyTextBox; "USD" Examples
CurrencyTextBox class, Attributes: {fractional: true}. Enter dollars and cents.
0.9 moved the
fractionalattribute inside the constraints object, and added an additional attribute,currency, to control what currency format this textbox accepts from the user. Thevaluebecame a generic floating point number. Listings 1 and 2 demonstrate these differences:Listing 1. 0.4 CurrencyTextBox syntax
<input type="text" name="income" class="medium" value="$54,775.53" dojoType="CurrencyTextBox" trim="true" required="true" fractional = "true" invalidMessage="Invalid amount. Include dollar sign, commas, and cents. Example: $12,000.00" />Listing 2. 0.9 CurrencyTextBox syntax
<input id="q08" type="text" name="income1" value="54775.53" dojoType="dijit.form.CurrencyTextBox" required="true" constraints={fractional:true} currency="USD" invalidMessage="Invalid amount. Include dollar sign, commas, and cents. Cents are mandatory." />The 0.9 version of this textbox accepts only the US dollar format from the user. Unlike 0.4 though, the
valueattribute is a floating point number. This means that you can easily build CurrencyTextBoxes in 0.9 for a wide range of currencies without having to set a different value for each currency format.fractionalis still set to true, but it is set inside the constraints object instead of on the widget.
DateTextBox → dijit.form.DateTextBox
See DropDownDatePicker
IntegerTextBox → dijit.form.NumberTextBox
dojo.require("dijit.form.NumberTextBox");IntegerTextBox expanded to a NumberTextBox in 0.9. The constraints object enables you to specify how many decimal places (0 for integers) the user's input should go with the
placesattribute.Name changes
Properties 0.4 0.9 Comments signed deleted signed is implicitly defined by min and max in the constraints Examples
IntegerTextBox class, Attributes: {trim: true, required: true, signed: true classPrefix: "myValidateColor"}, Enter feet above sea level with a sign.
signedis implicit to theminandmaxattributes. Listings 3 and 4 show how to set the signed flag, as well as the min and max ranges, using the constraints object:Listing 3. 0.4 IntegerTextBox syntax
<input type="text" name="elevation" class="medium" value="3000" dojoType="IntegerTextBox" trim="true" classPrefix="myValidateColor" required="true" signed="true" invalidMessage="Invalid elevation. Be sure to use a plus or minus sign." />Listing 4. 0.9 NumberTextBox syntax
<input id="q05" type="text" dojoType="dijit.form.NumberTextBox" name= "elevation" value= 3000 constraints= {min:-20000,max:20000,places:0} promptMessage= "Enter a value between -20000 and +20000" required= "true" invalidMessage= "Invalid elevation." />
InternetTextBoxes → dijit.form.ValidationTextBox
dojo.require("dijit.form.ValidationTextBox");InternetTextBoxes are no longer supported. Refer to ValidationTextBox and use your favorite regular expression for these widgets.
RealNumberTextBox → dijit.form.NumberTextBox
dojo.require("dijit.form.NumberTextBox");Like IntegerTextBox, RealNumberTextBox also became a NumberTextBox in 0.9. The
placesattribute of the constraints object enables you to specify how many decimal places the user's input should go. If you do not specifyplaces, then the textbox accepts all real numbers.
RegexpTextBox → dijit.form.ValidationTextBox
dojo.require("dijit.form.ValidationTextBox");0.9 added regexp support to ValidationTextBox. See ValidationTextBox for more details.
Name changes
Properties 0.4 0.9 Comments regexp regExp The start and end qualifers, ^ and $, are implicit in 0.9. Examples
RegexpTextBox class, Attributes: {required: true, trim: true}
Listing 5. 0.4 RegexpTextBox syntax
<input type="text" name="phone" class="medium" value="someTestString" dojoType="RegexpTextBox" regexp="^[\w]+$" required="true" invalidMessage="Invalid Non-Space Text." />Listing 6. 0.9 ValidationTextBox syntax
<input id="q22" type="text" name="phone" class="medium" value="someTestString" dojoType="dijit.form.ValidationTextBox" regExp="[\w]+" required="true" invalidMessage="Invalid Non-Space Text.">As you can see, a 0.9 ValidationTextBox is almost identical to a 0.4 RegexpTextBox. The start and ending qualifiers of the regular expression, ^ and $, are implicit in 0.9, so they are not present in the 0.9 example.
TextBox → dijit.form.TextBox
dojo.require("dijit.form.TextBox");Name changes
Properties 0.4 0.9 Comments ucfirst propercase digit deleted Use NumberTextBox to make a TextBox that processes numbers. Examples
TextBox class, Attributes: {trim: true, ucFirst: true, class: 'medium'}, First letter of each word is upper case.
Listing 7. 0.4 TextBox syntax
<input id="q1" type="text" name="firstname" value="testing testing" class="medium" dojoType="TextBox" trim="true" ucfirst="true" />Listing 8. 0.9 TextBox syntax
<input id="q01" type="text" name="firstname" value="testing testing" tabIndex=2 dojoType="dijit.form.TextBox" trim="true" propercase="true" />As you can see,
ucfirstbecame propercase, and the other attributes remain the same.
TimeTextBox
TimeTextBox is forthcoming.
ValidationTextBox → dijit.form.ValidationTextBox
dojo.require("dijit.form.ValidationTextBox");Name changes
Properties 0.4 0.9 Comments classPrefix deleted constraints Object that tells ValidationTextBox what input is allowed. invalidClass deleted maxLength deleted missingClass deleted missingMessage promptMessage promptMessage only appears in an empty field rangeClass deleted rangeMessage deleted regExp Port from 0.4 RegexpTextBox. Static regular expression for validating. regExpGen Instead of validating with a static regular expression, you can create a function that returns a regular expression. Examples
ValidationTextBox class, Attributes: {lowercase: true, required: true}. Displays a prompt message if field is missing.
0.9 streamlined many of the attributes used in 0.4 ValidationTextBoxes. Listings 9 and 10 show the version differences in a basic Occupation ValidationTextBox:
Listing 9. 0.4 ValidationTextBox syntax
<input type="text" name="occupation" class="medium" dojoType="ValidationTextBox" lowercase="true" required="true" missingMessage="* The occupation is required." />Listing 10. 0.9 ValidationTextBox syntax
<input id="q04" type="text" name="occupation" dojoType="dijit.form.ValidationTextBox" lowercase="true" required="true" promptMessage="Enter an occupation" />
lowercaseandrequiredstill apply to ValidationTextBox. However, when the user clears the textbox, thepromptMessagedisplays instead of themissingMessage. This is a significant change from 0.4 to 0.9: thepromptMessagein 0.9 only displays in an empty ValidationTextBox.ValidationTextBox, static regular expression
New to 0.9 ValidaitonTextBox is regular expression support. Listing 11 demonstrates a ValidationTextBox that only accepts a 5 digit zip code.
Listing 11. 0.9 ValidationTextBox with a static regular expression
<input type="text" name="zip" value="00000" dojoType="dijit.form.ValidationTextBox" regExp="\d{5}" required="true" invalidMessage="Invalid zip code.">ValidationTextBox, regular expression generator
0.9 ValidationTextBox also supports functions that generate regular expressions. Having a generating function enables you to write much more dynamic Web applications. ValidationTextBox passes its constraints object to the generating function. Listing 12 demonstrates a dynamic ValidationTextBox that only accepts a 5 digit zip code after 5:00PM, and only accepts a county name before then.
Listing 12. 0.9 ValidationTextBox with a static regular expression
<script> function after5(constraints){ var date=new Date(); if(date.getHours()>=17){ return "\\d{5}"; }else return "\\D+"; } </script> <input type="text" name="zip" value="00000" dojoType="dijit.form.ValidationTextBox" regExpGen="after5" required="true" invalidMessage="Zip codes after 5, county name before then.">
Us*TextBox → dijit.form.ValidationTextBox
dojo.require("dijit.form.ValidationTextBox");Us*TextBoxes are no longer supported. Refer to ValidationTextBox and use your favorite regular expression for these widgets.
TimePicker, DropDownTimePicker
DropDownTimePicker → dijit.form.TimeTextBox
DropDownTimePicker has been replaced by dijit.form.TimeTextBox and parallels dijit.form.DateTextBox. See DateTextBox for more details.
Parameter changes/deletions
Dojo 0.4 Dojo 0.9 Notes containerToggle deleted no longer customizable containerToggleDuration deleted no longer customizable formatLength use constraints.formatLength instead displayFormat use constraints.datePattern + selector saveFormat deleted No longer a choice. See dojo.date.stamp for specifications value value now contains a Javascript Date object only Method changes/deletions
Dojo 0.4 Dojo 0.9 Notes getTime() getValue() onValueChanged(), onInputChange() use onChange instead -- see dijit.form._FormWidget Examples
TimeTextBox class, Attributes: {lang: "en-us", required: true, trim: true}. Works for leap years
The TimeTextBox API is identical to the DateTextBox API. Listings 1 and 2 demonstrate the new 0.9 TimeTextBox syntax:
Listing 1. 0.4 DropDownTimePicker syntax
<input dojoType="dropdowntimepicker" lang="en-us" value="12:00" containertoggle="wipe" containerToggleDuration="300">Listing 2. 0.9 TimeTextBox syntax
<input dojoType="dijit.form.TimeTextBox" lang="en-us" value="T12:00:00" constraints="{formatLength:'short'}" />
TimePicker
TimePicker has been replaced by dijit.form._TimePicker but this widget is not meant to be used standalone because it does not provide accessibility to the visually or mobility impaired individual. Using the widget standalone is not currently supported because of this restriction. To provide access for all users, it is recommended that dijit.form.TimeTextBox be used for input of times.
TitlePane
TitlePane → dijit.TitlePane
dojo.require("dijit.Titlepane");Name changes
Properties 0.4 0.9 Comments label title labelNodeClass, containerNodeClass deleted Name hardcoded. Adjust CSS by setting class of widget and then making CSS patterns like .myClass .dijitTitlePaneContent { ... }
Methods 0.4 0.9 Comments setLabel setTitle Toaster
dojo.widget.Toaster is now available at dojox.widget.Toaster and seems to work mostly the same [except using dojo.publish/subscribe now]
Toolbar
dijit.Toolbar replaces dojo.widget.Toolbar as well as the Editor2Toolbar widget specific to dojo.widget.Editor2. It is used by the new dijit.Editor widget and can also be used as a generic toolbar. Toolbar is basically a container for buttons. The buttons really control all of the logic, and handlers are wired up directly to the buttons. Those buttons now have their own logic for efficient loading of their images as background images, and the buttons may optionally be DropDownButton instances spawning widgets like ColorPalette or TooltipDialog as dropdown.
Tooltip
Tooltip → dijit.Tooltip
Tooltip's API is largely unchanged from 0.4, but note that Tooltip is only meant for informational text; anything that requires user interaction (clicking etc.) should be in a TooltipDialog.
dojo.require("dijit.Tooltip");Name changes
Properties 0.4 0.9 Comments toggle, toggleDuration deleted controlled by MasterTooltip class but not easily changed by the user? href deleted caption label using this attribute is discouraged; use inline HTML instead Examples
Old code:
New code:
tooltip on a linkTree, TreeV3
TreeV3 → dijit.Tree
Background
Tree has essentially been rewritten for Dijit. It only supports a small subset of the functionality in the original TreeV3 code. Specifically, drag&drop, multi-selection, node editing, etc. are not supported.
Consider the Dijit Tree as halfway written; eventually I plan to add DnD, and the ability to change the tree's contents dynamically, and maybe the ability to remember what nodes were open on a certain tree... unclear exactly what I want Dijit to support.
The full tree functionality from 0.4 should be ported to DojoX is anyone is willing to volunteer to support it. Unfortunately the person supporting TreeV3 in 0.4 can't work on it for the forseeable future.
Dijit Tree Specifics
Tree is now driven by a dojo.data source, which (if written well) will do lazy loading of the tree data as it's needed. The store can also inline the data (see the various dojo.data tests for examples of this).
Example
(note: planning to remove labelAttr and just use store's getLabel() function)
Wizard
Wizard won't be ported to Dijit. It mayl be ported to Dojox, though we need a volunteer.
dojox.presentation base could work as foundation for new wizard, as it is an extended version of StackContainer [formerly dojo.widget.PageContainer]
dojo.json
dojo.json has been refactored into part of the Dojo Core package. Here is a list of the changes.
New Function Old Function dojo.toJson() dojo.json.serialize() dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint, /*String?*/ _indentStr){ // summary: // Create a JSON serialization of an object. // Note that this doesn't check for infinite recursion, so don't do that! // // it: // an object to be serialized. Objects may define their own // serialization via a special "__json__" or "json" function // property. If a specialized serializer has been defined, it will // be used as a fallback. // // prettyPrint: // if true, we indent objects and arrays to make the output prettier. // The variable dojo.toJsonIndentStr is used as the indent string // -- to use something other than the default (tab), // change that variable before calling dojo.toJson(). // // _inde