Part 1 in this article series introduces you to many of the new widgets and modules in Dojo Mobile 1.8 that you can use for your mobile web applications. Dojo Mobile 1.8 also includes many new enhancements to existing Dojo Mobile features. This article gives you a detailed look at those enhancements.
If the editable property of a list widget
(EdgeToEdgeList or RoundRectList) is true,
users can reorder items in the list. To enter the edit mode, get a
reference to the list widget and call the
startEdit() method. Then, for each item, a
delete icon appears on the left, and a move-handle icon appears on the
right.
Users can drag the move handle to move an item, as shown in the middle screen shot in Figure 1:
Figure 1. Editable list widget
Autoscrolling is not implemented yet. The list doesn't scroll while you drag an item.
When the user touches the delete icon, the list widget does nothing except
publish the /dojox/mobile/deleteListItem topic.
The application must subscribe to the topic for the icon touch to perform
some action, such as showing a delete button for confirmation (as shown in
the right-hand screen shot in Figure 1) or deleting the selected item. See
tests/test_RoundRectList-editable.html in the Dojo Mobile nightly build
tests for a complete example (see Resources later
in this article for a link).
Listing 1 shows how to instantiate an editable RoundRectList in markup:
Listing 1. Example of an editable RoundRectList
<ul data-dojo-type="dojox.mobile.RoundRectList"
data-dojo-props='editable:true'>
<li data-dojo-type="dojox.mobile.ListItem">
...
</ul>
|
Instead of using the EdgeToEdgeCategory widget, you can specify
header:true for ListItem to create category
headers, as shown in Listing 2:
Listing 2. Example of category header
<ul data-dojo-type="dojox.mobile.EdgeToEdgeList"> <li data-dojo-type="dojox.mobile.ListItem">Item 1</li> <li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='header:true'>Category</li> <li data-dojo-type="dojox.mobile.ListItem">Item 2</li> <li data-dojo-type="dojox.mobile.ListItem">Item 3</li> </ul> |
Listing 2 implements the category header shown in Figure 2:
Figure 2. Category header
This capability is useful especially when you feed data to the list widget
through a datastore. Listing 3 shows an
example of JavaScript Object Notation (JSON) data that contains items with
header:true:
Listing 3. JSON data that contains category headers
[
{ label: "Category 1", header: true },
{ label: "Wi-Fi", icon: "i-icon-1.png", moveTo: "wifi" },
{ label: "Brightness & Wallpaper", icon: "i-icon-2.png", moveTo: "bright" },
{ label: "Picture Frame", icon: "i-icon-3.png", moveTo: "picture" },
{ label: "General", icon: "i-icon-4.png", moveTo: "general", "selected": "true" },
{ label: "Mail, Contacts, Calendars", icon: "i-icon-5.png", moveTo: "wifi" },
{ label: "Safari", icon: "i-icon-6.png", moveTo: "bright" },
{ label: "iPod", icon: "i-icon-7.png", moveTo: "picture" },
{ label: "Category 2", header: true },
{ label: "Video", icon: "i-icon-8.png", moveTo: "general" },
{ label: "Photos", icon: "i-icon-9.png", moveTo: "wifi" },
{ label: "Store", icon: "i-icon-10.png", moveTo: "bright" }
];
|
Listing 3 implements the list shown in Figure 3:
Figure 3. List with category headers
As you just saw, you can create a categorized list such as Figure 3 from flat-structured data such as Listing 3. With EdgeToEdgeStoreList or RoundRectStoreList, you can also use hierarchical data, as shown in Listing 4:
Listing 4. Hierarchical JSON data
[
{ label: "Category 1", header: true,
children: [
{ label: "Wi-Fi", icon: "i-icon-1.png", moveTo: "wifi" },
{ label: "Brightness & Wallpaper", icon: "i-icon-2.png", moveTo: "bright" },
{ label: "Picture Frame", icon: "i-icon-3.png", moveTo: "picture" },
{ label: "General", icon: "i-icon-4.png", moveTo: "general", "selected": "true" },
{ label: "Mail, Contacts, Calendars", icon: "i-icon-5.png", moveTo: "wifi" },
{ label: "Safari", icon: "i-icon-6.png", moveTo: "bright" },
{ label: "iPod", icon: "i-icon-7.png", moveTo: "picture" }
]
},
{ label: "Category 2", header: true,
children: [
{ label: "Video", icon: "i-icon-8.png", moveTo: "general" },
{ label: "Photos", icon: "i-icon-9.png", moveTo: "wifi" },
{ label: "Store", icon: "i-icon-10.png", moveTo: "bright" }
]
}
];
|
Note that the resulting ListItem widget structure is flat, like the one generated by Listing 3, even when the data structure is hierarchical.
By default, properties in JSON data are directly mixed into ListItem when
you feed the data to the list widget through a datastore. The
itemMap property enables you to customize the
mapping between JSON properties and ListItem properties. For example,
Listing 5 shows some custom JSON
data:
Listing 5. Custom JSON data
[
{ text: "Apple", profile_image_url: "i-icon-1.png"},
{ text: "Banana", profile_image_url: "i-icon-2.png"},
...
];
|
In Listing 6,
itemMap maps text
and profile_image_url from the custom JSON in
Listing 5 to ListItem's
label and icon
properties, respectively:
Listing 6. Example usage of
itemMap
<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList"
data-dojo-props='store:store, itemMap:{text:"label", profile_image_url:"icon"}'></ul>
|
If ListItem has child nodes that include a
layout attribute with a value of
left, center, or
right, those child nodes are aligned
accordingly. Listing 7 shows an example
of a ListItem layout with child nodes that use all three of those
layout attribute values:
Listing 7. Example ListItem layout
<ul data-dojo-type="dojox.mobile.RoundRectList">
<li data-dojo-type="dojox.mobile.ListItem">
<div layout="left">Left Node</div>
</li>
<li data-dojo-type="dojox.mobile.ListItem">
<div layout="center">Center Node</div>
</li>
<li data-dojo-type="dojox.mobile.ListItem">
<div layout="right">Right Node</div>
</li>
</ul>
|
Listing 7 implements the list layout shown in Figure 4:
Figure 4. List items with left, center, and right alignment
Figure 5 shows ListItem's default uncheck mark (which is blank) and default checkmark icon:
Figure 5. ListItem's default uncheck and check marks
Now you can change the checkmark icon to the image of your choosing through
the checkClass property. You can also specify
an icon for the the uncheck mark via the
uncheckClass property, as shown in Listing 8:
Listing 8. Example uncheck and check buttons on ListItem
<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='select:"multiple"'>
<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='
checkClass:"mblDomButtonSilverCircleGreenButton",
uncheckClass:"mblDomButtonSilverCircleGrayButton"'>
Check Button
</li>
</ul>
|
Listing 8 implements the uncheck and check buttons shown in Figure 6:
Figure 6. Custom icons for check and uncheck marks
Each IconItem in IconContainer can have a badge. Listing 9 shows a declarative example:
Listing 9. Example of IconItem with a badge
<ul data-dojo-type="dojox.mobile.IconContainer">
<li data-dojo-type="dojox.mobile.IconItem"
data-dojo-props='label:"app1", icon:"icon-1.png", badge:"55"'>...</li>
</ul>
|
Listing 9 sets the badge shown in Figure 7:
Figure 7. IconItem with a badge
Of course, you can use the set() method to set a
badge programmatically.
If the editable property of the IconContainer
widget is true, as shown in Listing 10, users can reorder icons by
dragging them, and users can remove an icon by touching the X in the icon's
upper-left corner:
Listing 10. Instantiating an editable IconContainer
<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='editable:true'> <li data-dojo-type="dojox.mobile.IconItem" ... |
To enter the edit mode, get a reference to the list widget and call the
startEdit() method. Then, for each item, a
delete icon appears on the upper left, and the icon starts shaking. You
can also enter the edit mode via a long press (tap and hold) on one of the
icons.
Figure 8 shows an IconContainer in the edit mode:
Figure 8. IconContainer in the edit mode (shaking)
If you specify lazy:true at startup time, as
shown in Listing 11, ContentPane does
not load external content specified with the
href property:
Listing 11. Loading the content lazily
function loadContent(){
registry.byId("pane1").load();
}
....
<div data-dojo-type="dojox.mobile.ContentPane" id="pane1"
data-dojo-props='href:"content.html", lazy:true'></div>
|
You can load the content any time by calling the
load() method.
ContentPane has the ability to execute scripts, which can either be inline or refer to external files, as shown in Listing 12:
Listing 12. Sample content that includes scripts
<script>
alert("hello");
</script>
<script src="foo.js"></script>
<div dojoType="dojox.mobile.RoundRect" shadow="true">
Everything looks good
</div>
|
If you specify executeScripts:false, ContentPane
does not execute any scripts.
ContentPane has been refactored, and its implementation has been moved to
_ContentPaneMixin to make it reusable.
(ContentPane.js is now an empty class that
inherits from _ContentPaneMixin.) You might
want to create your own custom container widget that has the same
capability as ContentPane by inheriting from
_ContentPaneMixin. You can also add
ContentPane's capability to an existing widget without creating a subclass
by using the data-dojo-mixin property. For
example, as shown in Listing 13, you
can add ContentPane's ability to load external content, specified with the
href parameter, to the View widget:
Listing 13. Adding ContentPane's capability to View
<div data-dojo-type="dojox.mobile.View"
data-dojo-mixins="dojox.mobile._ContentPaneMixin"
data-dojo-props='href:"content.html"'></div>
|
Each TabBarButton in TabBar can have a badge. Listing 14 shows a declarative example:
Listing 14. Example of TabBarButton with a badge
<ul data-dojo-type="dojox.mobile.TabBar">
<li data-dojo-type="dojox.mobile.TabBarButton"
data-dojo-props='badge:"55",...'>Featured</li>
...
</ul>
|
Listing 14 implements the badge shown in Figure 9:
Figure 9. TabBarButton with a badge
Of course, you can use the set() method to set a
badge programmatically.
Two bar types, tabBar and segmentedControl, have been available for the TabBar widget up until now. Figure 10 shows the tabBar type:
Figure 10. TabBar - tabBar
Figure 11 shows the segmentedControl type:
Figure 11. TabBar - segmentedControl
Four new bar types — standardTab, slimTab, flatTab, and tallTab
— were added in Dojo Mobile 1.8. Among these bar types,
standardTab, slimTab, and flatTab are closable. If the
closable property is
true, the user can close (destroy) a tab by
clicking the X icon on the tab.
The standardTab type, shown in Figure 12, looks just like tabs for a tabbed panel. You might want to create a tabbed panel with this type of TabBar.
Figure 12. TabBar - standardTab
The slimTab type, shown in Figure 13, is a space-saving type of TabBar. You can use it for applications for smaller-screen devices such as smartphones.
Figure 13. TabBar - slimTab
The flatTab type, shown in Figure 14, has no borders, no background colors, and no selected colors by default. It can be displayed through the application's background color or background image.
Figure 14. TabBar - flatTab
In your user applications, you might want to customize the flatTab styles. For example, you can specify styles for selected and unselected items, as shown in Listing 15:
Listing 15. Customizing flatBar
.mblTabBarFlatTab .mblTabBarButton {
... styles for flatTab items here ...
}
.mblTabBarFlatTab .mblTabBarButtonSelected {
... styles for selected items here ...
}
|
The tallTab type, shown in Figure 15, arranges a tab's icon and its label vertically. This style is typically seen on Android devices.
Figure 15. TabBar - tallTab
You can change FixedSplitter's split direction (from horizontal to vertical
or vice versa) dynamically using the setter for the
orientation property, as shown in Listing 16:
Listing 16. Setter for FixedSplitter orientation
var splitter = registry.byId("splitter1");
splitter.set("orientation", "H"); // split horizontally
splitter.set("orientation", "V"); // split vertically
|
For example, you can change the split direction dynamically according to the orientation of the device screen, as illustrated in Figure 16:
Figure 16. Changing the orientation
Through the variablePane property, you can
specify the index of a pane that fills the remaining space, as shown in
Listing 17:
Listing 17. variablePane example
<div data-dojo-type="dojox.mobile.FixedSplitter"
data-dojo-props='variablePane:0'>
<div data-dojo-type="dojox.mobile.Pane">pane 0</div>
<div data-dojo-type="dojox.mobile.Pane">pane 1</div>
<div data-dojo-type="dojox.mobile.Pane">pane 2</div>
</div>
|
Figure 17 shows variable-height panes at indexes of 0, 1, and 2, respectively:
Figure 17. Specifying variable height pane
If variablePane's value is -1, the last child
pane fills the remaining space.
ToolBarButton can contain an arrow or an icon as shown in Listing 18:
Listing 18. ToolBarButton examples
<div data-dojo-type="dojox.mobile.Heading">
<span data-dojo-type="dojox.mobile.ToolBarButton"
data-dojo-props='arrow:"left"'>Arrow</span>
<span data-dojo-type="dojox.mobile.ToolBarButton"
data-dojo-props='arrow:"right"'>Arrow</span>
<span data-dojo-type="dojox.mobile.ToolBarButton"
data-dojo-props='icon:"tab-icon-33w.png"'>Image</span>
</div>
|
Listing 18 implements the ToolBarButton shown in Figure 18:
Figure 18. Screenshot of a ToolBarButton containing arrows and an icon
You can specify the size of ProgressIndicator in pixels through the
size property, as shown in Listing 19:
Listing 19. Customizing the size of ProgressIndicator
<div data-dojo-type="dojox.mobile.ProgressIndicator"
data-dojo-props='startSpinning:true, size:80'></div>
|
This widget is a square, so the size property
sets both its width and height to the value you specify. Listing 19 implements the ProgressIndicator
shown in Figure 19:
Figure 19. Screenshot of a ProgressIndicator enlarged to 80 pixels
Two predefined color variations — the default and
mblProgWhite— are available for
ProgressIndicator, as shown in Figure 20:
Figure 20. Predefined ProgressIndicator colors
You can also fully customize the colors of ProgressIndicator, as shown in Listing 20:
Listing 20. Fully customizing the color
<div data-dojo-type="dojox.mobile.ProgressIndicator" startSpinning="true"
colors="['#E60012','#F39800','#FFF100','#8FC31F','#009944','#009E96',
'#00A0E9','#0068B7','#1D2088','#920783','#E4007F','#E5004F']"></div>
|
Listing 20 implements the colorful ProgressIndicator shown in Figure 21:
Figure 21. ProgressIndicator with custom colors
By default, ProgressIndicator is absolute-positioned and center-aligned. If
you specify center:false, the position becomes
relative and center-align is not applied, so it behaves like an ordinary
div node.
ProgressIndicator on other widgets
To place a ProgressIndicator on a Heading or ListItem widget, you don't
need to create an ProgressIndicator instance and place manually. Instead,
set the busy property for Heading or ListItem
to true.
Listing 21 places a ProgressIndicator on a Heading:
Listing 21. ProgressIndicator on a Heading widget (declarative example)
<div data-dojo-type="dojox.mobile.Heading"
data-dojo-props='busy:true'>Loading...</div>
|
Figure 22 shows the result of Listing 21:
Figure 22. Heading widget with ProgressIndicator
Listing 22 places a ProgressIndicator on a ListItem:
Listing 22. ProgressIndicator on a ListItem widget (programmatic example)
registry.byId("item1").set("busy", true);
....
<li data-dojo-type="dojox.mobile.ListItem" id="item1"
data-dojo-props='icon:"mblDomButtonBlueBall", moveTo:"#", variableHeight:true'>
<div class="textBox">
<div class="loading1">Loading More Items...</div>
<div class="loading2">more than 45 items</div>
</div>
</li>
|
Figure 23 shows the result of Listing 22:
Figure 23. ListItem widget with ProgressIndicator
deviceTheme is a convenient utility module that automatically loads appropriate theme CSS files according to the detected user agent of the browser. However, you need to be careful when you use this utility. It programmatically loads CSS files when the user application starts up. Therefore, the CSS files might not be loaded before initialization code runs — depending on factors such as browser, loader mode, widgets being used, and user application. Some applications might work regardless of this issue, and others might not. This problem can occur if you use deviceTheme in the way shown in Listing 23:
Listing 23. Problematic usage of deviceTheme
<script>
require([
"dojox/mobile",
"dojox/mobile/deviceTheme",
....
]);
</script>
|
In Dojo Mobile 1.7, a possible workaround was to require deviceTheme from a
separate <script> block, as shown in
Listing 24:
Listing 24. Possible workaround in 1.7
<script src="dojo.js"></script>
<script>
dojo.require("dojox.mobile.deviceTheme");
</script>
<script>
dojo.require("dojox.mobile");
....
|
In Dojo Mobile 1.8, another option was introduced. The deviceTheme can be
loaded prior to dojo.js if you use the
<script> tag as shown in Listing 25:
Listing 25. Another workaround in 1.8
<script src="dojox/mobile/deviceTheme.js" data-dojo-config="mblThemeFiles:['base','Button']"></script> <script src="dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script> |
This way you can assume that the theme CSS files are loaded before
initialization code starts to execute. Note, however, that you cannot
build deviceTheme.js into a layer file if you
take this approach.
dojox.mobile.parser is a very small, pure subset
of dojo.parser. It has no functionality that
dojo.parser doesn't have. In Dojo Mobile 1.8, a
few small features were added to
dojox.mobile.parser, all of them based on
dojo.parser features.
If a widget has the stopParser flag, the parser
stops parsing its child widgets. So far the
dojox.mobile widgets do not use this feature,
but some others, such as dojox.mvc, might need
it.
The new data-dojo-type syntax, which uses a
slash delimiter (for example,
data-dojo-type="dojox/mobile/Button") is
supported.
You can dynamically apply mixin modules to a widget to augment its features
without creating a subclass. For example, unlike
dojox.mobile.ContentPane, View and SimpleDialog
cannot load external content. However, if you mix
_ContentPaneMixin into them, they can have the
same capability as dojox.mobile.ContentPane
— that is, they can load contents specified with the
href property. Listing 26 shows an example:
Listing 26. Example of
data-dojo-mixins<div id="dlg1" data-dojo-type="dojox.mobile.SimpleDialog" data-dojo-mixins="dojox.mobile._ContentPaneMixin" data-dojo-props='href:"dialog-data.html"'></div> |
Format for specifying multiple attribute values
dojox.mobile.parser no longer accepts array-type
attributes (for example,
labels="['A','B','C','D','E']"), because
dojo.parser doesn't accept them. Instead, you
can specify them as labels="A,B,C,D,E", which
is the format dojo.parser accepts.
In previous Dojo Mobile versions,
dojox.mobile.parser was unable to override
widget methods correctly. This problem has been fixed in Dojo Mobile 1.8,
and now you can override widget methods declaratively, as shown in the
example in Listing 27:
Listing 27. Overriding the
onClick method
<script type="text/javascript">
function myClick(e){
alert("Hello!");
}
</script>
<ul data-dojo-type="dojox.mobile.RoundRectList">
<li data-dojo-type="dojox.mobile.ListItem"
data-dojo-props='moveTo:"bar", onClick:myClick'>
Slide
</li>
</ul>
|
View navigation history management
The view navigation history management feature — also called the
bookmarkable feature — enables the user to bookmark
the current view and navigate between views with the browser's back and
forward buttons. This feature has been enhanced in Dojo Mobile 1.8, and
now it can manage the state of multiple views. You enable the feature
simply by requiring dojox/mobile/bookmarkable,
as shown in Listing 28:
Listing 28. Enabling the bookmarkable feature
<script>
require([
"dojox/mobile",
"dojox/mobile/bookmarkable",
....
]);
</script>
|
Usage is the same as that in Dojo Mobile 1.7 or earlier.
If you add a hash symbol (#) to a destination ID, as shown in Listing 29, and perform a view transition to
that destination, the hash in the browser URL will be updated with the ID.
Users can then bookmark the current view for later use or return to the
previous view with the browser's back button.
Listing 29. Example usage of the bookmarkable feature
<div id="home" data-dojo-type="dojox.mobile.View">
<ul data-dojo-type="dojox.mobile.RoundRectList">
<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#page1"'>
Go to page 1
</li>
<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#page2"'>
Go to page 2
</li>
</ul>
</div>
|
The new bookmarkable feature can manage the state of more-complex
applications that consist of nested or split views. In such cases, the
fragment ID, which keeps track of the view visibility state, is a
comma-separated list of the visible views (for example,
#view1,view4,mainView).
Another new enhancement is that if you set
mblForceBookmarkable:true to
djConfig or
data-dojo-config, all the view transitions are
stored in the browser history, whether the value of
moveTo has the #
prefix or not. In this case, you can omit the #
prefix, as shown in Listing 30:
Listing 30. Example usage of
mblForceBookmarkable
<script src=".../dojo.js" data-dojo-config="..., mblForceBookmarkable:true"></script>
<script>
require([
"dojox/mobile",
"dojox/mobile/bookmarkable",
....
]);
</script>
....
<div id="home" data-dojo-type="dojox.mobile.View">
<ul data-dojo-type="dojox.mobile.RoundRectList">
<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"page1"'>
Go to page 1
</li>
<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"page2"'>
Go to page 2
</li>
</ul>
</div>
|
In this article and in Part 1, you've seen what's new in Dojo Mobile 1.8 widgets and modules. This article showed you new enhancements to existing Dojo Mobile features. Through examples, you've learned that those enhancements enable you to build powerful mobile applications with less effort. Part 3 explores the newly restructured Dojo Mobile data handlers.
Learn
- "What's new in Dojo Mobile 1.8" (developerWorks, Nov 2012): Don't
miss the other articles in this series.
- "Develop lightweight mobile web applications with Dojo Mobile"
(developerWorks, Dec 2011): Yoshiroh shows how to optimize the footprint
and performance of your applications built with Dojo Mobile.
- Dojo Mobile: Learn
more about Dojo Mobile features.
- Dojo Mobile documentation: Consult the Dojo Mobile Reference
Guide and API documentation.
-
Dojo Mobile
tutorials: Take advantage of these Dojo Toolkit 1.8
tutorials.
- Dojo Mobile 1.8 nightly build tests: See how Dojo Mobile 1.8
widgets work by trying out the nightly build tests.
- Dojo Mobile on developerWorks: Learn more about Dojo Mobile from
these developerWorks articles.
- Dojo Mobile Showcase: Use the showcase's slick UI to explore
loads of sample widgets.
- ToDo application: Play with a sample app that demonstrates
dojox/app, dojox/mobile, and dojox/mvc.
- Nightly
demos: Search the latest Dojo demos for more mobile demos (folder
names starts with mobile).
- Mobile development
resources on developerWorks: Find how-to articles, evaluation
code, and expert perspectives on a range of topics for mobile developers.
Get products and technologies
- Dojo 1.8.x: Download the
latest Dojo Toolkit version.

Yoshiroh Kamiyama is an Advisory Software Engineer at Yamato Software Lab (YSL), IBM Japan. He works on WebSphere Feature Pack for Web 2.0 and Mobile, and previously worked on several development projects including Mobile Mashup, Lotus iNotes, and Rational Portfolio Manager, many of which used the Dojo Toolkit. He is an original contributor of dojox.mobile and a committer to the Dojo Toolkit.




