eduwavepool.unizwa.edu.om€¦ · Web viewProgram 1: Firest PHP Code Hello This is HTML
pcnirala.files.wordpress.com1 A1. Getting Started: Hello Dojo 1. HelloDojo Tutorial: Hello
Transcript of pcnirala.files.wordpress.com1 A1. Getting Started: Hello Dojo 1. HelloDojo Tutorial: Hello
1
A1. Getting Started: Hello Dojo
1. HelloDojo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Tutorial: Hello Dojo!</title>
</head>
<body>
<h1 id="greeting">Hello</h1>
<!-- load Dojo -->
<script src="/WebApp/dojo-release-1.10.4/dojo/dojo.js"
data-dojo-config="async: true"></script>
<script>
require([
'dojo/dom',
'dojo/dom-construct'
], function (dom, domConstruct) {
var greetingNode = dom.byId('greeting');
domConstruct.place('<em> Dojo!</em>', greetingNode);
});
</script>
</body>
</html>
Style: style.css
body {
padding:2em;
}
h1 {
margin-bottom:2em;
}
.add-borders ul, .add-borders li, .add-borders div, .add-borders a {
padding: 2px;
}
.add-borders ul {
border: 1px solid red;
}
.add-borders li {
border: 1px solid blue;
}
.add-borders div {
border: 1px solid green;
2
}
.add-borders a {
border: 1px solid black;
}
.bold {
font-weight: bold;
}
.italic {
font-style: italic;
}
.highlight {
background-color: yellow;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
A2. Getting Started: Configuring Dojo with dojoConfig
1. dojoConfig Programmatic
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: dojoConfig</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<style>
#dialog { min-width: 200px; }
</style>
</head>
<body class="claro">
<h1>Demo: dojo/_base/Config</h1>
<div id="dialog" data-dojo-type="dijit/Dialog" data-dojo-props="title: 'dojo/_base/_config'"></div>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dijit/registry", "dojo/parser", "dojo/json", "dojo/_base/config", "dijit/Dialog", "dojo/domReady!"],
function(registry, parser, JSON, config) {
parser.parse();
// Find the dialog
var dialog = registry.byId("dialog");
// Set the content equal to what dojo.config is
dialog.set("content", '<pre>' + JSON.stringify(config, null, '\t') + '</pre>');
// Show the dialog
3
dialog.show();
});
</script>
</body>
</html>
2. dojoConfig Declarative
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: data-dojo-config</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<style>
#dialog { min-width: 200px; }
</style>
</head>
<body class="claro">
<h1>Demo: data-dojo-config</h1>
<div id="dialog" data-dojo-type="dijit/Dialog" data-dojo-props="title: 'data-dojo-config / dojo.config'"></div>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
// Require the registry, parser, Dialog, and wait for domReady
require(["dijit/registry", "dojo/parser", "dojo/json", "dojo/_base/config", "dijit/Dialog", "dojo/domReady!"]
, function(registry, parser, JSON, config) {
parser.parse();
// Find the dialog
var dialog = registry.byId("dialog");
// Set the content equal to what dojo/_base/config is
dialog.set("content", '<pre>' + JSON.stringify(config, null, '\t') + '</pre>');
// Show the dialog
dialog.show();
});
</script>
</body>
</html>
3. Loader Configuration
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: dojo.config.baseUrl</title>
<link rel="stylesheet" href="style.css" media="screen">
4
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<style>
#dialog { min-width: 200px; }
</style>
</head>
<body class="claro">
<h1>Demo: dojo/_base/config.baseUrl</h1>
<div id="dialog" data-dojo-type="demo/AuthoredDialog"
data-dojo-props="title: 'dojo/_base/config.baseUrl demo', authorName: 'Sam Foster'">
</div>
<script>
var dojoConfig = {
has: {
"dojo-firebug": true,
"dojo-debug-messages": true
},
packages: [
{
name: "demo",
location: "/documentation/tutorials/1.10/dojo_config/demo"
}
]
};
</script>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["demo/AuthoredDialog", "dijit/registry", "dojo/json", "dojo/_base/config",
"dojo/parser", "dojo/domReady!"],
function(AuthoredDialog, registry, JSON, config, parser) {
parser.parse();
var dialog = registry.byId("dialog");
dialog.set("content", "<pre>" + JSON.stringify(config, null, "\t") + "</pre>");
dialog.show();
});
</script>
</body>
</html>
4. CustomProperties
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Application Config</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<style>
#dialog { min-width: 200px; }
5
</style>
</head>
<body class="claro">
<h1>Demo: Application Config</h1>
<script>
dojoConfig = {
has: {
"dojo-firebug": true,
"dojo-debug-messages": true
},
app: {
userName: "Anonymous"
}
};
</script>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dijit/Dialog", "dijit/registry", "dojo/_base/config", "dojo/_base/lang", "dojo/json", "dojo/io-query",
"dojo/domReady!"],
function(Dialog, registry, config, lang, JSON, ioQuery) {
// pull configuration from the query string
// and mix it into our app config
var queryParams = ioQuery.queryToObject(location.search.substring(1));
lang.mixin(config.app, queryParams);
// Create a dialog
var dialog = new Dialog({
title: 'Welcome back ' + config.app.userName,
content: '<pre>' + JSON.stringify(config, null, '\t') + '</pre>'
});
// Draw on the app config to put up a personalized message
dialog.show();
});
</script>
</body>
</html>
B1. DOM Basics: Dojo DOM Functions
1. Retrieval
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: byId</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
6
</head>
<body>
<h1>Demo: byId</h1>
<ul id="list">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
</ul>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
<script>
// Require the DOM resource
require(["dojo/dom", "dojo/domReady!"], function(dom) {
function setText(node, text){
node = dom.byId(node);
node.innerHTML = text;
}
var one = dom.byId("one");
setText(one, "One has been set");
setText("two", "Two has been set as well");
});
</script>
</body>
</html>
2. Creation
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: create</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body>
<h1>Demo: create</h1>
<ul id="list">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
7
</ul>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
<script>
require(["dojo/dom", "dojo/dom-construct", "dojo/domReady!"], function(dom, domConstruct) {
var list = dom.byId("list"),
three = dom.byId("three");
domConstruct.create("li", {
innerHTML: "Six"
}, list);
domConstruct.create("li", {
innerHTML: "Seven",
className: "seven",
style: {
fontWeight: "bold"
}
}, list);
domConstruct.create("li", {
innerHTML: "Three and a half"
}, three, "after");
});
</script>
</body>
</html>
3. Placement
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: place</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<style>
#three {
background:#e3e3e3;
}
</style>
</head>
<body>
<h1>Demo: place</h1>
<h4>Move "Three" to the following position</h4>
<button id="moveFirst">The first item</button>
<button id="moveBeforeTwo">Before Two</button>
<button id="moveAfterFour">After Four</button>
8
<button id="moveLast">The last item</button>
<ul id="list">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
</ul>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
<script>
require(["dojo/dom", "dojo/dom-construct", "dojo/on", "dojo/domReady!"], function(dom, domConstruct, on) {
function moveFirst(){
var list = dom.byId("list"),
three = dom.byId("three");
domConstruct.place(three, list, "first");
}
function moveBeforeTwo(){
var two = dom.byId("two"),
three = dom.byId("three");
domConstruct.place(three, two, "before");
}
function moveAfterFour(){
var four = dom.byId("four"),
three = dom.byId("three");
domConstruct.place(three, four, "after");
}
function moveLast(){
var list = dom.byId("list"),
three = dom.byId("three");
domConstruct.place(three, list);
}
// Connect the buttons
on(dom.byId("moveFirst"), "click", moveFirst);
on(dom.byId("moveBeforeTwo"), "click", moveBeforeTwo);
on(dom.byId("moveAfterFour"), "click", moveAfterFour);
on(dom.byId("moveLast"), "click", moveLast);
});
</script>
</body>
</html>
4. Destruction
9
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: empty and destroy</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body>
<h1>Demo: empty and destroy</h1>
<button id="destroyFirst">Destroy the first list item</button>
<button id="destroyAll">Destroy all list items</button>
<ul id="list">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
</ul>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
<script>
require(["dojo/dom", "dojo/dom-construct", "dojo/on", "dojo/domReady!"], function(dom, domConstruct, on) {
function destroyFirst(){
var list = dom.byId("list"),
items = list.getElementsByTagName("li");
if(items.length){
domConstruct.destroy(items[0]);
}
}
function destroyAll(){
domConstruct.empty("list");
}
// Connect buttons
on(dom.byId("destroyFirst"), "click", destroyFirst);
on(dom.byId("destroyAll"), "click", destroyAll);
});
</script>
</body>
</html>
B2. DOM Basics: Animation
1. Animating Properties part 1
10
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Border Animation</title>
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body>
<h3>Demo: Border Animation</h3>
<button id="startButton">Grow Borders</button>
<button id="reverseButton">Shrink Borders</button>
<div id="anim8target" class="box" style="border-style:outset">
<div class="innerBox">A box</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/_base/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(baseFx, on, dom) {
var startButton = dom.byId("startButton"),
reverseButton = dom.byId("reverseButton"),
anim8target = dom.byId("anim8target");
// Set up a couple of click handlers to run our animations
on(startButton, "click", function(evt){
baseFx.animateProperty({
node: anim8target,
properties: { borderWidth: 100 }
}).play();
});
on(reverseButton, "click", function(evt){
baseFx.animateProperty({
node: anim8target,
properties: { borderWidth: 1 }
}).play();
});
});
</script>
</body>
</html>
2. Animating Properties part 2
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: animateProperty with multiple style properties</title>
11
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body>
<h3>Demo: animateProperty with multiple style properties</h3>
<button id="dropButton">Drop out block</button>
<button id="ariseSirButton">Return block</button>
<div id="anim8target" class="box" style="top: 100px; left: 300px; background-color: #fc9">
<div class="innerBox">A box</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/_base/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(baseFx, on, dom) {
var dropButton = dom.byId("dropButton"),
ariseSirButton = dom.byId("ariseSirButton"),
anim8target = dom.byId("anim8target");
// Set up a couple of click handlers to run our animations
on(dropButton, "click", function(evt){
baseFx.animateProperty({
node: anim8target,
properties: {
top: { start: 100, end: 150 },
left: 0,
opacity: { start: 1, end: 0 }
},
duration: 800
}).play();
});
on(ariseSirButton, "click", function(evt){
baseFx.animateProperty({
node: anim8target,
properties: { top: 100, left: 300, opacity: 1 }
}).play();
});
});
</script>
</body>
</html>
3. Easing
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Animation Easing</title>
<link rel="stylesheet" href="style.css" media="screen">
</head>
12
<body>
<h1>Demo: Animation Easing</h1>
<button id="dropButton">Drop block</button>
<button id="ariseSirButton">Return block</button>
<div id="anim8target" class="box" style="top: 0; left: 50%; background-color: #fc9">
<div class="innerBox">A box</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/_base/fx", "dojo/fx/easing", "dojo/window", "dojo/on", "dojo/dom", "dojo/domReady!"], function(baseFx, easing,
win, on, dom) {
var dropButton = dom.byId("dropButton"),
ariseSirButton = dom.byId("ariseSirButton"),
anim8target = dom.byId("anim8target");
// Set up a couple of click handlers to run our animations
on(dropButton, "click", function(evt){
// get the dimensions of our viewport
var viewport = win.getBox(win.doc);
baseFx.animateProperty({
// use the bounceOut easing routine to have the box accelerate
// and then bounce back a little before stopping
easing: easing.bounceOut,
duration: 500,
node: anim8target,
properties: {
// calculate the 'floor'
// and subtract the height of the node to get the distance from top we need
top: { start: 0, end:viewport.h - anim8target.offsetHeight }
}
}).play();
});
on(ariseSirButton, "click", function(evt){
baseFx.animateProperty({
node: anim8target,
properties: { top: 0 }
}).play();
});
});
</script>
</body>
</html>
4. Putting it Together
<!DOCTYPE HTML>
<html lang="en">
13
<head>
<meta charset="utf-8">
<title>Demo: Combining and Chaining Animations</title>
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body>
<h1>Demo: Combining and Chaining Animations</h1>
<button id="swapButton">Swap</button>
<div class="container" id="container">
<div id="content1" class="contentBox" style="top: 0; left: 0">
<div class="innerBox">1: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident.</div>
</div>
<div id="content2" class="contentBox" style="top: 0; left: 250px">
<div class="innerBox">2: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div>
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/_base/fx", "dojo/fx", "dojo/fx/easing", "dojo/dom-style", "dojo/dom", "dojo/aspect", "dojo/on",
"dojo/domReady!"], function(baseFx, fx, easing, domStyle, dom, aspect, on) {
// define a function to return the animation which
// swaps the positions of 2 nodes
function swapAnim(node1, node2) {
var posn1 = parseInt(domStyle.get(node1, "left")),
posn2 = parseInt(domStyle.get(node2, "left"));
return moveNodes = fx.combine([
fx.slideTo({
duration: 1200,
node: node2,
left: posn1
}),
fx.slideTo({
duration: 1200,
node: node1,
left: posn2
})
]);
}
var originalOrder = true; // track which order our content nodes are in
var swapButton = dom.byId("swapButton"),
14
c1 = originalOrder ? dom.byId("content1") : dom.byId("content2"),
c2 = originalOrder ? dom.byId("content2") : dom.byId("content1"),
container = dom.byId("container");
// Set up a click handlers to run our animations
on(swapButton, "click", function(evt){
// chain the swap nodes animation
// with another to fade out a background color in our container
var anim = fx.chain([
swapAnim(c1, c2),
baseFx.animateProperty({
node: container,
properties: {
backgroundColor: "#fff"
}
})
]);
// before the animation begins, set initial container background
aspect.before(anim, "beforeBegin", function(){
domStyle.set(container, "backgroundColor", "#eee");
});
// when the animation ends, toggle the originalOrder
on(anim, "End", function(n1, n2){
originalOrder = !originalOrder;
});
anim.play();
});
});
</script>
</body>
</html>
B3. DOM Basics: Dojo Effects
1. Fading
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tutorial: fx.fadeIn and fx.fadeOut</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body>
<h1>Tutorial: fx.fadeIn and fx.fadeOut</h1>
15
<button id="fadeOutButton">Fade block out</button>
<button id="fadeInButton">Fade block in</button>
<div id="fadeTarget" class="red-block">
A red block
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true, isDebug: true"></script>
<script>
require(["dojo/_base/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(fx, on, dom) {
var fadeOutButton = dom.byId("fadeOutButton"),
fadeInButton = dom.byId("fadeInButton"),
fadeTarget = dom.byId("fadeTarget");
on(fadeOutButton, "click", function(evt){
fx.fadeOut({ node: fadeTarget }).play();
});
on(fadeInButton, "click", function(evt){
fx.fadeIn({ node: fadeTarget }).play();
});
});
</script>
</body>
</html>
2. Wiping
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tutorial: fx.wipeIn and fx.wipeOut</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body>
<h1>Tutorial: fx.wipeIn and fx.wipeOut</h1>
<button id="wipeOutButton">Wipe block out</button>
<button id="wipeInButton">Wipe block in</button>
<div id="wipeTarget" class="red-block wipe">
A red block
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true, isDebug: true"></script>
<script>
require(["dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(fx, on, dom) {
var wipeOutButton = dom.byId("wipeOutButton"),
wipeInButton = dom.byId("wipeInButton"),
wipeTarget = dom.byId("wipeTarget");
16
on(wipeOutButton, "click", function(evt){
fx.wipeOut({ node: wipeTarget }).play();
});
on(wipeInButton, "click", function(evt){
fx.wipeIn({ node: wipeTarget }).play();
});
});
</script>
</body>
</html>
3. Sliding
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tutorial: fx.slideTo</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body>
<h1>Tutorial: fx.slideTo</h1>
<button id="slideAwayButton">Slide block away</button>
<button id="slideBackButton">Slide block back</button>
<div id="slideTarget" class="red-block slide">
A red block
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true, isDebug: true"></script>
<script>
require(["dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(fx, on, dom) {
var slideAwayButton = dom.byId("slideAwayButton"),
slideBackButton = dom.byId("slideBackButton"),
slideTarget = dom.byId("slideTarget");
on(slideAwayButton, "click", function(evt){
fx.slideTo({ node: slideTarget, left: "200", top: "200" }).play();
});
on(slideBackButton, "click", function(evt){
fx.slideTo({ node: slideTarget, left: "0", top: "100" }).play();
});
});
</script>
</body>
</html>
17
4. Animation Events
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tutorial: fx Events</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body>
<h1>Tutorial: fx Events</h1>
<button id="slideAwayButton">Slide block away</button>
<button id="slideBackButton">Slide block back</button>
<div id="slideTarget" class="red-block slide">
A red block
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true, isDebug: true"></script>
<script>
require(["dojo/fx", "dojo/on", "dojo/dom-style", "dojo/dom", "dojo/domReady!"], function(fx, on, style, dom) {
var slideAwayButton = dom.byId("slideAwayButton"),
slideBackButton = dom.byId("slideBackButton"),
slideTarget = dom.byId("slideTarget");
on(slideAwayButton, "click", function(evt){
// Note that we're specifying the beforeBegin as a property of the animation
// rather than using connect. This ensures that our beforeBegin handler
// executes before any others.
var anim = fx.slideTo({
node: slideTarget,
left: "200",
top: "200",
beforeBegin: function(){
console.warn("slide target is: ", slideTarget);
style.set(slideTarget, {
left: "0px",
top: "100px"
});
}
});
// We could have also specified onEnd above alongside beforeBegin,
// but it's just as easy to connect like so
on(anim, "End", function(){
style.set(slideTarget, {
backgroundColor: "blue"
18
});
}, true);
// Don't forget to actually start the animation!
anim.play();
});
on(slideBackButton, "click", function(evt){
var anim = fx.slideTo({
node: slideTarget,
left: "0",
top: "100",
beforeBegin: function(){
style.set(slideTarget, {
left: "200px",
top: "200px"
});
}
});
on(anim, "End", function(){
style.set(slideTarget, {
backgroundColor: "red"
});
}, true);
anim.play();
});
});
</script>
</body>
</html>
5. Chaining
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tutorial: fx.chain</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body>
<h1>Tutorial: fx.chain</h1>
<button id="slideAwayButton">Slide block away</button>
<button id="slideBackButton">Slide block back</button>
<div id="slideTarget" class="red-block slide chain">
19
A red block
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true, isDebug: true"></script>
<script>
require(["dojo/_base/fx", "dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"
], function (baseFx, fx, on, dom) {
var slideAwayButton = dom.byId("slideAwayButton"),
slideBackButton = dom.byId("slideBackButton"),
slideTarget = dom.byId("slideTarget");
// Set up a couple of click handlers to run our chained animations
on(slideAwayButton, "click", function(evt){
fx.chain([
baseFx.fadeIn({ node: slideTarget }),
fx.slideTo({ node: slideTarget, left: "200", top: "200" }),
baseFx.fadeOut({ node: slideTarget })
]).play();
});
on(slideBackButton, "click", function(evt){
fx.chain([
baseFx.fadeIn({ node: slideTarget }),
fx.slideTo({ node: slideTarget, left: "0", top: "100" }),
baseFx.fadeOut({ node: slideTarget })
]).play();
});
});
</script>
</body>
</html>
6. Combining
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tutorial: fx.combine</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body>
<h1>Tutorial: fx.combine</h1>
<button id="slideAwayButton">Slide block away</button>
<button id="slideBackButton">Slide block back</button>
<div id="slideTarget" class="red-block slide chain">
A red block
20
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true, isDebug: true"></script>
<script>
require(["dojo/_base/fx", "dojo/fx", "dojo/on", "dojo/dom", "dojo/domReady!"], function(baseFx, fx, on, dom) {
var slideAwayButton = dom.byId("slideAwayButton"),
slideBackButton = dom.byId("slideBackButton"),
slideTarget = dom.byId("slideTarget");
// Set up a couple of click handlers to run our combined animations
on(slideAwayButton, "click", function(evt){
fx.combine([
baseFx.fadeIn({ node: slideTarget }),
fx.slideTo({ node: slideTarget, left: "200", top: "200" })
]).play();
});
on(slideBackButton, "click", function(evt){
fx.combine([
fx.slideTo({ node: slideTarget, left: "0", top: "100" }),
baseFx.fadeOut({ node: slideTarget })
]).play();
});
});
</script>
</body>
</html>
B4. DOM Basics: Events with Dojo
1. DOM Events
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: dojo/on</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<style>
#myButton {
margin-bottom:1em;
}
#myDiv {
border: 1px solid black;
background-color: white;
width: 100px;
height: 100px;
21
}
</style>
</head>
<body>
<h1>Demo: dojo/on</h1>
<button id="myButton">Click me!</button>
<div id="myDiv">Hover over me!</div>
<br /><br />
<button id="myScopedButton1">Click me to see the scope of my handler ("myScopedButton1")</button>
<br/>
<button id="myScopedButton2">Click me to see the scope of my handler ("myObject")</button>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true"></script>
<script>
require(["dojo/on", "dojo/dom", "dojo/dom-style", "dojo/_base/lang", "dojo/mouse", "dojo/domReady!"],
function(on, dom, domStyle, lang, mouse) {
var myButton = dom.byId("myButton"),
myDiv = dom.byId("myDiv"),
myScopedButton1 = dom.byId("myScopedButton1"),
myScopedButton2 = dom.byId("myScopedButton2"),
myObject = {
id: "myObject",
onClick: function(evt){
alert("The scope of this handler is " + this.id);
}
};
on(myButton, "click", function(evt){
domStyle.set(myDiv, "backgroundColor", "blue");
});
on(myDiv, mouse.enter, function(evt){
domStyle.set(myDiv, "backgroundColor", "red");
});
on(myDiv, mouse.leave, function(evt){
domStyle.set(myDiv, "backgroundColor", "");
});
var handle = on(myButton, "click", function(evt){
// Remove this event using the handle
handle.remove();
// Do other stuff here that you only want to happen one time
alert("This alert will only happen one time.");
});
// This will alert "myScopedButton1"
on(myScopedButton1, "click", myObject.onClick);
// This will alert "myObject" rather than "myScopedButton2"
on(myScopedButton2, "click", lang.hitch(myObject, "onClick"));
});
</script>
</body>
</html>
22
2. NodeList events
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: NodeList.on via dojo/query</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body>
<h1>Demo: NodeList.on via dojo/query</h1>
<button id="button1" class="clickMe">Click me</button>
<button id="button2" class="clickMeAlso">Click me also</button>
<button id="button3" class="clickMe">Click me too</button>
<button id="button4" class="clickMeAlso">Please click me</button>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true"></script>
<script>
require(["dojo/query", "dojo/_base/lang", "dojo/domReady!"], function(query, lang) {
var myObject = {
id: "myObject",
onClick: function(evt){
alert("The scope of this handler is " + this.id);
}
};
query(".clickMe").on("click", myObject.onClick);
query(".clickMeAlso").on("click", lang.hitch(myObject, "onClick"));
});
</script>
</body>
</html>
3. Event Delegation
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Event Delegation with dojo/on</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body>
<h1>Demo: Event Delegation with dojo/on</h1>
23
<div id="parentDiv">
<button id="button1" class="clickMe">Click me</button>
<button id="button2" class="clickMe">Click me also</button>
<button id="button3" class="clickMe">Click me too</button>
<button id="button4" class="clickMe">Please click me</button>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true"></script>
<script>
require(["dojo/on", "dojo/dom", "dojo/query", "dojo/domReady!"], function(on, dom) {
var myObject = {
id: "myObject",
onClick: function(evt){
alert("The scope of this handler is " + this.id);
}
};
var div = dom.byId("parentDiv");
on(div, ".clickMe:click", myObject.onClick);
});
</script>
</body>
</html>
4. Publish and Subscribe
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Publish and Subscribe with dojo/topic</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body>
<h1>Demo: Publish and Subscribe with dojo/topic</h1>
<button id="alertButton">Alert the user</button>
<button id="createAlert">Create another alert button</button>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true"></script>
<script>
require(["dojo/on", "dojo/topic", "dojo/dom", "dojo/dom-construct", "dojo/domReady!"], function(on, topic, dom, domConstruct) {
var alertButton = dom.byId("alertButton"),
createAlert = dom.byId("createAlert");
on(alertButton, "click", function() {
// When this button is clicked,
// publish to the "alertUser" topic
topic.publish("alertUser", "I am alerting you.");
});
24
on(createAlert, "click", function(evt){
// Create another button
var anotherButton = domConstruct.create("button", {
innerHTML: "Another alert button"
}, createAlert, "after");
// When the other button is clicked,
// publish to the "alertUser" topic
on(anotherButton, "click", function(evt){
topic.publish("alertUser", "I am also alerting you.");
});
});
// Register the alerting routine with the "alertUser"
// topic.
topic.subscribe("alertUser", function(text){
alert(text);
});
});
</script>
</body>
</html>
B5. DOM Basics: Keyboard Events with Dojo
1. Keyboard Events
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: dojo/keys</title>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true"></script>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<style>
input {
display: block;
}
</style>
</head>
<body>
<h1>Press any key</h1>
keyCode value: <input type="text" id="keyCode" size="2">
<?php Utils::printDojoScript("async: true") ?>
<script>
require(["dojo/on", "dojo/dom", "dojo/domReady!"], function (on, dom) {
on(document, "keyup", function(event) {
25
dom.byId("keyCode").value = event.keyCode;
});
});
</script>
</body>
</html>
2. The KeyboardEvent object part 1
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: dojo/keys</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<style>
input {
display: block;
}
#console {
margin-top: 2em;
border-top: 1px solid #333;
}
#console div {
background: #eee;
padding:5px 10px;
margin-top: 2px;
}
</style>
</head>
<body>
<h1>Press Up or Down Arrow Keys</h1>
<input type="text" id="input1" value="up">
<input type="text" id="input2" value="down">
<input type="submit" id="send" value="send">
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true"></script>
<script>
require(["dojo/dom-construct", "dojo/on", "dojo/query", "dojo/keys", "dojo/dom", "dojo/domReady!"
], function(domConstruct, on, query, keys, dom) {
function log(msg){
var c = dom.byId("console");
if(!c){
c = domConstruct.create("div", {
id: "console"
}, document.body);
}
c.innerHTML += "<div>" + msg + "</div>";
26
}
query("input[type='text']").on("keydown", function(event) {
//query returns a nodelist, which has an on() function available that will listen
//to all keydown events for each node in the list
switch(event.keyCode) {
case keys.UP_ARROW:
event.preventDefault();
//preventing the default behavior in case your browser
// uses autosuggest when you hit the down or up arrow.
log("up arrow has been pressed");
break;
case keys.DOWN_ARROW:
event.preventDefault();
//preventing the default behavior in case your browser
// uses autosuggest when you hit the down or up arrow.
log("down arrow has been pressed");
break;
case keys.ENTER:
log("enter has been pressed");
break;
default:
log("some other key: " + event.keyCode);
}
});
});
</script>
</body>
</html>
3. The KeyboardEvent object part 2
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Form Traversal</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<style>
input {
display: block;
}
#console {
margin-top: 2em;
border-top: 1px solid #333;
}
#console div {
background: #eee;
27
padding:5px 10px;
margin-top: 2px;
}
</style>
</head>
<body>
<h1>Press Up/Down Arrow Or Enter Keys to traverse form.</h1>
<h2>Home/End will go to the beginning or end.</h2>
<form id="traverseForm">
First Name: <input type="text" id="firstName">
Last Name: <input type="text" id="lastName">
Email Address: <input type="text" id="email">
Phone Number: <input type="text" id="phone">
<input type="submit" id="send" value="send">
</form>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true"></script>
<script>
require(["dojo/dom", "dojo/dom-construct", "dojo/on", "dojo/query", "dojo/keys", "dojo/NodeList-traverse", "dojo/domReady!"],
function(dom, domConstruct, on, query, keys) {
var inputs = query("input");
function log(msg){
var c = dom.byId("console");
if(!c){
c = domConstruct.create("div", {
id: "console"
}, document.body);
}
c.innerHTML += "<div>" + msg + "</div>";
}
on(dom.byId("traverseForm"), "keydown", function(event) {
var node = query.NodeList([event.target]);
var nextNode;
//on listens for the keydown events inside of the div node, on all form elements
switch(event.keyCode) {
case keys.UP_ARROW:
nextNode = node.prev("input");
if(nextNode[0]){
//if not first element
nextNode[0].focus();
//moving the focus from the current element to the previous
}
break;
case keys.DOWN_ARROW:
nextNode = node.next("input");
if(nextNode[0]){
//if not last element
nextNode[0].focus();
//moving the focus from the current element to the next
}
28
break;
case keys.HOME:
inputs[0].focus();
break;
case keys.END:
inputs[inputs.length - 2].focus();
break;
case keys.ENTER:
event.preventDefault();
//prevent default keeps the form from submitting when the enter button is pressed
//on the submit button
if(event.target.type !== "submit"){
nextNode = node.next("input");
if(nextNode[0]){
//if not last element
nextNode[0].focus();
//moving the focus from the current element to the next
}
}else {
// submit the form
log("form submitted!");
}
break;
default:
log("some other key: " + event.keyCode);
}
});
});
</script>
</body>
</html>
4. Keyboard Navigation
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/resources/dojo.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" />
<style type="text/css">
table {
width: 20em;
margin: 3em 0 0 3em;
}
table, td {
border: 1px solid gray;
}
td {
padding: 0.5em;
}
td:focus {
29
background-color: yellow;
}
</style>
</head>
<body class="claro">
<p><h1>Click on a cell below, then try navigating:</h1>
<ul>
<li>up, down, left, right</li>
<li>home, end</li>
<li>Letters - "a" for "apple", "b" for "banana", etc</li>
</ul>
</p>
<table data-dojo-type="MyGrid" id="grid">
<tr>
<td data-dojo-type="MyCell">apple</td>
<td data-dojo-type="MyCell">banana</td>
<td data-dojo-type="MyCell">orange</td>
</tr>
<tr>
<td data-dojo-type="MyCell">pear</td>
<td data-dojo-type="MyCell">grapes</td>
<td data-dojo-type="MyCell">strawberry</td>
</tr>
</table>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="parseOnLoad: false"></script>
<script>
require([
"dojo/_base/declare",
"dojo/_base/array",
"dojo/parser",
"dojo/query",
"dijit/_WidgetBase",
"dijit/_KeyNavMixin",
"dojo/domReady!"
], function(declare, arrayUtil, parser, query, _WidgetBase, _KeyNavMixin){
MyGrid = declare([_WidgetBase, _KeyNavMixin], {
buildRendering: function(){
// This is a behavioral widget so we'll just use the existing DOM.
// Alternately we could have a template.
this.inherited(arguments);
// Set containerNode. Usually this is set in the template.
this.containerNode = this.domNode;
},
postCreate: function(){
// Don't forget the this.inherited() call
this.inherited(arguments);
// Set tabIndex on the container <table> node, since by default it's not tab navigable
this.domNode.setAttribute("tabIndex", "0");
30
},
// Specifies which DOMNode children can be focused
childSelector: "td",
_focusedChildIndex: function(children){
// summary:
// Helper method to return the index of the currently focused child in the array
return arrayUtil.indexOf(children, this.focusedChild);
},
// Home/End key support
_getFirst: function(){
return this.getChildren()[0];
},
_getLast: function(){
var children = this.getChildren();
return children[children.length - 1];
},
// Simple arrow key support. Up/down logic assumes that evey row has the same number of cells.
_onLeftArrow: function(){
var children = this.getChildren();
this.focusChild(children[(this._focusedChildIndex(children) - 1 + children.length) % children.length]);
},
_onRightArrow: function(){
var children = this.getChildren();
this.focusChild(children[(this._focusedChildIndex(children) + 1) % children.length]);
},
_numCols: function(){
// summary:
// Helper method to return the number of columns in the table
return query("tr:first-child > td", this.domNode).length;
},
_onDownArrow: function(){
var children = this.getChildren();
this.focusChild(children[(this._focusedChildIndex(children) + this._numCols()) % children.length]);
},
_onUpArrow: function(){
var children = this.getChildren();
this.focusChild(children[(this._focusedChildIndex(children) - this._numCols() + children.length) %
children.length]);
},
// Letter key navigation support
_getNext: function(child){
var children = this.getChildren();
return children[(arrayUtil.indexOf(children, child) + 1) % children.length];
}
});
MyCell = declare(_WidgetBase, {
postCreate: function(){
31
this.domNode.setAttribute("tabIndex", "-1");
},
focus: function(){
this.domNode.focus();
}
});
parser.parse();
});
</script>
</body>
</html>
B6. DOM Basics: Using dojo query
1. More advanced selections
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tutorial: Queries</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
</head>
<body>
<h1>Tutorial: Queries</h1>
<p>Click the buttons below to see which nodes are selected by the corresponding queries.</p>
<button class="queryButton">#list</button>
<button class="queryButton">.odd</button>
<button class="queryButton">#list .odd</button>
<button class="queryButton">a.odd</button>
<button class="queryButton">li a</button>
<button class="queryButton">li > a</button>
<button class="queryButton">.italic > a</button>
<div class="add-borders">
<ul id="list">
<li class="odd">
<div class="bold">
<a class="odd">Odd</a>
</div>
</li>
<li class="even">
<div class="italic">
<a class="even">Even</a>
</div>
</li>
32
<li class="odd">
<a class="odd">Odd</a>
</li>
<li class="even">
<div class="bold">
<a class="even">Even</a>
</div>
</li>
<li class="odd">
<div class="italic">
<a class="odd">Odd</a>
</div>
</li>
<li class="even">
<a class="even">Even</a>
</li>
</ul>
<ul id="list2">
<li class="odd">Odd</li>
</ul>
</div>
<p>These lists are rendered from the following markup:</p>
<pre class="brush: html;"><ul id="list">
<li class="odd">
<div class="bold">
<a class="odd">Odd</a>
</div>
</li>
<li class="even">
<div class="italic">
<a class="even">Even</a>
</div>
</li>
<li class="odd">
<a class="odd">Odd</a>
</li>
<li class="even">
<div class="bold">
<a class="even">Even</a>
</div>
</li>
<li class="odd">
<div class="italic">
<a class="odd">Odd</a>
</div>
</li>
<li class="even">
<a class="even">Even</a>
</li>
</ul>
33
<ul id="list2">
<li class="odd">Odd</li>
</ul></pre>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/query", "dojo/NodeList-dom", "dojo/domReady!"], function(query) {
function executeSelector(button){
// Find and remove all highlight classes
query(".highlight").removeClass("highlight");
// Add the highlight class based on the selector inside of our button
query(button.innerHTML.replace(">", ">")).addClass("highlight");
}
query(".queryButton").on("click", function(e) {
executeSelector(e.target);
});
});
</script>
</body>
</html>
2. NodeList
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tutorial: NodeList</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
</head>
<body>
<h1>Tutorial: NodeList</h1>
<p>Click the buttons below to execute the corresponding query and NodeList functions.</p>
<button id="oddForEach">query(".odd").forEach(...)</button><br />
<button id="evenAddBlue">query(".even").addClass("blue")</button><br />
<button id="oddAddBlue">query(".odd").removeClass("red").addClass("blue")</button><br />
<button id="evenStyle">query(".even").style("color", "white").addClass("italic")</button><br />
<br />
<div id="list">
<div class="odd">One</div>
<div class="even">Two</div>
<div class="odd">Three</div>
34
<div class="even">Four</div>
<div class="odd">Five</div>
<div class="even">Six</div>
</div>
<p>This list is rendered from the following markup:</p>
<pre class="brush: html;"><div id="list">
<div class="odd">One</div>
<div class="even">Two</div>
<div class="odd">Three</div>
<div class="even">Four</div>
<div class="odd">Five</div>
<div class="even">Six</div>
</div></pre>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
// Wait for the DOM to be ready before working with it
require(["dojo/query", "dojo/dom-class", "dojo/on",
"dojo/dom", "dojo/NodeList-dom", "dojo/domReady!"
], function(query, domClass, on, dom) {
function oddForEach(){
query(".odd").forEach(function(node){
// For each node with a class of "odd",
// remove the class "blue" and add the class "red"
domClass.remove(node, "blue");
domClass.add(node, "red");
});
}
function oddAddBlue(){
// For each node with a class of "odd",
// remove the class "red" and add the class "blue"
query(".odd").removeClass("red").addClass("blue");
}
function evenAddBlue(){
// For each node with a class of "even",
// add the class "blue"
query(".even").addClass("blue");
}
function evenStyle(){
// For each node with a class of "even",
// Set its color CSS style to "white" and add a class of "italic"
query(".even").style("color", "white").addClass("italic");
}
// Connect the buttons
on(dom.byId("oddForEach"), "click", oddForEach);
35
on(dom.byId("evenAddBlue"), "click", evenAddBlue);
on(dom.byId("oddAddBlue"), "click", oddAddBlue);
on(dom.byId("evenStyle"), "click", evenStyle);
});
</script>
</body>
</html>
3. Events
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Tutorial: NodeList Events</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
</head>
<body>
<h1>Tutorial: NodeList Events</h1>
<button class="hookUp demoBtn">Click Me!</button>
<button class="hookUp demoBtn">Click Me!</button>
<button class="hookUp demoBtn">Click Me!</button>
<button class="hookUp demoBtn">Click Me!</button>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
// Wait for the DOM to be ready before working with it
require(["dojo/query", "dojo/domReady!"], function(query) {
query(".hookUp").on("click", function(){
alert("This button is hooked up!");
});
});
</script>
</body>
</html>
B7. DOM Basics: NodeList Extensions
1. Getting Started
<!DOCTYPE HTML>
<html lang="en">
<head>
36
<meta charset="utf-8">
<title>Demo: NodeList Extensions: dojo/query Recap</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: NodeList Extensions: dojo/query Recap</h1>
<button type="button" id="btn">Pick out fresh fruits</button>
<h3>Fresh Fruits</h3>
<ul id="freshList"></ul>
<h3>Fruits</h3>
<ul>
<li class="fresh">Apples</li>
<li class="fresh">Persimmons</li>
<li class="fresh">Grapes</li>
<li class="fresh">Fresh Figs</li>
<li class="dried">Dates</li>
<li class="dried">Raisins</li>
<li class="dried">Prunes</li>
<li class="fresh dried">Apricots</li>
<li class="fresh">Peaches</li>
<li class="fresh">Bananas</li>
<li class="fresh">Cherries</li>
</ul>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/query", "dojo/domReady!"], function(query){
query("#btn").on("click", function(){
query("li.fresh").on("click", function(event){
log("I love fresh " + event.target.innerHTML);
});
});
function log(msg){
var c = document.getElementById("console");
if(!c){
c = document.createElement("div");
c.setAttribute("id", "console");
document.body.appendChild(c);
}
c.innerHTML += "<div>" + msg + "</div>";
}
});
</script>
</body>
</html>
37
2. Animating Elements
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: NodeList Extensions: dojo/NodeList-fx</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<style>
li { position: relative; width: 400px; }
</style>
</head>
<body class="claro">
<h1>Demo: NodeList Extensions: dojo/NodeList-fx</h1>
<button type="button" id="btn">Highlight fresh fruits</button>
<h3>Fruits</h3>
<ul style="position:relative">
<li class="fresh">Apples</li>
<li class="fresh">Persimmons</li>
<li class="fresh">Grapes</li>
<li class="fresh">Fresh Figs</li>
<li class="dried">Dates</li>
<li class="dried">Raisins</li>
<li class="dried">Prunes</li>
<li class="fresh dried">Apricots</li>
<li class="fresh">Peaches</li>
<li class="fresh">Bananas</li>
<li class="fresh">Cherries</li>
</ul>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/query", "dojo/NodeList-fx", "dojo/domReady!"], function(query){
query("#btn").on("click", function(){
query("li.fresh")
.slideTo({
left: 200,
auto: true,
duration: 750
})
.animateProperty({
properties: {
backgroundColor: { start: "#ffffff", end: "#ffff66" }
},
duration: 750
})
.play();
});
38
});
</script>
</body>
</html>
3. Associating Data with Elements
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: NodeList Extensions: dojo/NodeList-data</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: NodeList Extensions: dojo/NodeList-data</h1>
<button type="button" id="btn">Inspect Data</button>
<h3>Fruits</h3>
<p>Click the fruits you like!</p>
<ul class="fruitList">
<li class="fresh">Apples</li>
<li class="fresh">Persimmons</li>
<li class="fresh">Grapes</li>
<li class="fresh">Fresh Figs</li>
<li class="dried">Dates</li>
<li class="dried">Raisins</li>
<li class="dried">Prunes</li>
<li class="fresh dried">Apricots</li>
<li class="fresh">Peaches</li>
<li class="fresh">Bananas</li>
<li class="fresh">Cherries</li>
</ul>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/query", "dojo/NodeList-data", "dojo/domReady!"], function(query, NodeList){
function mark(evt){
var nodeList = new NodeList(this); // make a new NodeList from the clicked element
nodeList.data("updated", new Date()); // update the 'updated' key for this element via the NodeList
}
query("li") // get all list items
.data("updated", new Date()) // set the initial data for each matching element
.on("click", mark); // add the event handler
query("#btn").on("click", function(){
query("li").data("updated").forEach(function(date){
39
log(date.getTime());
});
});
function log(msg){
var c = document.getElementById("console");
if(!c){
c = document.createElement("div");
c.setAttribute("id", "console");
document.body.appendChild(c);
}
c.innerHTML += "<div>" + msg + "</div>";
}
});
</script>
</body>
</html>
4. Moving Around the DOM
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: NodeList Extensions: dojo/NodeList-traverse</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
</head>
<body>
<h1>Demo: NodeList Extensions: dojo/NodeList-traverse</h1>
<h3>All Fruit</h3>
<ul>
<li><h4>Alkaline Fruits</h4>
<ul class="fruitList">
<li class="alkaline yum">Apples</li>
<li class="alkaline">Persimmons</li>
<li class="alkaline">Thompson Grapes (Seedless)</li>
<li class="alkaline">Muscat Grapes</li>
<li class="alkaline">All Sweet Grapes</li>
<li class="alkaline">Fresh Figs</li>
<li class="alkaline">Dates</li>
<li class="alkaline">Figs</li>
<li class="alkaline yum">Raisins</li>
<li class="alkaline yuck">Prunes</li>
<li class="alkaline">Apricots</li>
<li class="alkaline">Peaches</li>
<li class="alkaline yum">Bananas</li>
<li class="alkaline">Cherries</li>
<li class="alkaline">Bananas</li>
<li class="alkaline">Litchi "Nuts"</li>
40
<li class="alkaline">Carob</li>
</ul>
</li>
<li><h4>Subacidic Fruits</h4>
<ul class="fruitList">
<li class="subacidic">Sweet Apples (Delicious)</li>
<li class="subacidic">Sweet Peaches</li>
<li class="subacidic">Sweet Nectarines</li>
<li class="subacidic">Pears</li>
<li class="subacidic">Sweet Cherries</li>
<li class="subacidic">Some Grapes (Neither sweet nor sour)</li>
<li class="subacidic">Papayas</li>
<li class="subacidic">Mangos</li>
<li class="subacidic">Apricots</li>
<li class="subacidic">Fresh Litchi "Nuts"</li>
<li class="subacidic">Sweet Plums</li>
<li class="subacidic">Blueberries</li>
<li class="subacidic">Raspberries</li>
<li class="subacidic">Blackberries</li>
<li class="subacidic">Mulberries</li>
<li class="subacidic">Huckleberries</li>
<li class="subacidic">Cherimoyas</li>
</ul>
</li>
<li><h4>Acid Fruits</h4>
<ul class="fruitList">
<li class="acid">Oranges</li>
<li class="acid">Grapefruit</li>
<li class="acid">Pineapples</li>
<li class="acid">Strawberries</li>
<li class="acid">Pomegranates</li>
<li class="acid yuck">Lemons</li>
<li class="acid">Kiwi Fruit</li>
<li class="acid">Kumquats</li>
<li class="acid">Loquats</li>
<li class="acid">Carambolas</li>
<li class="acid yuck">Loganberries</li>
<li class="acid">Gooseberries</li>
<li class="acid">Cranberries </li>
<li class="acid">Limes</li>
<li class="acid">Sour Apples</li>
<li class="acid">Sour Grapes</li>
<li class="acid">Sour Peaches</li>
<li class="acid">Sour Nectarines</li>
<li class="acid">Sour Plums</li>
<li class="acid yuck">Sour Cherries</li>
</ul>
</li>
<li><h4>Melons</h4>
<ul class="fruitList">
<li class="melon">Watermelon</li>
<li class="melon yum">Honeydew Melon</li>
41
<li class="melon">Honey Balls</li>
<li class="melon yum">Cantaloupe</li>
<li class="melon yuck">Muskmelon</li>
<li class="melon">Casaba Melon</li>
<li class="melon">Crenshaw Melon</li>
<li class="melon">Pie Melon</li>
<li class="melon">Banana Melon</li>
<li class="melon">Persian Melon</li>
<li class="melon">Christmas Melon</li>
<li class="melon">Nutmeg Melon</li>
</ul>
</li>
</ul>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/query", "dojo/NodeList-traverse", "dojo/NodeList-dom", "dojo/domReady!"], function(query){
query("li.yum") // get LI elements with the class 'yum'
.addClass("highlight") // add a 'highlight' class to those LI elements
.closest(".fruitList") // find the closest parent elements of those LIs with the class 'fruitList'
.prev() // get the previous sibling (headings in this case) of each of those fruitList elements
.addClass("happy") // add a 'happy' class to those headings
.style({backgroundPosition: "left", paddingLeft: "20px"}); // add some style properties to those headings
});
</script>
</body>
</html>
5. Manipulating Elements
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: NodeList Extensions: Manipulate</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
</head>
<body>
<h1>Demo: NodeList Extensions: Manipulate</h1>
<h3>Likes</h3>
<ul id="likes"></ul>
<h3>Don't Likes</h3>
<ul id="dontLikes"></ul>
<h3>All Fruit</h3>
<ul>
<li>Alkaline Fruits
<ul>
<li class="alkaline yum">Apples</li>
42
<li class="alkaline">Persimmons</li>
<li class="alkaline">Thompson Grapes (Seedless)</li>
<li class="alkaline">Muscat Grapes</li>
<li class="alkaline">All Sweet Grapes</li>
<li class="alkaline">Fresh Figs</li>
<li class="alkaline">Dates</li>
<li class="alkaline">Figs</li>
<li class="alkaline yum">Raisins</li>
<li class="alkaline yuck">Prunes</li>
<li class="alkaline">Apricots</li>
<li class="alkaline">Peaches</li>
<li class="alkaline yum">Bananas</li>
<li class="alkaline">Cherries</li>
<li class="alkaline">Bananas</li>
<li class="alkaline">Lychees</li>
<li class="alkaline">Carob</li>
</ul>
</li>
<li>Subacidic Fruits
<ul>
<li class="subacidic">Sweet Apples (Delicious)</li>
<li class="subacidic">Sweet Peaches</li>
<li class="subacidic">Sweet Nectarines</li>
<li class="subacidic">Pears</li>
<li class="subacidic">Sweet Cherries</li>
<li class="subacidic">Some Grapes (Neither sweet nor sour)</li>
<li class="subacidic">Papayas</li>
<li class="subacidic">Mangos</li>
<li class="subacidic">Apricots</li>
<li class="subacidic yum">Fresh Lychees</li>
<li class="subacidic">Sweet Plums</li>
<li class="subacidic">Blueberries</li>
<li class="subacidic">Raspberries</li>
<li class="subacidic">Blackberries</li>
<li class="subacidic">Mulberries</li>
<li class="subacidic">Huckleberries</li>
<li class="subacidic">Cherimoyas</li>
</ul>
</li>
<li>Acid Fruits
<ul>
<li class="acid">Oranges</li>
<li class="acid">Grapefruit</li>
<li class="acid">Pineapples</li>
<li class="acid">Strawberries</li>
<li class="acid">Pomegranates</li>
<li class="acid yuck">Lemons</li>
<li class="acid">Kiwi Fruit</li>
<li class="acid">Kumquats</li>
<li class="acid">Loquats</li>
<li class="acid">Carambolas</li>
<li class="acid yuck">Loganberries</li>
43
<li class="acid">Gooseberries</li>
<li class="acid">Cranberries </li>
<li class="acid">Limes</li>
<li class="acid">Sour Apples</li>
<li class="acid">Sour Grapes</li>
<li class="acid">Sour Peaches</li>
<li class="acid">Sour Nectarines</li>
<li class="acid">Sour Plums</li>
<li class="acid yuck">Sour Cherries</li>
</ul>
</li>
<li>Melons
<ul>
<li class="melon">Watermelon</li>
<li class="melon yum">Honeydew Melon</li>
<li class="melon">Honey Balls</li>
<li class="melon yum">Cantaloupe</li>
<li class="melon yuck">Muskmelon</li>
<li class="melon">Casaba Melon</li>
<li class="melon">Crenshaw Melon</li>
<li class="melon">Pie Melon</li>
<li class="melon">Banana Melon</li>
<li class="melon">Persian Melon</li>
<li class="melon">Christmas Melon</li>
<li class="melon">Nutmeg Melon</li>
</ul>
</li>
</ul>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/query", "dojo/NodeList-manipulate", "dojo/domReady!"], function(query){
query(".yum") // get elements with the class 'yum'
.clone() // create a new NodeList containing cloned copies of each element
.prepend('<span class="emoticon happy"></span>') // inject a span inside each of the cloned elements
.appendTo("#likes"); // insert the clones into the element with id 'likes'
query(".yuck")
.clone()
.append('<span class="emoticon sad"></span>')
.appendTo("#dontLikes");
});
</script>
</body>
</html>
6. Advanced Content Injection
<!DOCTYPE HTML>
<html lang="en">
44
<head>
<meta charset="utf-8">
<title>Demo: NodeList Extensions: .html()</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: NodeList Extensions: .html()</h1>
<button type="button" id="btn">Add Checkboxes</button>
<ul>
<li>Fruits
<ul>
<li class="alkaline">Apples</li>
<li class="alkaline">Persimmons</li>
<li class="alkaline">Thompson Grapes (Seedless)</li>
<li class="alkaline">Muscat Grapes</li>
<li class="alkaline">All Sweet Grapes</li>
<li class="alkaline">Fresh Figs</li>
<li class="alkaline">Dates</li>
<li class="alkaline">Figs</li>
<li class="alkaline">Raisins</li>
<li class="alkaline">Prunes</li>
<li class="alkaline">Apricots</li>
<li class="alkaline">Peaches</li>
<li class="alkaline">Bananas</li>
<li class="alkaline">Cherries</li>
<li class="alkaline">Bananas</li>
<li class="alkaline">Litchi "Nuts"</li>
<li class="alkaline">Carob</li>
</ul>
</ul>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/query", "dojo/_base/lang", "dijit/form/CheckBox", "dojo/NodeList-html", "dojo/domReady!"
], function (query, lang) {
var demo = {
addCheckboxes: function(q){
query(q).html('<input name="fruit" value="" data-dojo-type="dijit/form/CheckBox">', {
onBegin: function() {
var label = lang.trim(this.node.innerHTML),
cont = this.content + label;
cont = cont.replace('value=""', 'value="'+lang.trim(this.node.innerHTML) + '"');
this.content = cont;
return this.inherited("onBegin", arguments);
},
parseContent: true
});
query("#btn").map(function(node){
node.disabled = "disabled";
45
});
}
}
query("#btn").on("click", lang.hitch(demo, "addCheckboxes", "li.alkaline"));
});
</script>
</body>
</html>
C1. Dojo Fundamentals: Ajax with dojo/request
1. Dojo request.get_
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: dojo/request/xhr</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
</head>
<body>
<h1>Demo: dojo/request/xhr</h1>
<p>Click the button below to see dojo/request/xhr in action.</p>
<div>
<button id="textButton">Request Text File</button>
</div>
<br /><br />
<div id="resultDiv">
</div>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/dom", "dojo/on", "dojo/request", "dojo/domReady!"],
function(dom, on, request){
// Results will be displayed in resultDiv
var resultDiv = dom.byId("resultDiv");
// Attach the onclick event handler to the textButton
on(dom.byId('textButton'), "click", function(evt){
// Request the text file
request.get("../resources/text/psalm_of_life.txt").then(
function(response){
// Display the text file content
resultDiv.innerHTML = "<pre>" + response + "</pre>";
},
function(error){
// Display the error returned
resultDiv.innerHTML = "<div class=\"error\">" + error + "<div>";
46
}
);
});
}
);
</script>
</body>
</html>
2. JSON (JavaScript Object Notation)
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: dojo/request/xhr JSON</title>
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body>
<h1>Demo: dojo/request/xhr JSON</h1>
<p>Display JSON data received from the server</p>
<div id="resultDiv">
</div>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/dom", "dojo/request", "dojo/json",
"dojo/_base/array", "dojo/domReady!"],
function(dom, request, JSON, arrayUtil){
// Results will be displayed in resultDiv
var resultDiv = dom.byId("resultDiv");
// Request the JSON data from the server
request.get("../resources/data/sample.json", {
// Parse data from JSON to a JavaScript object
handleAs: "json"
}).then(function(data){
// Display the data sent from the server
var html = "<h2>JSON Data</h2>" +
"<p>JSON encoded data:</p>" +
"<p><code>" + JSON.stringify(data) + "</code></p>"+
"<h3>Accessing the JSON data</h3>" +
"<p><strong>title</strong> " + data.title + "</p>" +
"<p><strong>items</strong> An array of items." +
"Each item has a name and a value. The type of " +
"the value is shown in parentheses.</p><dl>";
arrayUtil.forEach(data.items, function(item,i){
html += "<dt>" + item.name +
"</dt><dd>" + item.value +
" (" + (typeof item.value) + ")</dd>";
47
});
html += "</dl>";
resultDiv.innerHTML = html;
},
function(error){
// Display the error returned
resultDiv.innerHTML = error;
});
}
);
</script>
</body>
</html>
3. JSONP (Javascript Object Notation with Padding)
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: dojo/request/script</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
</head>
<body>
<h1>Demo: dojo/request/script</h1>
<p>Click the button below to see dojo/request/script request recent pull requests for Dojo's GitHub repo.</p>
<div>
<button class="action" id="pullrequestsButton">dojo pull requests</button>
</div>
<br /><br />
<ul id="pullrequests">
</ul>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/dom", "dojo/on", "dojo/request/script",
"dojo/dom-construct", "dojo/_base/array",
"dojo/domReady!"
], function(dom, on, script, domConstruct, arrayUtil){
var pullsNode = dom.byId("pullrequests");
// Attach the onclick event handler to tweetButton
on(dom.byId("pullrequestsButton"), "click", function(evt){
// Request the open pull requests from Dojo's GitHub repo
script.get("https://api.github.com/repos/dojo/dojo/pulls", {
// Use the "callback" query parameter to tell
// GitHub's services the name of the function
// to wrap the data in
jsonp: "callback"
48
}).then(function(response){
// Empty the tweets node
domConstruct.empty(pullsNode);
// Create a document fragment to keep from
// doing live DOM manipulation
var fragment = document.createDocumentFragment();
// Loop through each pull request and create a list item
// for it
arrayUtil.forEach(response.data, function(pull){
var li = domConstruct.create("li", {}, fragment);
var link = domConstruct.create("a", {href: pull.url, innerHTML: pull.title}, li);
});
// Append the document fragment to the list
domConstruct.place(fragment, pullsNode);
});
});
});
</script>
</body>
</html>
C2. Dojo Fundamentals: Dojo Arrays
1. Searching
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Array Searching</title>
<link rel="stylesheet" href="style.css" media="screen">
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
</head>
<body>
<h1>Demo: Array Searching</h1>
<p>The following list represents an array; the element whose index is found by calling <code>dojo/_base/array.indexOf(array,
2);</code> is highlighted.</p>
<ul id="list1">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>3</li>
<li>2</li>
<li>1</li>
<li>2</li>
49
<li>3</li>
<li>4</li>
<li>3</li>
<li>2</li>
<li>1</li>
</ul>
<p>The following list represents an array; the element whose index is found by calling <code>dojo/_base/array.indexOf(array, 2,
2);</code> is highlighted.</p>
<ul id="list2">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>3</li>
<li>2</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>3</li>
<li>2</li>
<li>1</li>
</ul>
<p>The following list represents an array; the element whose index is found by calling <code>dojo/_base/array.lastIndexOf(array,
2);</code> is highlighted.</p>
<ul id="list3">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>3</li>
<li>2</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>3</li>
<li>2</li>
<li>1</li>
</ul>
<p>The following list represents an array; the element whose index is found by calling <code>dojo/_base/array.indexOf(array,
object);</code> is highlighted.</p>
<ul id="list4">
<li>{ id: 0 }</li>
<li>{ id: 1 }</li>
<li>{ id: 2 }</li>
<li>{ id: 3 }</li>
</ul>
<script>
require(["dojo/_base/array", "dojo/dom-class", "dojo/query", "dojo/dom", "dojo/domReady!"
], function (arrayUtil, domClass, query, dom) {
50
var arr1 = [1,2,3,4,3,2,1,2,3,4,3,2,1],
obj1 = { id: 1 },
arr2 = [{ id: 0 }, obj1, { id: 2 }, { id: 3 }],
list1 = dom.byId("list1"),
list2 = dom.byId("list2"),
list3 = dom.byId("list3"),
list4 = dom.byId("list4");
// Adds the class "highlight" to the list item corresponding with the
// indices as returned by baseArray.indexOf or baseArray.lastIndexOf.
domClass.add(query("li", list1)[arrayUtil.indexOf(arr1, 2)], "highlight");
domClass.add(query("li", list2)[arrayUtil.indexOf(arr1, 2, 2)], "highlight");
domClass.add(query("li", list3)[arrayUtil.lastIndexOf(arr1, 2)], "highlight");
domClass.add(query("li", list4)[arrayUtil.indexOf(arr2, obj1)], "highlight");
});
</script>
</body>
</html>
2. Looping
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Array Looping</title>
<link rel="stylesheet" href="style.css" media="screen">
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
</head>
<body>
<h1>Demo: Array Looping</h1>
<p>The following lists' items are created by looping through an array of strings.</p>
<ul id="list1"></ul>
<ul id="list2"></ul>
<script>
require(["dojo/_base/array", "dojo/dom-construct", "dojo/dom", "dojo/domReady!"]
, function(arrayUtil, domConstruct, dom) {
var arr = ["one", "two", "three", "four"],
list1 = dom.byId("list1"),
list2 = dom.byId("list2"),
myObject = {
prefix: "ITEM: ",
formatItem: function(item, index){
return this.prefix + item + " (" + index + ")";
},
outputItems: function(arr, node){
arrayUtil.forEach(arr, function(item, index){
domConstruct.create("li", {
innerHTML: this.formatItem(item, index)
51
}, node);
}, this);
}
};
// Skip over index 4, leaving it undefined
arr[5] = "six";
arrayUtil.forEach(arr, function(item, index){
// This function is called for every item in the array
if(index == 3){
// This changes the original array,
// which changes the item passed to
// the sixth invocation of this function
arr[5] = "seven";
}
domConstruct.create("li", {
innerHTML: item + " (" + index + ")"
}, list1);
});
myObject.outputItems(arr, list2);
});
</script>
</body>
</html>
3. Looping Again
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Array Manipulation</title>
<link rel="stylesheet" href="style.css" media="screen">
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
</head>
<body>
<h1>Demo: Array Manipulation</h1>
<p>The following list is a representation of an array.</p>
<ul id="list1">
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
<li>five</li>
</ul>
<br/>
52
<p>The next list is a representation of the previous array being transformed by the following code:</p>
<pre class="brush:js">
arrayUtil.map(original, function(item, index){
return {
id: index * 100,
text: item
};
});
</pre>
<ul id="list2"></ul>
<br/>
<p>The final list is a representation of the mapped array being filtered by the following code:</p>
<pre class="brush:js">
arrayUtil.filter(mapped, function(item, index){
return item.id > 50 && item.id < 350;
});
</pre>
<ul id="list3"></ul>
<script>
require(["dojo/_base/array", "dojo/json", "dojo/dom-construct", "dojo/dom", "dojo/domReady!"]
, function(arrayUtil, JSON, domConstruct, dom) {
var original = ["one", "two", "three", "four", "five"],
list2 = dom.byId("list2"),
list3 = dom.byId("list3"),
mapped, filtered;
mapped = arrayUtil.map(original, function(item, index){
return {
id: index * 100,
text: item
};
}); // [ { id: 0, text: "one" }, { id: 100, text: "two" }, ... ]
filtered = arrayUtil.filter(mapped, function(item, index){
return item.id > 50 && item.id < 350;
}); // [ { id: 100, text: "two" }, { id: 200, text: "three" },
// { id: 300, text: "four" } ]
arrayUtil.forEach(mapped, function(item){
domConstruct.create("li", {
innerHTML: "<code>" + JSON.stringify(item) + "</code>"
}, list2);
});
arrayUtil.forEach(filtered, function(item){
domConstruct.create("li", {
innerHTML: "<code>" + JSON.stringify(item) + "</code>"
}, list3);
});
53
});
</script>
</body>
</html>
4. Matching
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Array Matching</title>
<link rel="stylesheet" href="style.css" media="screen">
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
</head>
<body>
<h1>Demo: Array Matching</h1>
<p>The following are results from running <code>every</code> and <code>some</code> on the lists represented. A result of
<code>true</code> is represented by the function name being highlighted.</p>
<br />
<h3 class="condition">Condition:</h3>
<pre>
function(item){ return item == 1; }
</pre>
<h3>Array:</h3>
<ul id="list1">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<h3>Results:</h3>
<p><span id="every1">every</span> <span id="some1">some</span></p>
<br/>
<h3 class="condition">Condition:</h3>
<pre>
function(item){ return item == 1; }
</pre>
<h3>Array:</h3>
<ul id="list2">
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
54
</ul>
<h3>Results:</h3>
<p><span id="every2">every</span> <span id="some2">some</span></p>
<br/>
<h3 class="condition">Condition:</h3>
<pre>
function(item){ return item == 2; }
</pre>
<h3>Array:</h3>
<ul id="list3">
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
<li>1</li>
</ul>
<h3>Results:</h3>
<p><span id="every3">every</span> <span id="some3">some</span></p>
<script>
require(["dojo/_base/array", "dojo/dom-class", "dojo/domReady!"], function(arrayUtil, domClass) {
var arr1 = [1,2,3,4,5],
arr2 = [1,1,1,1,1],
every1res = arrayUtil.every(arr1, function(item){ return item == 1; }),
every2res = arrayUtil.every(arr2, function(item){ return item == 1; }),
every3res = arrayUtil.every(arr2, function(item){ return item == 2; }),
some1res = arrayUtil.some(arr1, function(item){ return item == 1; }),
some2res = arrayUtil.some(arr2, function(item){ return item == 1; }),
some3res = arrayUtil.some(arr2, function(item){ return item == 2; });
domClass.toggle("every1", "highlight", every1res);
domClass.toggle("every2", "highlight", every2res);
domClass.toggle("every3", "highlight", every3res);
domClass.toggle("some1", "highlight", some1res);
domClass.toggle("some2", "highlight", some2res);
domClass.toggle("some3", "highlight", some3res);
});
</script>
</body>
</html>
C3. Dojo Fundamentals: Augmenting Objects
1. lang.mixin_
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
55
<title>
Demo: lang.mixin
</title>
<link rel="stylesheet" href="style.css" media="screen" type="text/css">
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/_base/lang", "dojo/json"], function(lang, JSON){
var defaultSettings = {
useTheForce: true,
isEvil: false,
length: 75,
color: 'blue'
};
function Lightsaber(settings){
// `defaultSettings` is first mixed into the blank object,
// then `settings` is mixed into the blank object, overriding
// any properties from `defaultSettings` without altering
// the `defaultSettings` object
this.settings = lang.mixin({}, defaultSettings, settings);
}
var darthsaber = new Lightsaber({
isEvil: true,
color: 'red'
});
// { useTheForce: true, isEvil: true, length: 75, color: "red" }
console.log("darthsaber:\n", JSON.stringify(darthsaber.settings, null, '\t'));
});
</script>
</head>
<body>
<h1>Demo: lang.mixin</h1>
<p>View source. The result is in the console.</p>
</body>
</html>
2. lang.extend
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>
Demo: lang.extend
</title>
<link rel="stylesheet" href="style.css" media="screen" type="text/css">
56
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
</head>
<body class="claro">
<h1>Demo: lang.extend</h1>
<p>View source. The result is in the console.</p>
<button id="btn" data-dojo-type="dijit/form/Button">Swing</button>
<script>
require([
"dojo/parser",
"dojo/_base/lang",
"dijit/registry",
"dijit/form/Button"
], function(parser, lang, registry){
parser.parse();
var defaultSettings = {
useTheForce: true,
isEvil: false,
length: 75,
color: 'blue'
};
function Lightsaber(settings){
// `defaultSettings` is first mixed into the blank object,
// then `settings` is mixed into the blank object, overriding
// any properties from `defaultSettings` without altering
// the `defaultSettings` object
this.settings = lang.mixin({}, defaultSettings, settings);
}
var darthsaber = new Lightsaber({
isEvil: true,
color: 'red'
});
var weaponMixin = {
hp: 5,
maxHp: 10,
repair: function() {
if(this.hp >= this.maxHp) {
console.log("Can't repair!");
return;
}
this.hp++;
},
swing: function() {
if(!this.hp) {
57
console.log("Weapon is broken!");
return;
}
this.hp--;
console.log(Math.random() >= 0.5 ? "hit!" : "miss!");
}
};
lang.extend(Lightsaber, weaponMixin);
// Now we can call swing() on our Lightsaber instance,
// even though we augmented the prototype after creating the instance.
darthsaber.swing(); // "hit!" (or "miss!" if you are unlucky)
registry.byId('btn').on('click', lang.hitch(darthsaber, 'swing'));
});
</script>
</body>
</html>
3. lang.clone_
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>
Demo: lang.clone
</title>
<link rel="stylesheet" href="style.css" media="screen" type="text/css">
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/_base/lang"], function(lang){
function mixinDemo(){
var a = {
name: "a",
subObject: {
foo: "bar"
}
};
var b = lang.mixin({}, a);
b.name = "b";
b.subObject.foo = "baz";
console.info('lang.mixin demo:');
console.log("a b, as expected:\n\t",
a.name, b.name);
58
console.log("true - both subObjects reference the exact same object:\n\t",
a.subObject === b.subObject);
console.log("baz baz - a change to one subObject affects both:\n\t",
a.subObject.foo, b.subObject.foo);
}
function cloneDemo(){
var a = {
name: "a",
subObject: {
foo: "bar"
}
};
var b = lang.clone(a);
b.name = "b";
b.subObject.foo = "baz";
console.info('lang.clone demo:');
console.log("a b, same as before:\n\t",
a.name, b.name);
console.log("false - the subObjects are different now:\n\t",
a.subObject === b.subObject);
console.log("bar baz - a change to one subObject no longer affects them all:\n\t",
a.subObject.foo, b.subObject.foo);
}
mixinDemo();
cloneDemo();
});
</script>
</head>
<body>
<h1>Demo: lang.clone</h1>
<p>View source. The result is in the console.</p>
</body>
</html>
C4. Dojo Fundamentals: Creating Classes
C5. Dojo Fundamentals: Getting started with Deferreds
1. Deferred
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: dojo/Deferred</title>
59
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body>
<h1>Demo: dojo/Deferred</h1>
<ul id="userlist"></ul>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/Deferred", "dojo/request", "dojo/_base/array", "dojo/dom-construct", "dojo/dom", "dojo/domReady!"],
function(Deferred, request, arrayUtil, domConstruct, dom) {
var deferred = new Deferred(),
userlist = dom.byId("userlist");
deferred.then(function(res){
arrayUtil.forEach(res, function(user){
domConstruct.create("li", {
id: user.id,
innerHTML: user.username + ": " + user.name
}, userlist);
});
},function(err){
domConstruct.create("li", {
innerHTML: "Error: " + err
}, userlist);
});
// Send an HTTP request
request.get("users.json", {
handleAs: "json"}).then(
function(response){
// Resolve when content is received
deferred.resolve(response);
},
function(error){
// Reject on error
deferred.reject(error);
}
);
});
</script>
</body>
</html>
2. Deferred Rejected
<!DOCTYPE HTML>
<html lang="en">
<head>
60
<meta charset="utf-8">
<title>Demo: dojo/Deferred with dojo/request</title>
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body>
<h1>Demo: dojo/Deferred with dojo/request</h1>
<ul id="userlist"></ul>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/request", "dojo/_base/array", "dojo/dom-construct", "dojo/dom", "dojo/domReady!"],
function(request, arrayUtil, domConstruct, dom) {
var deferred = request.get("users.json", {
handleAs: "json"
});
deferred.then(function(res){
var userlist = dom.byId("userlist");
arrayUtil.forEach(res, function(user){
domConstruct.create("li", {
id: user.id,
innerHTML: user.username + ": " + user.name
}, userlist);
});
},function(err){
// This shouldn't occur, but it's defined just in case
alert("An error occurred: " + err);
});
});
</script>
</body>
</html>
3. Chaining part 1
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Chaining Deferreds</title>
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body>
<h1>Demo: Chaining Deferreds</h1>
<h2>Result from chaining from original deferred</h2>
61
<ul id="userlist1"></ul>
<h2>Result from chaining from original.then()</h2>
<ul id="userlist2"></ul>
<h2>Result from chaining from original deferred after previous calls</h2>
<ul id="userlist3"></ul>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/request", "dojo/_base/array", "dojo/json", "dojo/dom-construct", "dojo/dom", "dojo/domReady!"],
function(request, arrayUtil, JSON, domConstruct, dom) {
var original = request.get("users-mangled.json", {
handleAs: "json"
});
var result = original.then(function(res){
var userlist = dom.byId("userlist1");
return arrayUtil.map(res, function(user){
domConstruct.create("li", {
innerHTML: JSON.stringify(user)
}, userlist);
return {
id: user[0],
username: user[1],
name: user[2]
};
});
});
result.then(function(objs){
var userlist = dom.byId("userlist2");
arrayUtil.forEach(objs, function(user){
domConstruct.create("li", {
innerHTML: JSON.stringify(user)
}, userlist);
});
});
original.then(function(res){
var userlist = dom.byId("userlist3");
arrayUtil.forEach(res, function(user){
domConstruct.create("li", {
innerHTML: JSON.stringify(user)
}, userlist);
62
});
});
});
</script>
</body>
</html>
4. Chaining part 2
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Chaining Deferreds</title>
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body>
<h1>Demo: Chaining Deferreds</h1>
<ul id="userlist"></ul>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/request", "dojo/_base/array", "dojo/dom-construct", "dojo/dom", "dojo/domReady!"],
function(request, arrayUtil, domConstruct, dom) {
function getUserList(){
return request.get("users-mangled.json", {
handleAs: "json"
}).then(function(response){
return arrayUtil.map(response, function(user){
return {
id: user[0],
username: user[1],
name: user[2]
};
});
});
}
getUserList().then(function(users){
var userlist = dom.byId("userlist");
arrayUtil.forEach(users, function(user){
domConstruct.create("li", {
id: user.id,
innerHTML: user.username + ": " + user.name
63
}, userlist);
});
});
});
</script>
</body>
</html>
C6. Dojo Fundamentals: Dojo Deferreds and Promises
1. Deferred as a Promise
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Chaining Promises</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body>
<h1>Demo: Chaining Promises</h1>
<h2>Result from chaining from original deferred</h2>
<ul id="userlist1"></ul>
<h2>Result from chaining from resulting promise</h2>
<ul id="userlist2"></ul>
<h2>Result from chaining from original deferred after previous calls</h2>
<ul id="userlist3"></ul>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true"></script>
<script>
require([
"dojo/request",
"dojo/_base/array",
"dojo/dom",
"dojo/dom-construct",
"dojo/json",
"dojo/domReady!"
], function(request, arrayUtil, dom, domConstruct, JSON){
var original = request.get("users-mangled.json", {
handleAs: "json"
});
64
var result = original.then(function(response){
var userlist = dom.byId("userlist1");
return arrayUtil.map(response, function(user){
domConstruct.create("li", {
innerHTML: JSON.stringify(user)
}, userlist);
return {
id: user[0],
username: user[1],
name: user[2]
};
});
});
result.then(function(objs){
var userlist = dom.byId("userlist2");
arrayUtil.forEach(objs, function(user){
domConstruct.create("li", {
innerHTML: JSON.stringify(user)
}, userlist);
});
});
original.then(function(res){
var userlist = dom.byId("userlist3");
arrayUtil.forEach(res, function(user){
domConstruct.create("li", {
innerHTML: JSON.stringify(user)
}, userlist);
});
});
});
</script>
</body>
</html>
2. Dojo When part 1
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Deferred.when</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
65
</head>
<body>
<h1>Demo: Deferred.when</h1>
<ul id="userlist1"></ul>
<ul id="userlist2"></ul>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true"></script>
<script>
require([
"dojo/when",
"dojo/request",
"dojo/_base/array",
"dojo/dom",
"dojo/dom-construct",
"dojo/json",
"dojo/domReady"
], function(when, request, arrayUtil, dom, domConstruct, JSON, domReady){
var getUserList = (function(){
var users;
return function(){
if(!users){
return request.get("users-mangled.json", {
handleAs: "json"
}).then(function(response){
// Save the resulting array into the users variable
users = arrayUtil.map(response, function(user){
return {
id: user[0],
username: user[1],
name: user[2]
};
});
// Make sure to return users here,
// for valid chaining
return users;
});
}
return users;
};
})();
domReady(function(){
when(getUserList(), function(users){
// This callback will be run after the request completes
var userlist = dom.byId("userlist1");
arrayUtil.forEach(users, function(user){
domConstruct.create("li", {
innerHTML: JSON.stringify(user)
66
}, userlist);
});
when(getUserList(), function(user){
// This callback will be run right away since it's already in the cache
var userlist = dom.byId("userlist2");
arrayUtil.forEach(users, function(user){
domConstruct.create("li", {
innerHTML: JSON.stringify(user)
}, userlist);
});
});
});
});
});
</script>
</body>
</html>
3. Dojo When part 2
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: dojo/when for creation</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body>
<h1>Demo: dojo/when for creation</h1>
<h2>List 1 (from server)</h2>
<ul id="userlist1"></ul>
<h2>List 2 (from static array)</h2>
<ul id="userlist2"></ul>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true"></script>
<script>
require([
"dojo/when",
"dojo/request",
"dojo/_base/array",
"dojo/dom",
"dojo/dom-construct",
"dojo/json",
67
"dojo/domReady"
], function(when, request, arrayUtil, dom, domConstruct, JSON, domReady){
function createUserList(node, users){
var nodeRef = dom.byId(node);
return when(
users,
function(users){
arrayUtil.forEach(users, function(user){
domConstruct.create("li", {
innerHTML: JSON.stringify(user)
}, nodeRef);
});
},
function(error){
domConstruct.create("li", {
innerHTML: "Error: " + error
}, nodeRef);
}
);
}
domReady(function(){
var users = request.get("users-mangled.json", {
handleAs: "json"
}).then(function(response){
return arrayUtil.map(response, function(user){
return {
id: user[0],
username: user[1],
name: user[2]
};
});
});
createUserList("userlist1", users);
createUserList("userlist2",
[{ id: 100, username: "username100", name: "User 100" }]);
});
});
</script>
</body>
</html>
4. Dojo Promise All
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
68
<title>Demo: dojo/promise/all</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body>
<h1>Demo: dojo/promise/all</h1>
<ul id="statuslist"></ul>
<!-- load dojo and provide config via data attribute -->
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
require(["dojo/promise/all", "dojo/request", "dojo/_base/array", "dojo/dom-construct", "dojo/dom", "dojo/domReady!"],
function(all, request, arrayUtil, domConstruct, dom){
var usersDef = request.get("users.json", {
handleAs: "json"
}).then(function(response){
var users = {};
arrayUtil.forEach(response, function(user){
users[user.id] = user;
});
return users;
});
var statusesDef = request.get("statuses.json", {
handleAs: "json"
});
all([usersDef, statusesDef]).then(function(results){
var users = results[0],
statuses = results[1],
statuslist = dom.byId("statuslist");
if(!results[0] || !results[1]){
domConstruct.create("li", {
innerHTML: "An error occurred"
}, statuslist);
return;
}
arrayUtil.forEach(statuses, function(status){
var user = users[status.userId];
domConstruct.create("li", {
id: status.id,
innerHTML: user.name + ' said, "' + status.status + '"'
}, statuslist);
});
});
});
</script>
</body>
69
</html>
D1. Dojo Widgets: Charting
1. Creating a basic chart declaratively
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Basic Declarative Chart</title>
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body>
<h1>Demo: Basic Declarative Chart</h1>
<!-- create the chart -->
<div
data-dojo-type="dojox/charting/widget/Chart"
data-dojo-props="theme:dojox.charting.themes.Claro" id="viewsChart" style="width: 550px; height: 550px;">
<!-- Pie Chart: add the plot -->
<div class="plot" name="default" type="Pie" radius="200" fontColor="#000" labelOffset="-20"></div>
<!-- pieData is the data source -->
<div class="series" name="Last Week's Visits" array="chartData"></div>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
// x and y coordinates used for easy understanding of where they should display
// Data represents website visits over a week period
chartData = [
{ x: 1, y: 19021 },
{ x: 1, y: 12837 },
{ x: 1, y: 12378 },
{ x: 1, y: 21882 },
{ x: 1, y: 17654 },
{ x: 1, y: 15833 },
{ x: 1, y: 16122 }
];
require([
// Require the widget parser
"dojo/parser",
// Require the basic 2d chart resource
70
"dojox/charting/widget/Chart",
// Require the theme of our choosing
"dojox/charting/themes/Claro",
// Charting plugins:
// Require the Pie type of Plot
"dojox/charting/plot2d/Pie"
]);
</script>
</body>
</html>
2. Creating a basic chart programmatically
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Basic Programmatic Chart</title>
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body>
<h1>Demo: Basic Programmatic Chart</h1>
<!-- create the chart -->
<div id="chartNode" style="width: 550px; height: 550px;"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
// x and y coordinates used for easy understanding of where they should display
// Data represents website visits over a week period
chartData = [
{ x: 1, y: 19021 },
{ x: 1, y: 12837 },
{ x: 1, y: 12378 },
{ x: 1, y: 21882 },
{ x: 1, y: 17654 },
{ x: 1, y: 15833 },
{ x: 1, y: 16122 }
];
require([
// Require the basic 2d chart resource
"dojox/charting/Chart",
71
// Require the theme of our choosing
"dojox/charting/themes/Claro",
// Charting plugins:
// Require the Pie type of Plot
"dojox/charting/plot2d/Pie",
// Wait until the DOM is ready
"dojo/domReady!"
], function(Chart, theme, PiePlot){
// Create the chart within it's "holding" node
var pieChart = new Chart("chartNode");
// Set the theme
pieChart.setTheme(theme);
// Add the only/default plot
pieChart.addPlot("default", {
type: PiePlot, // our plot2d/Pie module reference as type value
radius: 200,
fontColor: "black",
labelOffset: -20
});
// Add the series of data
pieChart.addSeries("January",chartData);
// Render the chart!
pieChart.render();
});
</script>
</body>
</html>
3. Examples Line Chart
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Monthly Sales</title>
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body>
<h1>Demo: Monthly Sales</h1>
<div id="chartNode" style="width:800px;height:400px;"></div>
72
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require([
// Require the basic 2d chart resource
"dojox/charting/Chart",
// Require the 'Tom' theme
"dojox/charting/themes/Tom",
// Charting plugins:
// We want to plot Lines
"dojox/charting/plot2d/Lines",
// We want to use Markers
"dojox/charting/plot2d/Markers",
// We'll use default x/y axes
"dojox/charting/axis2d/Default",
// Wait until the DOM is ready
"dojo/domReady!"
], function(Chart, theme, LinesPlot){
// Define the data
var chartData = [10000,9200,11811,12000,7662,13887,14200,12222,12000,10009,11288,12099];
// Create the chart within it's "holding" node
var chart = new Chart("chartNode");
// Set the theme
chart.setTheme(theme);
// Add the only/default plot
chart.addPlot("default", {
type: LinesPlot,
markers: true
});
// Add axes
chart.addAxis("x");
chart.addAxis("y", { min: 5000, max: 15000, vertical: true, fixLower: "major", fixUpper: "major" });
// Add the series of data
chart.addSeries("Monthly Sales",chartData);
// Render the chart!
chart.render();
73
});
</script>
</body>
</html>
4. Examples Stacked Areas Chart
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Stacked Monthly Sales</title>
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body>
<h1>Demo: Stacked Monthly Sales</h1>
<div id="chartNode" style="width:800px;height:400px;"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require([
// Require the basic 2d chart resource
"dojox/charting/Chart",
// Require the theme of our choosing
"dojox/charting/themes/Dollar",
// Charting plugins:
// We want to plot StackedAreas
"dojox/charting/plot2d/StackedAreas",
// We want to use Markers
"dojox/charting/plot2d/Markers",
// We'll use default x/y axes
"dojox/charting/axis2d/Default",
// Wait until the DOM is ready
"dojo/domReady!"
], function(Chart, theme) {
// Define the data
var chartData = [10000,9200,11811,12000,7662,13887,14200,12222,12000,10009,11288,12099];
var chartData2 = [3000,12000,17733,9876,12783,12899,13888,13277,14299,12345,12345,15763];
74
// Create the chart within it's "holding" node
var chart = new Chart("chartNode");
// Set the theme
chart.setTheme(theme);
// Add the only/default plot
chart.addPlot("default", {
type: "StackedAreas",
markers: true
});
// Add axes
chart.addAxis("x");
chart.addAxis("y", { min: 5000, max: 30000, vertical: true, fixLower: "major", fixUpper: "major" });
// Add the series of data
chart.addSeries("Monthly Sales - 2010",chartData);
chart.addSeries("Monthly Sales - 2009",chartData2);
// Render the chart!
chart.render();
});
</script>
</body>
</html>
5. Examples Columns Chart
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Columns - Monthly Sales</title>
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body>
<h1>Demo: Columns - Monthly Sales</h1>
<div id="chartNode" style="width:800px;height:400px;"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require([
// Require the basic chart class
"dojox/charting/Chart",
75
// Require the theme of our choosing
"dojox/charting/themes/MiamiNice",
// Charting plugins:
// We want to plot Columns
"dojox/charting/plot2d/Columns",
// We want to use Markers
"dojox/charting/plot2d/Markers",
// We'll use default x/y axes
"dojox/charting/axis2d/Default",
// Wait until the DOM is ready
"dojo/domReady!"
], function(Chart, theme) {
// Define the data
var chartData = [10000,9200,11811,12000,7662,13887,14200,12222,12000,10009,11288,12099];
// Create the chart within it's "holding" node
var chart = new Chart("chartNode");
// Set the theme
chart.setTheme(theme);
// Add the only/default plot
chart.addPlot("default", {
type: "Columns",
markers: true,
gap: 5
});
// Add axes
chart.addAxis("x");
chart.addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major" });
// Add the series of data
chart.addSeries("Monthly Sales",chartData);
// Render the chart!
chart.render();
});
</script>
</body>
</html>
6. Charting plugins
76
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Monthly Sales with Legend, Tooltips, and Magnify</title>
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Monthly Sales with Legend, Tooltips, and Magnify</h1>
<div id="chartNode" style="width:800px;height:400px;"></div>
<div id="legend"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require([
// Require the basic chart class
"dojox/charting/Chart",
// Require the theme of our choosing
"dojox/charting/themes/Claro",
// Charting plugins:
// We want to plot Lines
"dojox/charting/plot2d/Lines",
// Load the Legend, Tooltip, and Magnify classes
"dojox/charting/widget/Legend",
"dojox/charting/action2d/Tooltip",
"dojox/charting/action2d/Magnify",
// We want to use Markers
"dojox/charting/plot2d/Markers",
// We'll use default x/y axes
"dojox/charting/axis2d/Default",
// Wait until the DOM is ready
"dojo/domReady!"
], function(Chart, theme, LinesPlot, Legend, Tooltip, Magnify) {
// Define the data
var chartData = [10000,9200,11811,12000,7662,13887,14200,12222,12000,10009,11288,12099];
var chartData2 = [3000,12000,17733,9876,12783,12899,13888,13277,14299,12345,12345,15763];
var chartData3 = [3000,12000,17733,9876,12783,12899,13888,13277,14299,12345,12345,15763].reverse();
// Create the chart within it's "holding" node
var chart = new Chart("chartNode");
77
// Set the theme
chart.setTheme(theme);
// Add the only/default plot
chart.addPlot("default", {
type: LinesPlot,
markers: true
});
// Add axes
chart.addAxis("x");
chart.addAxis("y", { min: 5000, max: 30000, vertical: true, fixLower: "major", fixUpper: "major" });
// Add the series of data
chart.addSeries("Monthly Sales - 2010",chartData);
chart.addSeries("Monthly Sales - 2009",chartData2);
chart.addSeries("Monthly Sales - 2008",chartData3);
// Create the tooltip
var tip = new Tooltip(chart,"default");
// Create the magnifier
var mag = new Magnify(chart,"default");
// Render the chart!
chart.render();
// Create the legend
var legend = new Legend({ chart: chart }, "legend");
});
</script>
</body>
</html>
7. Pie Chart with MoveSlice
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Monthly Sales Pie Chart with MoveSlice</title>
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body class="claro">
<h1>Monthly Sales Pie Chart with MoveSlice</h1>
<div id="chartNode" style="width:800px;height:400px;"></div>
<!-- load dojo and provide config via data attribute -->
78
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require([
// Require the basic chart class
"dojox/charting/Chart",
// Require the theme of our choosing
"dojox/charting/themes/Claro",
// Charting plugins:
// We want to plot a Pie chart
"dojox/charting/plot2d/Pie",
// Retrieve the Legend, Tooltip, and MoveSlice classes
"dojox/charting/action2d/Tooltip",
"dojox/charting/action2d/MoveSlice",
// We want to use Markers
"dojox/charting/plot2d/Markers",
// We'll use default x/y axes
"dojox/charting/axis2d/Default",
// Wait until the DOM is ready
"dojo/domReady!"
], function(Chart, theme, Pie, Tooltip, MoveSlice) {
// Define the data
var chartData = [10000,9200,11811,12000,7662,13887,14200,12222,12000,10009,11288,12099];
// Create the chart within it's "holding" node
var chart = new Chart("chartNode");
// Set the theme
chart.setTheme(theme);
// Add the only/default plot
chart.addPlot("default", {
type: Pie,
markers: true,
radius:170
});
// Add axes
chart.addAxis("x");
chart.addAxis("y", { min: 5000, max: 30000, vertical: true, fixLower: "major", fixUpper: "major" });
// Add the series of data
chart.addSeries("Monthly Sales - 2010",chartData);
// Create the tooltip
79
var tip = new Tooltip(chart,"default");
// Create the slice mover
var mag = new MoveSlice(chart,"default");
// Render the chart!
chart.render();
});
</script>
</body>
</html>
8. Monthly Sales with Highlights
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Columns - Monthly Sales with Highlights</title>
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body>
<h1>Demo: Columns - Monthly Sales with Highlights</h1>
<div id="chartNode" style="width:800px;height:400px;"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require([
// Require the basic chart class
"dojox/charting/Chart",
// Require the theme of our choosing
"dojox/charting/themes/MiamiNice",
// Charting plugins:
// We want to plot Columns
"dojox/charting/plot2d/Columns",
// Require the highlighter
"dojox/charting/action2d/Highlight",
// We want to use Markers
"dojox/charting/plot2d/Markers",
// We'll use default x/y axes
80
"dojox/charting/axis2d/Default",
// Wait until the DOM is ready
"dojo/domReady!"
], function(Chart, theme, ColumnsPlot, Highlight) {
// Define the data
var chartData = [10000,9200,11811,12000,7662,13887,14200,12222,12000,10009,11288,12099];
// Create the chart within it's "holding" node
var chart = new Chart("chartNode");
// Set the theme
chart.setTheme(theme);
// Add the only/default plot
chart.addPlot("default", {
type: ColumnsPlot,
markers: true,
gap: 5
});
// Add axes
chart.addAxis("x");
chart.addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major" });
// Add the series of data
chart.addSeries("Monthly Sales",chartData);
// Highlight!
new Highlight(chart,"default");
// Render the chart!
chart.render();
});
</script>
</body>
</html>
D2. Dojo Widgets: Checkboxes
1. Declare a checkbox
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo: Dijit CheckBox</title>
81
<link rel="stylesheet" href="demo.css">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
</head>
<body class="claro">
<h2>dijit.form.CheckBox</h2>
<div>
<h3>Declarative Checkboxes</h3>
<p>
<input type="checkbox" id="dbox1" checked
data-dojo-type="dijit/form/CheckBox">
<label for="dbox1">Want</label>
</p>
<p>
<input type="checkbox" id="dbox2"
data-dojo-type="dijit/form/CheckBox">
<label for="dbox2">Need</label>
</p>
<p>
<input type="checkbox" id="dbox3" checked disabled
data-dojo-type="dijit/form/CheckBox">
<label for="dbox3">Disabled option</label>
</p>
</div>
<h3>Programmatic Checkboxes</h3>
<div>
<p id="pbox1_container">
<label for="pbox1">Want</label>
</p>
<p id="pbox2_container">
<label for="pbox2">Need</label>
</p>
<p id="pbox3_container">
<label for="pbox3">Disabled option</label>
</p>
</div>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dijit/form/CheckBox", "dojo/parser", "dojo/domReady!"], function(CheckBox, parser) {
parser.parse();
var box1 = new CheckBox({
id: "pbox1",
82
checked: true
});
// place the widget on the page
box1.placeAt("pbox1_container", "first");
var box2 = new CheckBox({
id: "pbox2"
});
box2.placeAt("pbox2_container", "first");
var box3 = new CheckBox({
id: "pbox3",
checked: true,
disabled: true
});
box3.placeAt("pbox3_container", "first");
});
</script>
</body>
</html>
2. Checkbox Values
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo: Dijit CheckBox Getter/Setters</title>
<link rel="stylesheet" href="demo.css">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
</head>
<body class="claro">
<h2>dijit/form/CheckBox value setters</h2>
<div>
<h3>Pizza Toppings</h3>
<ul style="list-style-type: none">
<li>
<input id="topping1" type="checkbox" value="anchovies" checked
data-dojo-type="dijit/form/CheckBox">
<label for="topping1">Anchovies</label>
</li>
<li>
<input id="topping2" type="checkbox" value="olives"
data-dojo-type="dijit/form/CheckBox">
<label for="topping2">Olives</label>
</li>
</ul>
<p>
83
<input id="deluxe" type="checkbox" value="deluxe"
data-dojo-type="dijit/form/CheckBox">
<label for="deluxe">Go Deluxe?</label>
</p>
<button id="summaryBtn">Which Toppings?</button>
</div>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dijit/form/CheckBox", "dojo/on", "dijit/registry", "dojo/parser", "dojo/domReady!"], function(CheckBox, on, registry,
parser){
parser.parse();
on(document.getElementById("summaryBtn"), "click", function(evt){
var toppings = [];
if(registry.byId("topping1").get("checked")){
toppings.push(registry.byId("topping1").get("value"));
}
if(registry.byId("topping2").get("value") !== false){
toppings.push(registry.byId("topping2").get("value"));
}
alert("Toppings: " + toppings.join(", "));
}, true);
registry.byId("deluxe").on("change", function(isChecked){
registry.byId("topping2").set("value", isChecked ? "kalamata olives" : "olives");
}, true);
});
</script>
</body>
</html>
3. Radio Buttons
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo: Dijit RadioButton</title>
<link rel="stylesheet" href="demo.css">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
</head>
<body class="claro">
<h2>dijit/form/RadioButton value setters</h2>
<h3>Pizza Toppings</h3>
<ul style="list-style-type: none">
84
<li>
<input id="topping1" type="radio" name="topping" value="anchovies" checked
data-dojo-type="dijit/form/RadioButton">
<label for="topping1">Anchovies</label>
</li>
<li>
<input id="topping2" type="radio" name="topping" value="olives"
data-dojo-type="dijit/form/RadioButton">
<label for="topping2">Olives</label>
</li>
<li>
<input id="topping3" type="radio" name="topping" value="pineapple"
data-dojo-type="dijit/form/RadioButton">
<label for="topping3">Pineapple</label>
</li>
</ul>
<button id="summaryBtn">Which Toppings?</button>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dijit/form/RadioButton", "dojo/on", "dijit/registry", "dojo/parser", "dojo/domReady!"], function(RadioButton, on,
registry, parser){
parser.parse();
on(document.getElementById("summaryBtn"), "click", function(evt){
var toppings = [];
if(registry.byId("topping1").get("checked")){
toppings.push(registry.byId("topping1").get("value"));
}
if(registry.byId("topping2").get("checked")){
toppings.push(registry.byId("topping2").get("value"));
}
if(registry.byId("topping3").get("checked")) {
toppings.push(registry.byId("topping3").get("value"));
}
alert("Topping: " + toppings.join(", "));
});
});
</script>
</body>
</html>
4. Events
<!DOCTYPE html>
<html>
85
<head>
<meta charset="utf-8">
<title>Demo: Dijit CheckBox/RadioButton onChange</title>
<link rel="stylesheet" href="demo.css">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
</head>
<body class="claro">
<h2>Using onChange</h2>
<h3>Pizza Toppings</h3>
<ul style="list-style-type: none">
<li>
<input id="topping1" name="topping" type="radio" value="anchovies" checked
data-dojo-type="dijit/form/RadioButton">
<label for="topping1">Anchovies</label>
</li>
<li>
<input id="topping2" name="topping" type="radio" value="pineapple"
data-dojo-type="dijit/form/RadioButton">
<label for="topping2">Pineapple</label>
</li>
</ul>
<div id="toppingNote">Likes the salty!</div>
<h3>Crust</h3>
<p>
<input id="crust" name="crust" type="checkbox" value="thick"
data-dojo-type="dijit/form/CheckBox">
<label for="crust">Thick Crust</label>
</p>
<div id="crustNote"></div>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dijit/form/RadioButton", "dijit/registry", "dojo/parser", "dojo/domReady!"], function(RadioButton, registry, parser){
parser.parse();
var summaryNode = document.getElementById("toppingNote"),
remarkNode = document.getElementById("crustNote");
registry.byId("topping1").on("change", function(isChecked){
if(isChecked){
summaryNode.innerHTML = "Likes the salty!";
}
}, true);
registry.byId("topping2").on("change", function(isChecked){
if(isChecked){
summaryNode.innerHTML = "Likes the sweet!";
}
}, true);
86
registry.byId("crust").on("change", function(isChecked){
remarkNode.innerHTML = isChecked ? "Healthy gums!" : "";
}, true);
});
</script>
</body>
</html>
5. ToggleButton
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo: Dijit ToggleButton</title>
<link rel="stylesheet" href="demo.css">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
</head>
<body class="claro">
<h3>dijit/form/ToggleButton</h3>
<h4>Declaration Using Markup</h4>
<input type="checkbox" checked
data-dojo-type="dijit/form/ToggleButton"
data-dojo-props="iconClass: 'dijitCheckBoxIcon', label: 'Toggle Me'">
<h4>Programmatic Declaration</h4>
<div id="toggleButtonProgrammatic"></div>
<input type="button" value="Change label" id="changeLabel">
<input type="button" value="Change icon" id="changeIcon">
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dijit/form/RadioButton", "dijit/form/ToggleButton", "dojo/on", "dijit/registry", "dojo/parser", "dojo/domReady!"],
function(RadioButton, ToggleButton, on, registry, parser){
parser.parse();
var myToggleButton = new ToggleButton({
checked: true,
iconClass: "dijitCheckBoxIcon",
label: "Toggle Me, Too."
},"toggleButtonProgrammatic");
on(document.getElementById("changeLabel"), "click", function(){
// provide a new label for the button
myToggleButton.set("label", "New Label");
});
on(document.getElementById("changeIcon"), "click", function(){
// hook a .recent rule in our stylesheet
87
myToggleButton.set("iconClass", "dijitRadioIcon");
});
});
</script>
</body>
</html>
D3. Dojo Widgets: Dialogs & Tooltips
1. Declarative (HTML) Tooltip Creation
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Mixed Tooltip Usages</title>
<style>
.rodTip { background:lightblue; border-bottom:1px dotted blue; cursor:help; padding:2px; display:inline-block; }
.customTip { background:pink; }
</style>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Mixed Tooltip Usages</h1>
<h2>Tooltip on a dijit/form/Button (Declarative)</h2>
<button id="tooltipButton" onmouseover="dijit.Tooltip.defaultPosition=['above', 'below']">Tooltip Above</button>
<div class="dijitHidden"><span data-dojo-type="dijit/Tooltip" data-dojo-props="connectId:'tooltipButton'">I am <strong>above</strong> the
button</span></div>
<button id="tooltipButton2" onmouseover="dijit.Tooltip.defaultPosition=['below','above']">Tooltip Below</button>
<div class="dijitHidden"><span data-dojo-type="dijit/Tooltip" data-dojo-props="connectId:'tooltipButton2'">I am <strong>below</strong> the
button</span></div>
<button id="tooltipButton3" onmouseover="dijit.Tooltip.defaultPosition=['after-centered','before-centered']">Tooltip After</button>
<div class="dijitHidden"><span data-dojo-type="dijit/Tooltip" data-dojo-props="connectId:'tooltipButton3'">I am <strong>after</strong> the
button</span></div>
<button id="tooltipButton4" onmouseover="dijit.Tooltip.defaultPosition=['before-centered','after-centered']">Tooltip Before</button>
<div class="dijitHidden"><span data-dojo-type="dijit/Tooltip" data-dojo-props="connectId:'tooltipButton4'">I am <strong>before</strong> the
button</span></div>
<br /><br />
<h2>Tooltip on Text in Paragraph (Programmatic)</h2>
<p>
<span id="nameTip" class="rodTip">Roderick David "Rod" Stewart</span>, CBE (born 10 January 1945) is a British singer-songwriter and musician,
born and raised in <span id="londonTip" class="rodTip">North London, England</span> and currently residing in Epping. He is of Scottish and English
lineage.
88
</p>
<p>
With his career in its fifth decade, Stewart has sold <span id="recordsTip" class="rodTip">over 100 million records worldwide</span>, making
him one of the best selling artists of all time. In the UK, he has garnered six consecutive number one albums, and his tally of 62 hit singles
include 31 that reached the top 10, six of which gained the number one position. He has had 16 top ten singles in the U.S, with four of these
reaching number one on the Billboard Hot 100. In 2008, Billboard magazine ranked him the 17th most successful artist on the "The Billboard Hot 100
Top All-Time Artists". He was voted at #33 in Q Magazine's list of the top 100 Greatest Singers of all time. In 1994, Stewart was inducted into the
Rock and Roll Hall of Fame.
</p>
<!-- load dojo and provide config via data attribute -->
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
// Require the Tooltip class
require(["dijit/Tooltip", "dojo/parser", "dojo/domReady!"], function(Tooltip, parser){
parser.parse();
// Add tooltip of his picture
new Tooltip({
connectId: ["nameTip"],
label: "<img src='../images/rod-stewart.jpg' alt='Rod Stewart' width='300' height='404' />"
});
// Add tooltip of North London
new Tooltip({
connectId: ["londonTip"],
label: "<img src='../images/emirates-stadium.jpg' alt='The Emirates in London' width='400' height='267' />"
});
//Add tooltip of record
new Tooltip({
connectId: ["recordsTip"],
label: "<img src='../images/every-picture.jpg' alt='Every Picture Tells a Story' width='200' height='197' />"
});
// Add custom tooltip
var myTip = new Tooltip({
connectId: ["hoverLink"],
label: "Don't I look funky?",
"class": "customTip"
});
});
</script>
</body>
</html>
2. Programatic Tooltip Creation
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
89
<title>Demo: Mixed Tooltip Usages</title>
<style>
.rodTip { background:lightblue; border-bottom:1px dotted blue; cursor:help; padding:2px; display:inline-block; }
.customTip { background:pink; }
</style>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Mixed Tooltip Usages</h1>
<h2>Tooltip on a dijit/form/Button (Declarative)</h2>
<button id="tooltipButton" onmouseover="dijit.Tooltip.defaultPosition=['above', 'below']">Tooltip Above</button>
<div class="dijitHidden"><span data-dojo-type="dijit/Tooltip" data-dojo-props="connectId:'tooltipButton'">I am <strong>above</strong> the
button</span></div>
<button id="tooltipButton2" onmouseover="dijit.Tooltip.defaultPosition=['below','above']">Tooltip Below</button>
<div class="dijitHidden"><span data-dojo-type="dijit/Tooltip" data-dojo-props="connectId:'tooltipButton2'">I am <strong>below</strong> the
button</span></div>
<button id="tooltipButton3" onmouseover="dijit.Tooltip.defaultPosition=['after-centered','before-centered']">Tooltip After</button>
<div class="dijitHidden"><span data-dojo-type="dijit/Tooltip" data-dojo-props="connectId:'tooltipButton3'">I am <strong>after</strong> the
button</span></div>
<button id="tooltipButton4" onmouseover="dijit.Tooltip.defaultPosition=['before-centered','after-centered']">Tooltip Before</button>
<div class="dijitHidden"><span data-dojo-type="dijit/Tooltip" data-dojo-props="connectId:'tooltipButton4'">I am <strong>before</strong> the
button</span></div>
<br /><br />
<h2>Tooltip on Text in Paragraph (Programmatic)</h2>
<p>
<span id="nameTip" class="rodTip">Roderick David "Rod" Stewart</span>, CBE (born 10 January 1945) is a British singer-songwriter and musician,
born and raised in <span id="londonTip" class="rodTip">North London, England</span> and currently residing in Epping. He is of Scottish and English
lineage.
</p>
<p>
With his career in its fifth decade, Stewart has sold <span id="recordsTip" class="rodTip">over 100 million records worldwide</span>, making
him one of the best selling artists of all time. In the UK, he has garnered six consecutive number one albums, and his tally of 62 hit singles
include 31 that reached the top 10, six of which gained the number one position. He has had 16 top ten singles in the U.S, with four of these
reaching number one on the Billboard Hot 100. In 2008, Billboard magazine ranked him the 17th most successful artist on the "The Billboard Hot 100
Top All-Time Artists". He was voted at #33 in Q Magazine's list of the top 100 Greatest Singers of all time. In 1994, Stewart was inducted into the
Rock and Roll Hall of Fame.
</p>
<!-- load dojo and provide config via data attribute -->
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
// Require the Tooltip class
require(["dijit/Tooltip", "dojo/parser", "dojo/domReady!"], function(Tooltip, parser){
parser.parse();
// Add tooltip of his picture
90
new Tooltip({
connectId: ["nameTip"],
label: "<img src='../images/rod-stewart.jpg' alt='Rod Stewart' width='300' height='404' />"
});
// Add tooltip of North London
new Tooltip({
connectId: ["londonTip"],
label: "<img src='../images/emirates-stadium.jpg' alt='The Emirates in London' width='400' height='267' />"
});
//Add tooltip of record
new Tooltip({
connectId: ["recordsTip"],
label: "<img src='../images/every-picture.jpg' alt='Every Picture Tells a Story' width='200' height='197' />"
});
// Add custom tooltip
var myTip = new Tooltip({
connectId: ["hoverLink"],
label: "Don't I look funky?",
"class": "customTip"
});
});
</script>
</body>
</html>
3. Product Details
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Product Details</title>
<style>
p { padding:0; margin:0; }
</style>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Product Details</h1>
<h2>My Favorite Movies</h2>
<ul>
<li><a href="http://www.imdb.com/title/tt0112573/" id="movieBraveheart">Braveheart</a></li>
<li><a href="http://www.imdb.com/title/tt0237534/" id="movieBrotherhood">Brotherhood of the Wolf</a></li>
<li><a href="http://www.imdb.com/title/tt0245844/" id="movieCristo">The Count of Monte Cristo</a></li>
</ul>
<div class="dijitHidden">
<div data-dojo-type="dijit/Tooltip" data-dojo-props="connectId:'movieBraveheart'">
<img style="width:100px; height:133px; display:block; float:left; margin-right:10px;" src="../images/braveheart.jpg" />
91
<p style="width:400px;"><strong>Braveheart</strong><br />Braveheart is the partly historical, partly mythological, story of William
Wallace, a Scottish common man who fights for his country's freedom from English rule around the end of the 13th century...</p>
<br style="clear:both;">
</div>
</div>
<div class="dijitHidden">
<div data-dojo-type="dijit/Tooltip" data-dojo-props="connectId:'movieBrotherhood'">
<img style="width:100px; height:133px; display:block; float:left; margin-right:10px;" src="../images/brotherhood.jpg" />
<p style="width:400px;"><strong>Brotherhood of the Wolf</strong><br />In 1765 something was stalking the mountains of central France.
A 'beast' that pounced on humans and animals with terrible ferocity...</p>
<br style="clear:both;">
</div>
</div>
<div class="dijitHidden">
<div data-dojo-type="dijit/Tooltip" data-dojo-props="connectId:'movieCristo'">
<img style="width:100px; height:133px; display:block; float:left; margin-right:10px;" src="../images/count.jpg" />
<p style="width:400px;"><strong>The Count of Monte Cristo</strong><br />'The Count of Monte Cristo' is a remake of the Alexander Dumas
tale by the same name. Dantes, a sailor who is falsely accused of treason by his best friend Fernand, who wants Dantes' girlfriend Mercedes for
himself...</p>
<br style="clear:both;">
</div>
</div>
<!-- load dojo and provide config via data attribute -->
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
// Require the Tooltip Class
require(["dijit/Tooltip", "dojo/parser", "dojo/domReady!"], function(Tooltip, parser){
// Change the tooltip positions
Tooltip.defaultPosition = ["after-centered","below"];
parser.parse();
});
</script>
</body>
</html>
4. Dialog Examples, Terms and Conditions
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Terms and Conditions</title>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
92
<body class="claro">
<h1>Demo: Terms and Conditions</h1>
<button type="button" data-dojo-type="dijit/form/Button" data-dojo-props="onClick:showDialog">View Terms and Conditions</button>
<div class="dijitHidden">
<div data-dojo-type="dijit/Dialog" style="width:600px;" data-dojo-props="title:'Terms and Conditions'" id="terms">
<p><strong>Please agree to the following terms and conditions:</strong></p>
<div style="height:160px;overflow-y:scroll;border:1px solid #769dc4;padding:0 10px;width:560px;"><p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed sed suscipit massa. Aenean vel turpis tincidunt velit gravida
venenatis. In iaculis urna non quam tincidunt elementum. Nunc pellentesque aliquam dui, ac facilisis massa sollicitudin et. Donec tincidunt vulputate
ultrices. Duis eu risus ut ipsum auctor scelerisque non quis ante. Nam tempor lobortis justo, et rhoncus mauris cursus et. Mauris auctor congue
lectus auctor ultrices. Aenean quis feugiat purus. Cras ornare vehicula tempus. Nunc placerat, lorem adipiscing condimentum sagittis, augue velit
ornare odio, eget semper risus est et erat.
</p>
<p>
Donec odio enim, aliquam eu facilisis eu, venenatis sit amet felis. Etiam pharetra arcu ut augue tincidunt convallis.
Fusce malesuada mauris massa, a porttitor lorem. Nullam risus erat, bibendum ut sodales at, scelerisque ut odio. Mauris viverra ultricies mi, eu
congue risus hendrerit id. Praesent magna leo, egestas eget ullamcorper a, auctor nec nunc. Cum sociis natoque penatibus et magnis dis parturient
montes, nascetur ridiculus mus. Sed nec nisl eget enim bibendum gravida sed ac est. Aliquam volutpat elementum urna ut malesuada. Mauris faucibus
tincidunt odio ac venenatis. Quisque eleifend sem nec dui gravida nec feugiat libero interdum. Quisque ultricies nisi non arcu lobortis fringilla.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi porttitor, justo vel suscipit lobortis, enim odio
tincidunt nunc, non pharetra lacus dolor a nisl. Vivamus porta venenatis libero vitae commodo.
</p>
<p>
Cras lacinia imperdiet mi, pretium interdum ante pellentesque et. Quisque commodo metus at velit feugiat fringilla
interdum eros ornare. Praesent varius libero quis quam vehicula dapibus. Nam commodo tristique ipsum quis sagittis. In hac habitasse platea dictumst.
Morbi eget leo sit amet erat placerat fermentum eu a nunc. Ut scelerisque justo eu odio placerat lobortis. In ultrices sapien ut mauris pharetra
varius. Fusce tempus accumsan orci, ac gravida libero venenatis sit amet. Curabitur malesuada vulputate iaculis.
</p>
<p>
Nullam metus nulla, viverra sit amet aliquet a, dignissim a eros. Nunc cursus, sapien vel vestibulum aliquet, magna
nibh rutrum nulla, sed condimentum nunc mauris at ante. Cras ornare turpis adipiscing massa ultricies a tempus lorem hendrerit. Pellentesque habitant
morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec laoreet ipsum tincidunt mi pellentesque sit amet mollis tortor tempus.
Maecenas at purus ac odio sollicitudin congue a non augue. Aliquam eleifend porttitor fermentum. Curabitur non justo ipsum. Duis lectus felis,
fermentum sed aliquet interdum, eleifend sit amet leo. Vivamus magna diam, suscipit nec fringilla sit amet, ultrices vitae dui. Cras ut justo non
velit mollis blandit.
</p>
<p>
Pellentesque molestie consequat nisi ac interdum. Pellentesque augue quam, viverra sodales vestibulum eget, aliquam id
quam. Suspendisse sed mauris augue, at tempus tortor. Quisque tincidunt metus eu turpis condimentum a fringilla leo sagittis. Integer ac felis nunc.
Vivamus eu dictum sem. Vestibulum quis ligula sed elit semper hendrerit id ac enim. Curabitur convallis cursus mauris nec pulvinar. Fusce semper
risus a ante pretium elementum. Donec tellus metus, iaculis in suscipit at, venenatis non mauris. Sed nec justo sed nulla ornare hendrerit vitae
pharetra magna. Quisque eu felis felis, et venenatis odio.
</p></div>
<br>
<button type="button" data-dojo-type="dijit/form/Button" data-dojo-props="onClick:hideDialog">I Agree</button>
<button type="button" data-dojo-type="dijit/form/Button" data-dojo-props="onClick:doAlert">I Don't Agree</button>
</div>
</div>
<!-- load dojo and provide config via data attribute -->
93
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
// Require the Dialog class
require(["dijit/registry", "dojo/parser", "dijit/Dialog", "dijit/form/Button", "dojo/domReady!"], function(registry, parser){
// Show the dialog
window.showDialog = function() {
registry.byId("terms").show();
};
// Hide the dialog
window.hideDialog = function() {
registry.byId("terms").hide();
};
// Force them to provide an answer
window.doAlert = function() {
alert("You must agree!");
};
parser.parse();
});
</script>
</body>
</html>
5. Dialog Examples, Stacked Dialogs
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Stacked Dialogs</title>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Stacked Dialogs</h1>
<button onclick="createDialog(true);">Create New Dialog</button>
<!-- load dojo and provide config via data attribute -->
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
// Require the Dialog class
require(["dijit/Dialog"], function(Dialog){
// Create counter
var counter = 1;
// Create a new Dialog
window.createDialog = function(first) {
94
// Create a new dialog
var dialog = new Dialog({
// Dialog title
title: "New Dialog " + counter,
// Create Dialog content
content: (!first ? "I am a dialog on top of other dialogs" : "I am the bottom dialog") + "<br /><br /><button
onclick='createDialog();'>Create another dialog.</button>"
});
dialog.show();
counter++;
}
});
</script>
</body>
</html>
6. Dialog Examples, Ajax Dialogs with Black Underlay
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Ajax Dialog with Black Underlay</title>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<style>
/* colors the underlay black instead of white
* We're using '.claro .dijitDialogUnderlay' as our selector,
* to match the specificity in claro.css */
.claro .dijitDialogUnderlay { background:#000; }
</style>
</head>
<body class="claro">
<h1>Demo: Ajax Dialog with Black Underlay</h1>
<p>Click the button below to show a dialog which loads its content via Ajax.</p>
<button onclick="showDialog();">Load Ajax Dialog</button>
<div class="dijitHidden">
<div data-dojo-type="dijit/Dialog" style="width:600px;" data-dojo-props="title:'Ajax Dialog',href:'dialog-ajax-
content.html',loadingMessage:'Loading dialog content...'" id="ajaxDialog"></div>
</div>
<!-- load dojo and provide config via data attribute -->
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
// Require the Dialog class
require(["dijit/registry", "dojo/parser", "dijit/Dialog", "dojo/domReady!"], function(registry, parser){
95
// Show the dialog
showDialog = function() {
registry.byId("ajaxDialog").show();
}
// Hide the dialog
hideDialog = function() {
registry.byId("ajaxDialog").hide();
}
parser.parse();
});
</script>
</body>
</html>
7. TooltipDialog Example, Button Dropdown
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Button Dropdown</title>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Button Dropdown</h1>
<p>Please log into your account.</p>
<div data-dojo-type="dijit/form/DropDownButton">
<span>Login</span><!-- Text for the button -->
<!-- The dialog portion -->
<div data-dojo-type="dijit/TooltipDialog" id="ttDialog">
<strong><label for="email" style="display:inline-block;width:100px;">Email:</label></strong>
<div data-dojo-type="dijit/form/TextBox" id="email"></div>
<br />
<strong><label for="pass" style="display:inline-block;width:100px;">Password:</label></strong>
<div data-dojo-type="dijit/form/TextBox" id="pass"></div>
<br />
<button data-dojo-type="dijit/form/Button" data-dojo-props="onClick:doAlert" type="submit">Submit</button>
</div>
</div>
<!-- load dojo and provide config via data attribute -->
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
// Require the Button, TooltipDialog, DropDownButton, and TextBox classes
require(["dojo/parser", "dijit/form/Button", "dijit/form/DropDownButton", "dijit/TooltipDialog", "dijit/form/TextBox", "dojo/domReady!"],
function(parser){
// Alerter
96
parser.parse();
});
function doAlert() {
alert('Logging in!');
}
</script>
</body>
</html>
D4. Dojo Widgets: Layout with Dijit
1. Getting Started
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: NodeList Extensions: dojo/query Recap</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: NodeList Extensions: dojo/query Recap</h1>
<button type="button" id="btn">Pick out fresh fruits</button>
<h3>Fresh Fruits</h3>
<ul id="freshList"></ul>
<h3>Fruits</h3>
<ul>
<li class="fresh">Apples</li>
<li class="fresh">Persimmons</li>
<li class="fresh">Grapes</li>
<li class="fresh">Fresh Figs</li>
<li class="dried">Dates</li>
<li class="dried">Raisins</li>
<li class="dried">Prunes</li>
<li class="fresh dried">Apricots</li>
<li class="fresh">Peaches</li>
<li class="fresh">Bananas</li>
<li class="fresh">Cherries</li>
</ul>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
require(["dojo/query", "dojo/domReady!"], function(query){
query("#btn").on("click", function(){
97
query("li.fresh").on("click", function(event){
log("I love fresh " + event.target.innerHTML);
});
});
function log(msg){
var c = document.getElementById("console");
if(!c){
c = document.createElement("div");
c.setAttribute("id", "console");
document.body.appendChild(c);
}
c.innerHTML += "<div>" + msg + "</div>";
}
});
</script>
</body>
</html>
2. Adding Widgets
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: BorderContainer</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<div id="appLayout" class="demoLayout" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design: 'headline'">
<div class="centerPanel" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region: 'center'">
<div>
<h4>Group 1 Content</h4>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.</p>
</div>
<div>
<h4>Group 2 Content</h4>
</div>
<div>
<h4>Group 3 Content</h4>
</div>
</div>
<div class="edgePanel" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region: 'top'">Header content (top)</div>
<div id="leftCol" class="edgePanel" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region: 'left', splitter: true">Sidebar content
(left)</div>
98
</div>
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
require(["dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dojo/domReady!"], function(parser){
parser.parse();
});
</script>
</body>
</html>
3. BorderContainer
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Nested BorderContainer</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<div class="demoLayout" style="height: 300px; width: 300px" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design: 'headline'">
<div class="centerPanel" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region: 'center'">center</div>
<div class="demoLayout" style="height: 50%" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="region: 'top', splitter: true,
design: 'headline'">
<div class="centerPanel" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region: 'center'">center</div>
<div class="edgePanel" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region: 'bottom'">bottom</div>
</div>
<div class="edgePanel" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="splitter: true, region: 'left'">left</div>
<div class="demoLayout" style="width: 50%" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="region: 'right', design:
'headline'">
<div class="centerPanel" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region: 'center'">center</div>
<div class="edgePanel" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region: 'left'">left</div>
</div>
<div class="edgePanel" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="splitter: true, region: 'bottom'">bottom</div>
</div>
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
require(["dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dojo/domReady!"], function(parser){
parser.parse();
});
</script>
</body>
</html>
99
4. Making the Tabs
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Layout with Dijit</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<div id="appLayout" class="demoLayout" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design: 'headline'">
<div class="centerPanel" data-dojo-type="dijit/layout/TabContainer" data-dojo-props="region: 'center', tabPosition: 'bottom'">
<div data-dojo-type="dijit/layout/ContentPane" title="Group 1">
<h4>Group 1 Content</h4>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex
ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit
anim id est laborum.</p>
</div>
<div data-dojo-type="dijit/layout/ContentPane" title="Group Two">
<h4>Group 2 Content</h4>
</div>
<div data-dojo-type="dijit/layout/ContentPane" title="Long Tab Label for this One">
<h4>Group 3 Content</h4>
</div>
</div>
<div class="edgePanel" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region: 'top'">Header content (top)</div>
<div id="leftCol" class="edgePanel" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region: 'left', splitter: true">Sidebar content
(left)</div>
</div>
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
require(["dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/TabContainer", "dijit/layout/ContentPane", "dojo/domReady!"],
function(parser){
parser.parse();
});
</script>
</body>
</html>
5. Startup and Resize part 1
<!DOCTYPE HTML>
100
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Progammatic Layout</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<div id="appLayout" class="demoLayout"></div>
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
require(["dijit/layout/BorderContainer", "dijit/layout/TabContainer", "dijit/layout/ContentPane", "dojo/domReady!"],
function(BorderContainer, TabContainer,ContentPane){
// create the BorderContainer and attach it to our appLayout div
var appLayout = new BorderContainer({
design: "headline"
}, "appLayout");
// create the TabContainer
var contentTabs = new TabContainer({
region: "center",
id: "contentTabs",
tabPosition: "bottom",
"class": "centerPanel"
});
// add the TabContainer as a child of the BorderContainer
appLayout.addChild( contentTabs );
// create and add the BorderContainer edge regions
appLayout.addChild(
new ContentPane({
region: "top",
"class": "edgePanel",
content: "Header content (top)"
})
);
appLayout.addChild(
new ContentPane({
region: "left",
id: "leftCol", "class": "edgePanel",
content: "Sidebar content (left)",
splitter: true
})
);
// Add initial content to the TabContainer
contentTabs.addChild(
new ContentPane({
href: "contentGroup1.html",
101
title: "Group 1"
})
);
// start up and do layout
appLayout.startup();
});
</script>
</body>
</html>
6. Startup and Resize part 2
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Layout with Dijit</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<div id="appLayout" class="demoLayout" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design: 'headline'">
<div class="centerPanel" data-dojo-type="dijit/layout/TabContainer" data-dojo-props="region: 'center', tabPosition: 'bottom'">
<div data-dojo-type="dijit/layout/ContentPane" title="Group 1">
<h4>Group 1 Content</h4>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex
ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit
anim id est laborum.</p>
</div>
<div data-dojo-type="dijit/layout/ContentPane" title="Group Two">
<h4>Group 2 Content</h4>
</div>
<div data-dojo-type="dijit/layout/ContentPane" title="Long Tab Label for this One">
<h4>Group 3 Content</h4>
</div>
</div>
<div class="edgePanel" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region: 'top'">Header content (top)</div>
<div id="leftCol" class="edgePanel" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region: 'left', splitter: true">Sidebar content
(left)</div>
</div>
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
require(["dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/TabContainer", "dijit/layout/ContentPane", "dojo/domReady!"],
function(parser){
parser.parse();
102
});
</script>
</body>
</html>
D5. Dojo Widgets: Dijit Editor
1. Implementing dijit part 1
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Basic Editor</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Basic Editor</h1>
<p>The following is the default editor, no special settings or plugins.</p>
<div data-dojo-type="dijit/Editor"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true,parseOnLoad: true"></script>
<script>
// Include the class
require(["dijit/Editor", "dojo/parser"]);
</script>
</body>
</html>
2. Implementing dijit part 2
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Custom Editor</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Custom Editor</h1>
<p>The following Editor instance allows only a select few tools:</p>
103
<div data-dojo-type="dijit/Editor" style="width:700px;min-height:100px;" data-dojo-
props="plugins:['bold','italic','|','cut','copy','paste','|','insertUnorderedList']"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true,parseOnLoad: true"></script>
<script>
// Include the class
require(["dijit/Editor", "dojo/parser"]);
</script>
</body>
</html>
3. Implementing dijit part 3
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Programmatic Editor</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Programmatic Editor</h1>
<p>The following Editor instance allows only a select few tools, and is created programmatically:</p>
<div style="width:700px;min-height:100px;" id="myEditor"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true"></script>
<!-- Notice that there's no parseOnLoad -->
<script>
// Include the class
require(["dijit/Editor", "dojo/domReady!"], function(Editor){
// Make our editor
var editor = new Editor({
plugins: ["bold","italic","|","cut","copy","paste","|","insertUnorderedList"]
}, "myEditor");
editor.startup();
});
</script>
</body>
</html>
4. Using Plugins
<!DOCTYPE HTML>
104
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Additional Dijit Plugins</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Additional Dijit Plugins</h1>
<div data-dojo-type="dijit/Editor" style="width:800px;min-height:100px;" data-dojo-
props="extraPlugins:['foreColor','hiliteColor','|','createLink','insertImage','fullscreen','viewsource','newpage']">
This is the <strong>default</strong> content.
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true,parseOnLoad: true"></script>
<script>
// Include the class
require(["dijit/Editor", "dojo/parser", "dijit/_editor/plugins/TextColor", "dijit/_editor/plugins/LinkDialog",
"dijit/_editor/plugins/FullScreen", "dijit/_editor/plugins/ViewSource", "dijit/_editor/plugins/NewPage"]);
</script>
</body>
</html>
5. Using Plugins part 2
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Additional DojoX Plugins</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/editor/plugins/resources/editorPlugins.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/editor/plugins/resources/css/PageBreak.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/editor/plugins/resources/css/ShowBlockNodes.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/editor/plugins/resources/css/Preview.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/editor/plugins/resources/css/Save.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/editor/plugins/resources/css/Breadcrumb.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/editor/plugins/resources/css/FindReplace.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/editor/plugins/resources/css/PasteFromWord.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/editor/plugins/resources/css/InsertAnchor.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/editor/plugins/resources/css/CollapsibleToolbar.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/editor/plugins/resources/css/Blockquote.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/editor/plugins/resources/css/Smiley.css" />
</head>
<body class="claro">
<h1>Demo: Additional DojoX Plugins</h1>
105
<div data-dojo-type="dijit/Editor" style="width:800px;min-height:100px;" data-dojo-
props="extraPlugins:['prettyprint','pagebreak','showblocknodes','preview','save','toolbarlinebreak','normalizeindentoutdent','breadcrumb','findreplac
e','pastefromword','insertanchor','collapsibletoolbar','foreColor', 'hiliteColor','blockquote','smiley','uploadImage']">
This is the <strong>default</strong> content.
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true,parseOnLoad: true"></script>
<script>
// Include the class
require(["dijit/Editor", "dojo/parser",
"dojox/editor/plugins/PrettyPrint",
"dojox/editor/plugins/PageBreak",
"dojox/editor/plugins/ShowBlockNodes",
"dojox/editor/plugins/Preview",
"dojox/editor/plugins/Save",
"dojox/editor/plugins/ToolbarLineBreak",
"dojox/editor/plugins/NormalizeIndentOutdent",
"dojox/editor/plugins/Breadcrumb",
"dojox/editor/plugins/FindReplace",
"dojox/editor/plugins/PasteFromWord",
"dojox/editor/plugins/InsertAnchor",
"dojox/editor/plugins/CollapsibleToolbar",
"dojox/editor/plugins/TextColor",
"dojox/editor/plugins/Blockquote",
"dojox/editor/plugins/Smiley",
"dojox/editor/plugins/UploadImage"]);
</script>
</body>
</html>
D6. Dojo Widgets: Form Management with dojox/form/Manager
1. Helper methods of the Form Manager
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: dojox/form/Manager</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<div data-dojo-type="dijit/layout/BorderContainer" id="borderContainer" data-dojo-props="design:'sidebar',gutters:false,liveSplitters:false">
<div data-dojo-type="dijit/layout/ContentPane" id="resultsContainer" data-dojo-props="region:'left',splitter:true">
<table id="result" border="1">
<thead>
<tr>
106
<th>Name</th>
<th>Value</th>
</tr>
</thead>
<tbody id="table"></tbody>
</table>
<p id="controls">
<input type="checkbox" id="c01" name="c01" value="c01" checked="checked">
<label for="c01">enable the form elements</label>
<br>
<input type="checkbox" id="c02" name="c02" value="c02">
<label for="c02">add/remove background</label>
<br>
<input type="checkbox" id="c03" name="c03" value="c03" checked="checked">
<label for="c03">show form elements</label>
<br>
<input type="checkbox" id="c04" name="c04" value="c04" checked="checked">
<label for="c04">show form widgets</label>
</p>
</div>
<div data-dojo-type="dijit/layout/ContentPane" id="formContainer" data-dojo-props="region:'center',splitter:true">
<h1>Demo: dojox/form/Manager</h1>
<p>
Make sure you open the script console to see all of the form values change!
</p>
<form data-dojo-type="dojox/form/Manager" id="form">
<fieldset data-dojo-attach-point="part1">
<legend>HTML form elements</legend>
<div>
<input type="checkbox" id="e01" name="e01" value="e01" data-dojo-observer="showValues, logRadio">
<label for="e01">e01 input/checkbox</label>
</div>
<div>
<input type="radio" id="e021" name="e02" value="e02-1" data-dojo-observer="showValues">
<label for="e021">e02-1 input/radio</label>
<input type="radio" id="e022" name="e02" value="e02-2" checked="checked" data-dojo-observer="showValues">
<label for="e022">e02-2 input/radio</label>
</div>
<div>
<input type="text" id="e03" name="e03" value="e03" data-dojo-observer="showValues">
<label for="e03">e03 input/text</label>
</div>
<div>
<input type="password" id="e04" name="e04" value="e04" data-dojo-observer="showValues">
<label for="e04">e04 input/password</label>
</div>
<div>
<input type="hidden" id="e05" name="e05" value="e05" data-dojo-observer="showValues">
<label for="e05">e05 input/hidden</label>
</div>
<div>
<select id="e06" name="e06" data-dojo-observer="showValues">
107
<option value="e06-1">e06-1 first</option>
<option value="e06-2" selected="selected">e06-2 second</option>
</select>
<label for="e06">e06 select</label>
</div>
<div>
<label for="e07">e07 textarea</label><br>
<textarea id="e07" name="e07"
rows="3" cols="15" style="width: 15em;" data-dojo-
observer="showValues">e07</textarea>
</div>
<div>
<button name="e08" data-dojo-observer="showValues">e08 button</button>
<input type="button" name="e09" value="e09 input/button" data-dojo-observer="showValues">
<input type="reset" name="e10" value="e10 input/reset" data-dojo-observer="showValues">
<input type="submit" name="e11" value="e11 input/submit" data-dojo-observer="showValues">
</div>
</fieldset>
<fieldset data-dojo-attach-point="part2">
<legend>Dijit form widgets</legend>
<div>
<input type="checkbox" data-dojo-type="dijit/form/CheckBox" id="w01" name="w01" value="w01" data-dojo-
observer="showValues">
<label for="w01">w01 input/checkbox dijit/form/CheckBox</label>
</div>
<div>
<input type="radio" data-dojo-type="dijit/form/RadioButton" id="w021" name="w02" value="w02-1" data-dojo-
observer="showValues">
<label for="w021">w02-1 input/radio dijit/form/RadioButton</label>
<input type="radio" data-dojo-type="dijit/form/RadioButton" id="w022" name="w02" value="w02-2" checked="checked"
data-dojo-observer="showValues, logRadio">
<label for="w022">w02-2 input/radio dijit/form/RadioButton</label>
</div>
<div>
<input type="text" data-dojo-type="dijit/form/TextBox" id="w03" name="w03" value="w03" data-dojo-
props="intermediateChanges:true" data-dojo-observer="showValues">
<label for="w03">w03 input/text dijit/form/TextBox with intermediateChanges set to true</label>
</div>
<div>
<input type="password" data-dojo-type="dijit/form/TextBox" id="w04" name="w04" value="w04" data-dojo-
props="intermediateChanges:false" data-dojo-observer="showValues">
<label for="w04">w04 input/password dijit/form/TextBox with intermediateChanges set to false</label>
</div>
<div>
<select data-dojo-type="dijit/form/Select" id="w06" name="w06" data-dojo-observer="showValues">
<option value="w06-1">w06-1 first</option>
<option value="w06-2" selected="selected">w06-2 second</option>
</select>
<label for="w06">w06 select dijit/form/Select</label>
</div>
<div>
<label for="w07">w07 textarea dijit/form/SimpleTextarea with intermediateChanges set to true</label><br>
108
<textarea data-dojo-type="dijit/form/SimpleTextarea" id="w07" name="w07" data-dojo-
observer="showValues"
rows="3" cols="15" style="width: 15em;" data-dojo-
props="intermediateChanges:true">w07</textarea>
</div>
<div>
<button data-dojo-type="dijit/form/Button" name="w08" value="w08" data-dojo-observer="showValues">w08
button</button>
<button type="button" data-dojo-type="dijit/form/Button" name="w09" value="w09 Button/button" data-dojo-
observer="showValues">w09 type=button</button>
<button type="reset" data-dojo-type="dijit/form/Button" name="w10" value="w10 Button/reset" data-dojo-
observer="showValues">w10 type=reset</button>
<button type="submit" data-dojo-type="dijit/form/Button" name="w11" value="w11 Button/submit" data-dojo-
observer="showValues">w11 type=submit</button>
</div>
</fieldset>
<script type="dojo/method" data-dojo-event="logRadio">
// sample observer: logs radio buttons by name
var values = this.gatherFormValues(["e02", "w02"]);
console.log("e02: " + values.e02 + ", w02: " + values.w02);
</script>
<script type="dojo/method" data-dojo-event="showValues" data-dojo-args="value,name">
if(name){
// first time this method is called with no parameters
// show the name and the value otherwise
console.log("name = ", name, " value = ", value);
}
require(["dijit/registry", "dojo/query", "dojo/dom-class", "dojo/dom-construct", "dojo/dom",
"dojo/domReady!"],
function(registry, query, domClass, domConstruct, dom){
// clear any hilited cells
query("tr.hilite", dom.byId("table")).forEach(function(node){
domClass.remove(node, "hilite");
});
// get the node of the table row used to display the value for this input
var rowNode = dom.byId("tr" + name);
// hilite the node
domClass.add(rowNode, "hilite");
// update the value displayed
query("td.value", rowNode).forEach(function(node){
var textNode = document.createTextNode(value.toString());
domConstruct.place(textNode, node, "only");
});
});
</script>
</form>
</div>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async:true"></script>
<script>
require([
109
"dijit/registry",
"dojo/parser",
"dojo/on",
"dojo/query",
"dojo/dom-construct",
"dojo/_base/lang",
"dojo/_base/array",
"dojo/dom",
"dijit/layout/ContentPane",
"dijit/layout/BorderContainer",
"dojox/form/Manager",
"dijit/form/Button",
"dijit/form/CheckBox",
"dijit/form/RadioButton",
"dijit/form/TextBox",
"dijit/form/ComboBox",
"dijit/form/SimpleTextarea",
"dijit/form/Select",
"dojo/domReady!"],
function(registry, parser, on, query, domConstruct, lang, arrayUtil, dom){
// parse the page to render the Dojo elements
parser.parse();
// get the form widget
var form = registry.byId("form");
window.formManager = form;
// query for all the inputs whose name begins with e (for element) or w (for widget)
var names = [];
query("[name^=e], [name^=w]", dom.byId("form")).forEach(function(node){
if(arrayUtil.lastIndexOf(names, node.name, names.length - 1) === -1){
names.push(node.name);
}
});
// gather the values in the form for all the inputs named in the name array
var values = form.gatherFormValues(names),
table = dom.byId("table");
// sort the name array and create a table to display the names and values
names.sort();
arrayUtil.forEach(names, function(name){
// Note: This is just a quick way to create a table, and is
// not the most performant way to create a table using Dojo,
// but is sufficient for this example
domConstruct.place('<tr id="tr' + name + '"><td>' + name + '</td><td class="value">' + values[name] +
'</td>',table);
});
// attach the event handlers to the control checkboxes
query("input[id^=c0]", dom.byId("controls")).on("click", function(event){
switch (event.target.id){
case "c01":
form[this.checked ? "enable" : "disable"]();
break;
case "c02":
110
form[this.checked ? "addClass" : "removeClass"]("makeYellow", ["part1", "part2"]);
break;
case "c03":
form[this.checked ? "show" : "hide"](["part1"]);
break;
case "c04":
form[this.checked ? "show" : "hide"](["part2"]);
}
});
// ensure the submit buttons don't submit, but log
form.on("submit", function(event){
event.preventDefault();
event.stopPropagation();
console.log("Submit");
});
});
</script>
</body>
</html>
D7. Dojo Widgets: Vector Graphics with Dojo’s GFX
1. Creating the Surface
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: GFX Surface</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body>
<h1>Demo: GFX Surface</h1>
<div id="surfaceElement" style="border:1px solid #ccc;width:400px;height:400px;"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
<script>
require(["dojox/gfx", "dojo/domReady!"], function(gfx) {
surface = gfx.createSurface("surfaceElement", 400, 400);
});
</script>
</body>
</html>
111
2. Creating Shapes
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Basic Shapes</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body>
<h1>Demo: Basic Shapes</h1>
<div id="surfaceElement" style="border: 1px solid #ccc;width: 400px;height: 400px;"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
<script>
require(["dojox/gfx", "dojo/domReady!"], function(gfx) {
// Create a GFX surface
// Arguments: node, width, height
surface = gfx.createSurface("surfaceElement", 400, 400);
// Create a square
surface.createRect({ x: 100, y: 50, width: 200, height: 100 }).setFill("yellow").setStroke("blue");
// Add a circle
surface.createCircle({ cx: 100, cy: 300, r: 50 }).setFill("green").setStroke("pink");
// Now an ellipse
surface.createEllipse({ cx: 300, cy: 200, rx: 50, r: 25 }).setFill("#fff").setStroke("#999");
// And a line
surface.createLine({ x1: 10, y1: 50, x2: 400, y2: 400 }).setStroke("green");
// How about a polyline?
surface.createPolyline([{ x: 250, y: 250 }, { x: 300, y: 300 }, { x: 250, y: 350 }, { x: 200, y: 300 }, { x: 110, y: 250
}]).setStroke("blue");
// Add in an image
surface.createImage({ x: 100, y: 300, width: 123, height: 56, src: "../images/logo.png" });
// With some text
surface.createText({ x: 64, y: 220, text: "Vector Graphics Rock!", align: "start"}).
setFont({ family: "Arial", size: "20pt", weight: "bold" }). //set font
setFill("blue");
// And an advanced textpath
112
var textShape0 = surface.createTextPath({text: "TextPath!"}).moveTo(125, 70).lineTo(285, 20).setFont({ family: "Verdana", size: "2em"
}).setFill("black");
// And a simple path
surface.createPath("m100 100 100 0 0 100c0 50-50 50-100 0s-50-100 0-100z").setStroke("black");
});
</script>
</body>
</html>
3. Filling a Shape
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: GFX Fills</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body>
<h1>Demo: GFX Fills</h1>
<div id="surfaceElement" style="border:1px solid #ccc;width:400px;height:400px;"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
require(["dojox/gfx", "dojo/domReady"], function(gfx) {
gfx.renderer = "canvas";
// Create a GFX surface
// Arguments: node, width, height
surface = gfx.createSurface("surfaceElement", 400, 400);
// Create a circle with a set "blue" color
surface.createCircle({ cx: 50, cy: 50, rx: 50, r: 25 }).setFill("blue");
// Crate a circle with a set hex color
surface.createCircle({ cx: 300, cy: 300, rx: 50, r: 25 }).setFill("#f00");
// Create a circle with a linear gradient
surface.createRect({x: 180, y: 40, width: 200, height: 100 }).
setFill({ type:"linear",
x1: 0,
113
y1: 0, //x: 0=>0, consistent gradient horizontally
x2: 0, //y: 0=>420, changing gradient vertically
y2: 420,
colors: [
{ offset: 0, color: "#003b80" },
{ offset: 0.5, color: "#0072e5" },
{ offset: 1, color: "#4ea1fc" }
]
});
// Create a circle with a radial gradient
surface.createEllipse({
cx: 120,
cy: 260,
rx: 100,
ry: 100
}).setFill({
type: "radial",
cx: 150,
cy: 200,
colors: [
{ offset: 0, color: "#4ea1fc" },
{ offset: 0.5, color: "#0072e5" },
{ offset: 1, color: "#003b80" }
]
});
});
</script>
</body>
</html>
4. Setting a Stroke on a Shape
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: GFX Strokes</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body>
<h1>Demo: GFX Strokes</h1>
<div id="surfaceElement" style="border:1px solid #ccc;width:400px;height:400px;"></div>
<!-- load dojo and provide config via data attribute -->
114
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
require(["dojox/gfx", "dojo/domReady!"], function(gfx) {
// Create a GFX surface
// Arguments: node, width, height
surface = dojox.gfx.createSurface("surfaceElement", 400, 400);
// Create a rectangle with a basic black border
surface.createRect({x: 100, y: 50, width: 200, height: 100 }).setStroke("#000");
// Create a circle with a 3-pixel dotted red border
surface.createCircle({ cx: 300, cy: 300, rx:50, r:25 }).setStroke({
style: "Dot", width: 3, cap: "round", color: "#f00"
});
// Create a circle with
// Create a circle with a 3-pixel dotted red border
surface.createCircle({ cx: 150, cy: 250, rx:100, r:50 }).setStroke({
style: "Dash", width: 3, cap: "butt", color: "#00f"
});
});
</script>
</body>
</html>
5. Grouping Shapes Together
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Moveable Group</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body>
<h1>Demo: Moveable Group</h1>
<p>
Click and drag any of the shapes to see the entire group move!
</p>
<div id="surfaceElement" style="border:1px solid #ccc;width:400px;height:400px;"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
<script>
require(["dojox/gfx", "dojox/gfx/Moveable", "dojo/domReady!"], function(gfx, Moveable) {
115
// Create a GFX surface
// Arguments: node, width, height
surface = gfx.createSurface("surfaceElement", 400, 400);
// Create a group
var group = surface.createGroup();
// Create a square
group.createRect({ x: 100, y: 50, width: 200, height: 100 }).setFill("yellow").setStroke("blue");
// Add a circle
group.createCircle({ cx: 100, cy: 300, r: 50 }).setFill("green").setStroke("pink");
// Now an ellipse
group.createEllipse({ cx: 300, cy: 200, rx: 50, r: 25 }).setFill("#fff").setStroke("#999");
// And a line
group.createLine({ x1: 10, y1: 50, x2: 400, y2: 400 }).setStroke("green");
// How about a polyline?
group.createPolyline([{ x: 250, y: 250 }, { x: 300, y: 300 }, { x: 250, y: 350 }, { x: 200, y: 300 }, { x: 110, y: 250
}]).setStroke("blue");
// Add in an image
group.createImage({ x: 100, y: 300, width: 123, height: 56, src: "../images/logo.png" });
// With some text
group.createText({ x: 64, y: 220, text: "Vector Graphics Rock!", align: "start"}).
setFont({ family: "Arial", size: "20pt", weight: "bold" }). //set font
setFill("blue");
// And an advanced textpath
group.createTextPath({ text: "TextPath!" }).moveTo(125, 70).lineTo(285, 20).setFont({family: "Verdana", size:
"2em"}).setFill("black");
// And a simple path
group.createPath("m100 100 100 0 0 100c0 50-50 50-100 0s-50-100 0-100z").setStroke("black");
// Make them moveable!
new Moveable(group);
});
</script>
</body>
</html>
6. Fill, Stroke, and Font Animations
<!DOCTYPE html>
<html lang="en">
116
<head>
<meta charset="utf-8">
<title>Demo: Animating Fills, Fonts, and Strokes</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Animating Fills, Fonts, and Strokes</h1>
<div id="surfaceElement" style="border:1px solid #ccc;width:400px;height:400px;"></div>
<br /><br />
<button data-dojo-type="dijit/form/Button" data-dojo-props="onClick:doAnimations">Start Animations</button>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
require(["dojox/gfx", "dojox/gfx/fx", "dijit/form/Button", "dojo/parser", "dojo/domReady!"], function(gfx, gfxFx) {
// Function to start animations
doAnimations = function() {
console.warn("Do Animations!");
gfxFx.animateFill({
shape: circle,
duration: 500,
color: { start: "blue", end: "green" }
}).play();
gfxFx.animateStroke({
shape: rectangle,
duration: 500,
color: { start: "yellow", end: "black" },
width: { end: 15 },
join: { values: ["miter", "bevel", "round"] }
}).play();
gfxFx.animateFont({
shape: text,
duration: 500,
variant: { values: ["normal", "small-caps"] },
size: { end: 20, units: "pt" },
color: "green"
}).play();
};
// Create a GFX surface
// Arguments: node, width, height
surface = gfx.createSurface("surfaceElement", 400, 400);
// Create a circle, a dojox.gfx.fx instance, play it immediately
circle = surface.createCircle({ cx: 50, cy: 50, rx: 50, r: 25 }).setFill("blue");
// Create a rectangle, animate its stroke
117
rectangle = surface.createRect({x: 100, y: 50, width: 200, height: 100 }).setStroke("yellow");
// Create text, animate it
text = surface.createText({ x:64, y:220, text:"Vector Graphics Rock!", align:"start"}).setFont({ family:"Arial", size:"20pt",
weight:"bold" }).setFill("red");
});
</script>
</body>
</html>
7. Rotating a Shape
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Rotate a Group of Shapes</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Rotate a Group of Shapes</h1>
<div id="surfaceElement" style="border:1px solid #ccc;width:400px;height:400px;"></div>
<br /><br />
<button data-dojo-type="dijit/form/Button" data-dojo-props="onClick:doAnimations">Start Animations</button>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
require(["dojox/gfx", "dojox/gfx/fx", "dijit/form/Button", "dojo/parser", "dojo/domReady!"], function(gfx, gfxFx, Button) {
// Function to start animations
doAnimations = function() {
new gfxFx.animateTransform({
duration: 1200,
shape: group,
transform: [{
name: "rotategAt",
start: [0, 200, 200], // Starts at 0 degree rotation
end: [360, 200, 200] // Ends at 360 degrees
}]
}).play();
new gfxFx.animateTransform({
duration: 1800,
118
shape: group2,
transform: [{
name: "rotategAt",
start: [0, 200, 200], // Starts at 0 degree rotation
end: [-360, 200, 200] // Ends at 360 degrees
}]
}).play();
};
// Create a GFX surface
// Arguments: node, width, height
surface = gfx.createSurface("surfaceElement", 400, 400);
// Create a group
group = surface.createGroup();
// Create a circle
var circle1 = group.createCircle({ cx: 100, cy: 300, r:50 }).setFill({
type: "radial",
cx: 100,
cy: 300,
colors: [
{ offset: 0, color: "#f3001f" },
{ offset: 1, color: "#a40016" }
]
});
var circle2 = group.createCircle({ cx: 100, cy: 100, r:50 }).setFill({
type: "radial",
cx: 100,
cy: 100,
colors: [
{ offset: 0, color: "#f3001f" },
{ offset: 1, color: "#a40016" }
]
});
var circle3 = group.createCircle({ cx: 300, cy: 300, r: 50 }).setFill({
type: "radial",
cx: 300,
cy: 300,
colors: [
{ offset: 0, color: "#f3001f" },
{ offset: 1, color: "#a40016" }
]
});
var circle4 = group.createCircle({ cx: 300, cy: 100, r: 50 }).setFill({
type: "radial",
cx: 300,
cy: 100,
colors: [
{ offset: 0, color: "#f3001f" },
{ offset: 1, color: "#a40016" }
]
});
119
group2 = surface.createGroup();
var icircle1 = group2.createCircle({ cx: 100, cy: 300, r: 25 }).setFill({
type: "radial",
cx: 100,
cy: 300,
colors: [
{ offset: 0, color: "#b0bddd" },
{ offset: 1, color: "#0543de" }
]
});
var icircle2 = group2.createCircle({ cx: 100, cy: 100, r: 25 }).setFill({
type: "radial",
cx: 100,
cy: 100,
colors: [
{ offset: 0, color: "#b0bddd" },
{ offset: 1, color: "#0543de" }
]
});
var icircle3 = group2.createCircle({ cx: 300, cy: 300, r: 25 }).setFill({
type: "radial",
cx: 300,
cy: 300,
colors: [
{ offset: 0, color: "#b0bddd" },
{ offset: 1, color: "#0543de" }
]
});
var icircle4 = group2.createCircle({ cx: 300, cy: 100, r: 25 }).setFill({
type: "radial",
cx: 300,
cy: 100,
colors: [
{ offset: 0, color: "#b0bddd" },
{ offset: 1, color: "#0543de" }
]
});
});
</script>
</body>
</html>
8. Scaling and Skewing
<!DOCTYPE html>
<html lang="en">
120
<head>
<meta charset="utf-8">
<title>Demo: Scaling and Skewing Shapes</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Scaling and Skewing Shapes</h1>
<div id="surfaceElement" style="border:1px solid #ccc;width:400px;height:400px;"></div>
<br /><br />
<button data-dojo-type="dijit/form/Button" data-dojo-props="onClick:shrink">Shrink</button>
<button data-dojo-type="dijit/form/Button" data-dojo-props="onClick:grow">Grow</button>
<button data-dojo-type="dijit/form/Button" data-dojo-props="onClick:skew">Skew -20</button>
<button data-dojo-type="dijit/form/Button" data-dojo-props="onClick:skewBack">Skew 20</button>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
require(["dojox/gfx", "dojox/gfx/fx", "dijit/form/Button", "dojo/parser", "dojo/domReady!"], function(gfx, gfxFx, Button) {
// Function to start animations
shrink = function() {
group.applyTransform(gfx.matrix.scale({ x: 0.5, y: 0.5 }));
};
grow = function() {
group.applyTransform(gfx.matrix.scale({ x: 2, y: 2 }));
};
skew = function() {
group.applyTransform(gfx.matrix.skewYg(-20));
};
skewBack = function() {
group.applyTransform(gfx.matrix.skewYg(20));
};
// Create a GFX surface
// Arguments: node, width, height
surface = gfx.createSurface("surfaceElement", 400, 400);
// Create a group
group = surface.createGroup();
var circle1 = group.createCircle({ cx: 100, cy: 300, r:50 }).setFill({
type: "radial",
cx: 100,
cy: 300,
colors: [
{ offset: 0, color: "#f3001f" },
121
{ offset: 1, color: "#a40016" }
]
});
var circle2 = group.createCircle({ cx: 100, cy: 100, r:50 }).setFill({
type: "radial",
cx: 100,
cy: 100,
colors: [
{ offset: 0, color: "#f3001f" },
{ offset: 1, color: "#a40016" }
]
});
var circle3 = group.createCircle({ cx: 300, cy: 300, r:50 }).setFill({
type: "radial",
cx: 300,
cy: 300,
colors: [
{ offset: 0, color: "#f3001f" },
{ offset: 1, color: "#a40016" }
]
});
var circle4 = group.createCircle({ cx: 300, cy: 100, r:50 }).setFill({
type: "radial",
cx: 300,
cy: 100,
colors: [
{ offset: 0, color: "#f3001f" },
{ offset: 1, color: "#a40016" }
]
});
});
</script>
</body>
</html>
9. Events group.on_
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: GFX Events</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body>
<h1>Demo: GFX Events</h1>
122
<p>Click any element of the group to see its event object in the Javascript console.</p>
<div id="surfaceElement" style="border:1px solid #ccc;width:400px;height:400px;"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
require(["dojox/gfx", "dojo/on", "dojo/domReady!"], function(gfx, on) {
// Create a GFX surface
// Arguments: node, width, height
surface = gfx.createSurface("surfaceElement", 400, 400);
// Create a group
var group = surface.createGroup();
// Create a square
group.createRect({ x: 100, y: 50, width: 200, height: 100 }).setFill("yellow").setStroke("blue");
// Add a circle
var circle = group.createCircle({ cx: 100, cy: 300, r: 50 }).setFill("green").setStroke("pink");
circle.on("click",function(e) {
circle.setFill("red");
console.log("Circle click!",e);
});
// Now an ellipse
group.createEllipse({ cx: 300, cy: 200, rx: 50, r: 25 }).setFill("#fff").setStroke("#999");
// Add a click event to the group
group.on("click", function(e) {
// Log the event the console
console.log("Group click!",e);
}, true);
});
</script>
</body>
</html>
10. Create the Dojo Logo with GFX
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Dojo Logo</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
123
<body class="claro">
<h1>Demo: Dojo Logo</h1>
<div style="padding:10px 0 20px 0;">
<button data-dojo-type="dijit/form/Button" data-dojo-props="onClick:rotateLogo">Rotate Logo</button>
<button data-dojo-type="dijit/form/Button" data-dojo-props="onClick:enlargeLogo">Enlarge Logo</button>
<button data-dojo-type="dijit/form/Button" data-dojo-props="onClick:shrinkLogo">Shrink Logo</button>
<button data-dojo-type="dijit/form/Button" data-dojo-props="onClick:skewUp">Skew Up</button>
<button data-dojo-type="dijit/form/Button" data-dojo-props="onClick:skewDown">Skew Down</button>
<button data-dojo-type="dijit/form/Button" data-dojo-props="onClick:animateStrokes">Animate Strokes</button>
<button data-dojo-type="dijit/form/Button" data-dojo-props="onClick:animateFills">Animate Fill</button>
<button data-dojo-type="dijit/form/Button" data-dojo-props="onClick:beautifyFills">Beautify Fill - Red</button>
<button data-dojo-type="dijit/form/Button" data-dojo-props="onClick:wackyMovement">Random Chaos!</button>
</div>
<div id="surfaceElement" style="border:1px solid #ccc;width:1100px;height:700px;"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
// Keep track of all shapes
allShapes = [];
// Require the dojox.gfx resource
require(["dojox/gfx", "dojox/gfx/fx", "dojo/_base/array", "dijit/form/Button", "dojo/parser", "dojo/domReady!"],
function(gfx, gfxFx, arrayUtil) {
// Function to rotate logo
rotateLogo = function() {
new gfxFx.animateTransform({
duration: 700,
shape: allGroup,
transform: [{
name: 'rotategAt',
start: [0, 550, 350], // Starts at 0 degree rotation
end: [360, 550, 350] // Ends at 360 degrees
}]
}).play();
};
// Function to enlarge Logo
enlargeLogo = function() {
124
allGroup.applyTransform(gfx.matrix.scale({ x: 2, y: 2 }));
};
// Function to shrink Logo
shrinkLogo = function() {
allGroup.applyTransform(gfx.matrix.scale({ x: 0.5, y: 0.5 }));
};
// Skewing functions
skewUp = function() {
allGroup.applyTransform(gfx.matrix.skewYg(-20));
};
skewDown = function() {
allGroup.applyTransform(gfx.matrix.skewYg(20));
};
// Animate strokes
animateStrokes = function() {
arrayUtil.forEach(allShapes, function(item) {
new gfxFx.animateStroke({
duration: 1200,
shape: item,
color: { end: "green" },
width: { end: 15 },
join: { values: ["miter", "bevel", "round"] },
onEnd: function() {
new gfxFx.animateStroke({
duration: 1200,
shape: item,
color: { end: "#000"},
width: { end: 1 },
join: { values: ["round", "bevel", ""] }
}).play();
}
}).play();
});
};
// Animate fills
animateFills = function() {
arrayUtil.forEach(allShapes, function(item) {
new gfxFx.animateFill({
duration: 1200,
shape: item,
color: { start: "black", end: "green" },
onEnd: function() {
new dojox.gfx.fx.animateFill({
duration: 1200,
shape: item,
color: { end: "black" }
}).play();
}
125
}).play();
});
};
// Create decent Fill
beautifyFills = function() {
arrayUtil.forEach(allShapes, function(item) {
item.setFill(redFill).setStroke("#a70017");
});
};
// Wacky animations
wackyMovement = function() {
arrayUtil.forEach(allShapes, function(shape) {
var rand1 = Math.floor(Math.random() * 700);
var rand2 = Math.floor(Math.random() * 700);
new gfxFx.animateTransform({
duration: Math.floor(Math.random() * 2000),
shape: shape,
transform: [{
name: 'rotategAt',
start: [0, rand1, rand2], // Starts at 0 degree rotation
end: [720, rand1, rand2] // Ends at 360 degrees
}]
}).play();
});
};
// Create a GFX surface
// Arguments: node, width, height
surface = gfx.createSurface("surfaceElement", 1100, 700);
// Regular fill
regularFill = { type: "linear", x1: 0, y1: 0, x2: 0, y2: 900, colors: [{ offset: 0, color: "#555"},{ offset: 1, color:
"#000"}] };
redFill = { type: "linear", x1: 0, y1: 0, x2: 0, y2: 900, colors: [{ offset: 0, color: "#f3001f"},{ offset: 1, color:
"#a40016"}] };
// Tiny letter "t" in "toolkit"
var letterToolkitT = surface.createPath("M826.698,536.736v11.722h12.71v6.758h-
12.71v26.25c0,6.065,1.718,9.483,6.659,9.483 c2.427,0,3.834-0.203,5.147-0.61l0.406,6.759c-1.721,0.621-4.439,1.211-7.876,1.211c-4.145,0-7.466-1.404-
9.575-3.729 c-2.429-2.729-3.442-7.062-3.442-12.82v-26.555h-7.576v-6.756h7.576v-8.996L826.698,536.736z").setFill(regularFill).setStroke("#000");
// "o"
var letterToolkitO1 = surface.createPath("M868.708,598.43c-13.119,0-23.418-9.695-23.418-25.142c0-16.354,10.801-
25.938,24.225-25.938 c14.039,0,23.525,10.196,23.525,25.036c0,18.175-12.623,26.05-24.229,26.05h-0.103V598.43L868.708,598.43z M869.115,591.764
c8.481,0,14.846-7.975,14.846-19.089c0-8.267-4.146-18.686-14.643-18.686c-10.396,0-14.931,9.694-14.931,18.976
c0,10.717,6.052,18.783,14.638,18.783h0.09V591.764L869.115,591.764z").setFill(regularFill).setStroke("#000");
// "o"
var letterToolkitO2 = surface.createPath("M924.162,598.43c-13.119,0-23.406-9.695-23.406-25.142c0-16.354,10.801-
25.938,24.213-25.938 c14.039,0,23.517,10.196,23.517,25.036c0,18.175-12.611,26.05-24.216,26.05h-0.106L924.162,598.43L924.162,598.43z
126
M924.574,591.764c8.487,0,14.834-7.975,14.834-19.089c0-8.267-4.129-18.686-14.638-18.686c-10.395,0-14.94,9.694-14.94,18.976
c0,10.717,6.063,18.783,14.643,18.783h0.103L924.574,591.764L924.574,591.764z").setFill(regularFill).setStroke("#000");
// "l"
var letterToolkitL = surface.createPath("M959.734,525.641h8.873v71.672h-
8.873V525.641z").setFill(regularFill).setStroke("#000");
// "k"
var letterToolkitK = surface.createPath("M992.453,570.868h0.197c1.207-1.72,2.832-3.837,4.235-5.552l14.455-
16.859h10.592l-18.883,20.086 l21.506,28.771h-10.801l-16.746-23.418l-4.541,5.043v18.377h-8.889v-
71.676h8.889v45.229L992.453,570.868L992.453,570.868z").setFill(regularFill).setStroke("#000");
// "i"
var letterToolkitI = surface.createPath("M1036.886,540.172c-3.217,0-5.336-2.527-5.336-5.443c0-3.131,2.222-5.555,5.556-
5.555 c3.215,0,5.452,2.424,5.452,5.555c0,2.916-2.118,5.443-5.555,5.443H1036.886z M1032.656,597.312v-
48.854h8.877v48.854H1032.656z").setFill(regularFill).setStroke("#000");
// "t"
var letterToolkitT2 = surface.createPath("M1066.992,536.736v11.722h12.715v6.758h-
12.715v26.25c0,6.065,1.715,9.483,6.662,9.483 c2.414,0,3.836-0.203,5.149-0.61l0.396,6.759c-1.709,0.621-4.435,1.211-7.869,1.211c-4.139,0-7.473-
1.404-9.594-3.729 c-2.408-2.729-3.435-7.062-3.435-12.82v-26.555h-7.563v-6.756h7.563v-
8.996L1066.992,536.736z").setFill(regularFill).setStroke("#000");
// Big show
var letterDojo = surface.createPath("M694.594,104.102v60.604h40.403v-60.604H694.594z M694.998,471.96 c-0.812,17.886-
11.512,56.267-45.76,80.509l26.369,36.766c0,0,62.211-66.451,59.391-114.733V184.906h-40.4L694.998,471.96z M1046.902,335.198c0,73.13-60.609,121.206-
121.207,121.206c-70.703,0-118.781-60.604-118.781-121.206 c0-65.651,53.125-118.778,118.781-118.778C998.82,216.419,1046.902,277.023,1046.902,335.198z
M1087.302,335.198 c0-85.854-68.278-159.182-161.606-159.182c-65.656,0-141.411,40.403-159.185,136.359v48.076c0,5.054,2.623,15.148,5.051,22.625
c25.251,80.809,98.578,113.732,154.134,113.732C1011.544,496.811,1087.302,428.531,1087.302,335.198z M280.47,94v126.057v71.61 v89.591c-18.989,46.672-
65.653,75.151-112.322,75.151c-70.703,0-118.78-60.604-118.78-121.206 c0-65.651,53.128-118.779,118.78-
118.779c30.608,0,56.867,10.708,77.064,27.268l7.072-45.048 c-24.141-14.238-52.722-22.619-84.139-22.619c-65.65-0.009-141.404,40.395-
159.18,136.351v48.076 c0,5.054,2.623,15.149,5.052,22.625c25.252,80.809,98.578,113.733,154.129,113.733c42.524,0,82.729-16.869,112.322-45.232v36.355
h50.499V94.011H280.47V94z M632.775,335.198c0,73.13-60.604,121.206-121.207,121.206c-70.703,0-118.78-60.604-118.78-121.206 c0-65.651,53.125-
118.778,118.78-118.778C584.699,216.419,632.775,277.023,632.775,335.198z M673.178,335.198 c0-85.854-68.275-159.182-161.609-159.182c-65.651,0-
141.406,40.403-159.182,136.359v48.076c0,5.054,2.623,15.148,5.052,22.625
c25.25,80.809,98.578,113.732,154.129,113.732C597.423,496.811,673.178,428.531,673.178,335.198z M993.773,115.415h-131.31 c-2.432,2.623-5.053,2.623-
5.053,7.674c0,7.476,2.621,7.476,2.621,10.102h131.309c2.433-2.623,5.053-2.623,5.053-10.102 C996.394,118.041,993.773,118.041,993.773,115.415z
M579.65,115.415H448.34c-2.426,2.623-5.049,2.623-5.049,7.674 c0,7.476,2.623,7.476,2.623,10.102h131.307c2.43-2.623,5.053-2.623,5.053-
10.102C582.273,118.041,579.65,118.041,579.65,115.415z").setFill(regularFill).setStroke("#000");
// Put all pieces together
allGroup = surface.createGroup();
arrayUtil.forEach([letterToolkitT, letterToolkitO1, letterToolkitO2, letterToolkitL, letterToolkitK, letterToolkitI,
letterToolkitT2, letterDojo], function(item) {
allGroup.add(item);
allShapes.push(item);
});
});
</script>
</body>
</html>
127
11. Create the London Ajax Logo with GFX
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: London Ajax Logo</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: London Ajax Logo</h1>
<div id="gfxNode" style="width:480px;height:480px;border:1px solid #ccc;margin:20px;float:left;"></div>
<div style="width:300px;float:left;margin-top:20px;">
<h2>Animations and Transformations</h2>
<button data-dojo-type="dijit/form/Button" id="rotate360">Rotate 360 Degrees</button>
<br /><br />
<button data-dojo-type="dijit/form/Button" id="halfSize">Half Size</button>
<button data-dojo-type="dijit/form/Button" id="doubleSize">Double Size</button>
<br /><br />
<button data-dojo-type="dijit/form/Button" id="makeMovable">Make Movable</button>
<button data-dojo-type="dijit/form/Button" id="stopMovable" disabled="true">Stop Movable</button>
<br /><br />
<button data-dojo-type="dijit/form/Button" id="translate">Down-Right</button>
<button data-dojo-type="dijit/form/Button" id="translate2">Up-Left</button>
<br /><br />
<button data-dojo-type="dijit/form/Button" id="skew">Skew</button>
<button data-dojo-type="dijit/form/Button" id="skewback">Skew Back</button>
<br /><br />
<button data-dojo-type="dijit/form/Button" id="rotateanimate">Rotate w/ Color Animation</button>
<br /><br />
<button data-dojo-type="dijit/form/Button" id="animateText">Animate Text</button>
<button data-dojo-type="dijit/form/Button" id="animateFill">Animate Fill</button>
<br /><br />
<button data-dojo-type="dijit/form/Button" id="animateStroke">Animate Stroke</button>
<br /><br />
<p><em>Note: some animations will reset the group to its original shape to best illustrate an effect.</em></p><br />
<h2>Events</h2>
<p>Double-click anywhere on the logo to rotate it 360 degrees.</p>
</div>
<div style="clear:both;"></div>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
<script>
require(["dojox/gfx", "dojox/gfx/fx", "dojox/gfx/Moveable", "dojo/aspect", "dojo/_base/array", "dijit/registry", "dojo/parser",
"dijit/form/Button", "dojo/domReady!"], function(gfx, gfxFx, Moveable, aspect, arrayUtil, registry, parser) {
128
parser.parse();
// Create the surface
surface = gfx.createSurface("gfxNode", 480, 480);
// Create the group
group = surface.createGroup();
// Create "V" Shape
var vShapeStyles = {
stroke: {
color: "#a70017"
},
fill: {
type: "linear", x1: 0, y1: 0, x2: 0, y2: 420,
colors: [{ offset: 0, color: "#f3001f" }, { offset: 1, color: "#a40016" }]
}
};
var vShape = surface.createPolyline([
{ x:28, y:420 },
{ x:100, y:420 },
{ x:240, y:124 },
{ x:384, y:420 },
{ x:456, y:420 },
{ x:276, y:44 },
{ x:208, y:44 },
{ x:28, y:420 }
]).setStroke(vShapeStyles.stroke).setFill(vShapeStyles.fill);
// Create Blue Box
var rectShape = surface.createRect({ x: 32, y: 272, width: 412, height: 64 }).setFill("#0000ae");
// Create Text
var textShape = surface.createText({ x: 64, y: 320, text: "LONDON AJAX", align: "start"}).setFont({ family: "Arial", size: "36pt",
weight: "bold" }).setFill("#ffffff");
//Group 'em!
group.add(vShape);
group.add(rectShape);
group.add(textShape);
//rotate and style!
var originalVShapeColor = vShape.getFill(), originalRectShapeColor = rectShape.getFill();
var rotateFx = new gfxFx.animateTransform({
duration: 3200,
shape: group,
transform: [ { name: "rotategAt", start: [0, 240, 240], end: [360, 240, 240] }]/*,
onAnimate: function() {
vShape.setFill({ type:"linear", x1:0, y1:0, x2:0, y2:420, colors: [{ offset:0, color:"#a40016"},{ offset:1, color:"#f3001f"}]
});
rectShape.setFill("#0daf24");
},
onEnd: function() {
129
vShape.setFill(originalVShapeColor);
rectShape.setFill(originalRectShapeColor);
}*/
});
// Events
registry.byId("rotate360").on("click", function() {
rotateFx.play();
});
registry.byId("halfSize").on("click", function() {
group.applyTransform(gfx.matrix.scale({ x:0.5, y:0.5 }));
});
registry.byId("doubleSize").on("click", function() {
group.applyTransform(gfx.matrix.scale({ x:2, y:2 }));
});
var movable;
registry.byId("makeMovable").on("click", function() {
movable = new Moveable(group);
registry.byId("stopMovable").set("disabled", false);
registry.byId("makeMovable").set("disabled", true);
});
registry.byId("stopMovable").on("click", function() {
movable.destroy();
registry.byId("stopMovable").set("disabled", true);
registry.byId("makeMovable").set("disabled", false);
});
registry.byId("translate").on("click", function() {
group.applyTransform(gfx.matrix.translate(30, 40));
});
registry.byId("translate2").on("click", function() {
group.applyTransform(gfx.matrix.translate(-30, -40));
});
registry.byId("skew").on("click", function() {
group.applyTransform(gfx.matrix.skewYg(-20));
});
registry.byId("skewback").on("click", function() {
group.applyTransform(gfx.matrix.skewYg(20));
});
var rotateFxAnimate = new gfxFx.animateTransform({
duration: 200,
shape: group,
transform: [ { name: "rotategAt", start: [0, 240, 240], end: [360, 240, 240] }],
onAnimate: function() {
vShape.setFill({ type: "linear", x1: 0, y1: 0, x2: 0, y2: 420, colors: [{ offset: 0, color: "#a40016"},{ offset: 1,
color: "#f3001f"}] });
rectShape.setFill("#0daf24");
},
onEnd: function() {
vShape.setFill(originalVShapeColor);
130
rectShape.setFill(originalRectShapeColor);
}
});
registry.byId("rotateanimate").on("click", function() {
rotateFxAnimate.play();
});
/* animate text */
registry.byId("animateText").on("click", function() {
new gfxFx.animateFont({
duration: 1200,
shape: textShape,
//variant: { values: ["normal", "small-caps"] },
size: { start: 36, end: 20, units: "pt" },
onAnimate: function() {
registry.byId("animateText").set("disabled", true);
},
onEnd: function() {
new gfxFx.animateFont({
duration: 1200,
shape: textShape,
//variant: { values: ["small-caps", "normal"] },
size: { start:20, end: 36, units: "pt" },
onEnd: function() {
registry.byId("animateText").set("disabled", false);
}
}).play();
}
}).play();
});
/* animate stroke */
registry.byId("animateStroke").on("click", function() {
new gfxFx.animateStroke({
duration: 1200,
shape: vShape,
color: { start: "red", end: "green" },
width: { end: 15 },
join: { values: ["miter", "bevel", "round"] },
onAnimate: function() {
registry.byId("animateStroke").set("disabled", true);
},
onEnd: function() {
new gfxFx.animateStroke({
duration: 1200,
shape: vShape,
color: { start: "green", end: "#a40016" },
width: { end: 1 },
join: { values: ["round", "bevel", ""] },
onEnd: function() {
registry.byId("animateStroke").set("disabled", false);
}
}).play();
131
}
}).play();
});
/* animate fill */
registry.byId("animateFill").on("click", function() {
new gfxFx.animateFill({
duration: 1200,
shape: rectShape,
color: { end: "green" },
onAnimate: function() {
registry.byId("animateFill").set("disabled", true);
},
onEnd: function() {
new gfxFx.animateFill({
duration: 1200,
shape: rectShape,
color: { end: "#0000ae" },
onEnd: function() {
registry.byId("animateFill").set("disabled", false);
}
}).play();
}
}).play();
});
group.on("dblclick", function() {
rotateFx.play();
});
});
</script>
</body>
</html>
E1. Dojo Widgets Contd.. : Dijit Menus
1. Getting Started Declarative Demo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo: Dijit Menus</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h3>Menu Demo</h3>
132
<div id="mainMenu" data-dojo-type="dijit/Menu">
<div id="edit" data-dojo-type="dijit/MenuItem">Edit</div>
<div id="view" data-dojo-type="dijit/MenuItem">View</div>
<div id="task" data-dojo-type="dijit/MenuItem">Task</div>
</div>
<p>Last selected: <span id="lastSelected">none</span></p>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
<script>
require([
"dijit/registry",
"dojo/parser",
"dojo/dom",
"dijit/WidgetSet", // for registry.byClass
"dijit/Menu",
"dijit/MenuItem",
"dojo/domReady!"
], function(registry, parser, dom){
// a menu item selection handler
var onItemSelect = function(event){
dom.byId("lastSelected").innerHTML = this.get("label");
};
parser.parse();
registry.byClass("dijit.MenuItem").forEach(function(item){
item.on('click', onItemSelect);
});
});
</script>
</body>
</html>
2. Getting Started Programmatic Demo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo: Dijit Menus</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h3>Menu Demo</h3>
<div id="mainMenu"></div>
<p>Last selected: <span id="lastSelected">none</span></p>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
<script>
133
require([
"dojo/dom",
"dijit/registry",
"dijit/Menu",
"dijit/MenuItem",
"dojo/domReady!"
], function(dom, registry, Menu, MenuItem){
// a menu item selection handler
var onItemSelect = function(event){
dom.byId("lastSelected").innerHTML = this.get("label");
};
// create the Menu container
var menu = new Menu({}, "mainMenu");
// create and add child item widgets
// for each of "edit", "view", "task"
menu.addChild(new MenuItem({
id: "edit",
label: "Edit",
onClick: onItemSelect
}));
menu.addChild(new MenuItem({
id: "view",
label: "View",
onClick: onItemSelect
}));
menu.addChild(new MenuItem({
id: "task",
label: "Task",
onClick: onItemSelect
}));
menu.startup();
});
</script>
</body>
</html>
3. Menu Structure Declarative Demo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo: Dijit Menus</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
134
<body class="claro">
<h3>Nested Menu Demo</h3>
<div id="mainMenu" data-dojo-type="dijit/Menu">
<div id="edit" data-dojo-type="dijit/MenuItem">Edit</div>
<div id="view" data-dojo-type="dijit/MenuItem">View</div>
<div id="task" data-dojo-type="dijit/PopupMenuItem">
<span>Task</span>
<div id="taskMenu" data-dojo-type="dijit/Menu">
<div id="complete" data-dojo-type="dijit/MenuItem">Mark as Complete</div>
<div id="cancel" data-dojo-type="dijit/MenuItem">Cancel</div>
<div id="begin" data-dojo-type="dijit/MenuItem">Begin</div>
</div>
</div><!-- end of sub-menu -->
</div>
<p>Last selected: <span id="lastSelected">none</span></p>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
<script>
require([
"dojo/dom",
"dojo/parser",
"dijit/registry",
"dijit/WidgetSet", // for registry.byClass
"dijit/Menu",
"dijit/MenuItem",
"dijit/PopupMenuItem",
"dojo/domReady!"
], function(dom, parser, registry){
// a menu item selection handler
var onItemSelect = function(event){
// The event handler runs in the context of the widget
dom.byId("lastSelected").innerHTML = this.get("label");
};
parser.parse();
registry.byClass("dijit.MenuItem").forEach(function(item){
item.on("click", onItemSelect);
});
});
</script>
</body>
</html>
4. Menu Structure Programmatic Demo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
135
<title>Demo: Dijit Menus</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h3>Menu Demo</h3>
<div id="mainMenu"></div>
<p>Last selected: <span id="lastSelected">none</span></p>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
<script>
require([
"dojo/dom",
"dijit/registry",
"dijit/Menu",
"dijit/MenuItem",
"dojo/domReady!"
], function(dom, registry, Menu, MenuItem){
// a menu item selection handler
var onItemSelect = function(event){
dom.byId("lastSelected").innerHTML = this.get("label");
};
// create the Menu container
var menu = new Menu({}, "mainMenu");
// create and add child item widgets
// for each of "edit", "view", "task"
menu.addChild(new MenuItem({
id: "edit",
label: "Edit",
onClick: onItemSelect
}));
menu.addChild(new MenuItem({
id: "view",
label: "View",
onClick: onItemSelect
}));
menu.addChild(new MenuItem({
id: "task",
label: "Task",
onClick: onItemSelect
}));
menu.startup();
});
</script>
</body>
</html>
5. Menu Icons
136
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo: Dijit Menus</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h3>Declarative Menu using iconClass</h3>
<div id="mainMenu" data-dojo-type="dijit/Menu">
<div data-dojo-type="dijit/MenuItem" id="edit"
data-dojo-props="iconClass: 'dijitIconEdit'">
Edit
</div>
<div data-dojo-type="dijit/MenuItem" id="view"
data-dojo-props="iconClass: 'dijitIconApplication'">
View
</div>
<div data-dojo-type="dijit/MenuItem" id="task"
data-dojo-props="iconClass: 'dijitIconTask'">
Task
</div>
</div>
<h3>Programmatic Menu using iconClass</h3>
<div id="progMenu"></div>
<p>Last selected: <span id="lastSelected">none</span></p>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
<script>
require([
"dojo/dom",
"dojo/parser",
"dijit/Menu",
"dijit/MenuItem",
"dijit/registry",
"dijit/WidgetSet", // for registry.byClass
"dojo/domReady!"
], function(dom, parser, Menu, MenuItem, registry){
// a menu item selection handler
var onItemSelect = function(event){
dom.byId("lastSelected").innerHTML = this.get("label");
};
// create equivalent programmatic example
var menu = new Menu({}, "progMenu");
menu.addChild(new MenuItem({
id: "p_edit",
137
label: "Edit",
iconClass: "dijitIconEdit"
}) );
menu.addChild(new MenuItem({
id: "p_view",
label: "View",
iconClass: "dijitIconApplication"
}) );
menu.addChild(new MenuItem({
id: "p_task",
label: "Task",
iconClass: "dijitIconTask"
}) );
menu.startup();
parser.parse();
registry.byClass("dijit.MenuItem").forEach(function(item){
item.on("click", onItemSelect);
});
});
</script>
</body>
</html>
6. Menu Variations
<!DOCTYPE html>
<html class="dj_webkit dj_chrome dj_contentbox"><head>
<meta charset="utf-8">
<title>Demo: Dijit Menus</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<style>
.tasks {
width: 23em;
list-style-type: none;
margin: 0;
padding: 0;
}
.task {
margin: 2px;
padding: 6px;
border: 1px solid #ccc;
}
.tasks .selected {
border-color: #000;
}
138
.task:hover {
border-color: #99f;
}
.begin {
background-color: #cfc;
}
.complete {
background-color: #393;
color: #fff;
}
.cancel {
background-color: #fcc;
}
</style>
</head>
<body class="claro" _dijitmenumainmenu="1">
<h3>Menu Demo</h3>
<h4>Tasks</h4>
<ul id="taskList" class="tasks" _dijitmenutaskmenu="1">
<li id="task_0" class="task">Code review</li>
<li id="task_1" class="task">Build tests</li>
<li id="task_2" class="task">Prototype UI</li>
</ul>
<!-- load dojo and provide config via data attribute -->
<script type="text/javascript" charset="utf-8" src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//Menu.js"></script><script
type="text/javascript" charset="utf-8" src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//MenuItem.js"></script><script type="text/javascript"
charset="utf-8" src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//PopupMenuItem.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//registry.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/window.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//popup.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//DropDownMenu.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//hccss.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//main.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//_Widget.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//_TemplatedMixin.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//_Contained.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//_CssStateMixin.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//place.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//BackgroundIframe.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//Viewport.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//_MenuBase.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/hccss.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//_WidgetBase.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//_OnDijitClickMixin.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//_FocusMixin.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/uacss.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/cache.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/string.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//_AttachMixin.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/touch.js"></script><script type="text/javascript" charset="utf-8"
139
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//a11yclick.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//_KeyNavContainer.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/Stateful.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//Destroyable.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//focus.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//_Container.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//_KeyNavMixin.js"></script><script type="text/javascript" charset="utf-8"
src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit//a11y.js"></script><script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"
data-dojo-config="isDebug:1, async:1"></script>
<script>
require([
"dojo/_base/lang",
"dojo/dom-class",
"dojo/mouse",
"dojo/on",
"dojo/query",
"dijit/Menu",
"dijit/MenuItem",
"dijit/PopupMenuItem",
"dijit/registry",
"dojo/domReady!"
], function(lang, domClass, mouse, on, query, Menu, MenuItem, PopupMenuItem, registry){
var demo = {
taskNodes: null, // used to store task DOM nodes for reuse later
hoveredTaskNode: null, // last task node hovered (for onTaskItemClick)
currentTaskNode: null, // currently "selected" task
classStates: ["begin", "cancel", "complete"], // state classes for tasks
// handler for clicks on task context menu items
onTaskItemClick: function(event){
// retrieve the widget representing the item clicked
var item = registry.getEnclosingWidget(event.target);
// pass the info we have along to update state
this.setTaskState(item.id);
},
setTaskState: function(state){
// remove any previous state classes and apply new one
if(this.hoveredTaskNode){
domClass.remove(this.hoveredTaskNode, this.classStates);
domClass.add(this.hoveredTaskNode, state);
}
},
// called when one of the task nodes is clicked
updateCurrentTask: function(node){
if (this.currentTaskNode){
// remove selected class from previously-selected task node
domClass.remove(this.currentTaskNode, "selected");
}
140
// add selected class to newly-selected task node
domClass.add(node, "selected");
// now that a task is selected, we can enable our task sub-menu
registry.byId("task").set("disabled", false);
// update currentTaskNode for future use
this.currentTaskNode = node;
},
// called when one of the task nodes is hovered over
updateHoveredTask: function(node){
this.hoveredTaskNode = node;
}
}
// query task nodes, saving NodeList for future use
demo.taskNodes = query(".task");
demo.taskNodes.on("click", function(event){
demo.updateCurrentTask(event.target);
});
// WebKit doesn't support native mouseenter event, so use emulated version
demo.taskNodes.on(mouse.enter, function(event){
demo.updateHoveredTask(event.target);
});
// create main menu as general context menu for entire document
var mainMenu = new Menu({
id: "mainMenu",
contextMenuForWindow: true
});
// create task menu as context menu for task nodes.
var taskMenu = new Menu({
id: "taskMenu",
targetNodeIds: ["taskList"],
selector: ".task"
});
// define the task menu items
taskMenu.addChild(new MenuItem({
id: "begin",
label: "Begin",
onClick: lang.hitch(demo, "onTaskItemClick")
}) );
taskMenu.addChild(new MenuItem({
id: "complete",
label: "Mark as Complete",
onClick: lang.hitch(demo, "onTaskItemClick")
}) );
taskMenu.addChild(new MenuItem({
141
id: "cancel",
label: "Cancel",
onClick: lang.hitch(demo, "onTaskItemClick")
}) );
// create main menu items
mainMenu.addChild(new MenuItem({
id: "about",
label: "About"
}) );
// To demonstrate dynamically disabling/enabling an item,
// this item is initially disabled until we select a task.
mainMenu.addChild(new PopupMenuItem({
id: "task",
label: "Task",
disabled: true,
// notice we reuse the same Menu as the task context menu
popup: taskMenu
}) );
mainMenu.startup();
taskMenu.startup();
});
</script>
<table class="dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable" role="menu" tabindex="0" cellspacing="0" id="taskMenu" widgetid="taskMenu"
aria-labelledby="task_text" style="display: none;">
<tbody class="dijitReset" data-dojo-attach-point="containerNode"><tr class="dijitReset dijitMenuItem" data-dojo-attach-point="focusNode"
role="menuitem" tabindex="-1" id="begin" aria-label="Begin " widgetid="begin" style="-webkit-user-select: none;">
<td class="dijitReset dijitMenuItemIconCell" role="presentation">
<span role="presentation" class="dijitInline dijitIcon dijitMenuItemIcon dijitNoIcon" data-dojo-attach-point="iconNode"></span>
</td>
<td class="dijitReset dijitMenuItemLabel" colspan="2" data-dojo-attach-point="containerNode,textDirNode" role="presentation"
id="begin_text">Begin</td>
<td class="dijitReset dijitMenuItemAccelKey" style="display: none" data-dojo-attach-point="accelKeyNode" id="begin_accel"></td>
<td class="dijitReset dijitMenuArrowCell" role="presentation">
<span data-dojo-attach-point="arrowWrapper" style="visibility: hidden">
<span class="dijitInline dijitIcon dijitMenuExpand"></span>
<span class="dijitMenuExpandA11y">+</span>
</span>
</td>
</tr><tr class="dijitReset dijitMenuItem" data-dojo-attach-point="focusNode" role="menuitem" tabindex="-1" id="complete" aria-label="Mark as Complete
" widgetid="complete" style="-webkit-user-select: none;">
<td class="dijitReset dijitMenuItemIconCell" role="presentation">
<span role="presentation" class="dijitInline dijitIcon dijitMenuItemIcon dijitNoIcon" data-dojo-attach-point="iconNode"></span>
</td>
<td class="dijitReset dijitMenuItemLabel" colspan="2" data-dojo-attach-point="containerNode,textDirNode" role="presentation"
id="complete_text">Mark as Complete</td>
<td class="dijitReset dijitMenuItemAccelKey" style="display: none" data-dojo-attach-point="accelKeyNode" id="complete_accel"></td>
<td class="dijitReset dijitMenuArrowCell" role="presentation">
<span data-dojo-attach-point="arrowWrapper" style="visibility: hidden">
142
<span class="dijitInline dijitIcon dijitMenuExpand"></span>
<span class="dijitMenuExpandA11y">+</span>
</span>
</td>
</tr><tr class="dijitReset dijitMenuItem" data-dojo-attach-point="focusNode" role="menuitem" tabindex="-1" id="cancel" aria-label="Cancel "
widgetid="cancel" style="-webkit-user-select: none;">
<td class="dijitReset dijitMenuItemIconCell" role="presentation">
<span role="presentation" class="dijitInline dijitIcon dijitMenuItemIcon dijitNoIcon" data-dojo-attach-point="iconNode"></span>
</td>
<td class="dijitReset dijitMenuItemLabel" colspan="2" data-dojo-attach-point="containerNode,textDirNode" role="presentation"
id="cancel_text">Cancel</td>
<td class="dijitReset dijitMenuItemAccelKey" style="display: none" data-dojo-attach-point="accelKeyNode" id="cancel_accel"></td>
<td class="dijitReset dijitMenuArrowCell" role="presentation">
<span data-dojo-attach-point="arrowWrapper" style="visibility: hidden">
<span class="dijitInline dijitIcon dijitMenuExpand"></span>
<span class="dijitMenuExpandA11y">+</span>
</span>
</td>
</tr></tbody>
</table><div class="dijitPopup dijitMenuPopup" role="region" aria-label="mainMenu" style="visibility: visible; top: 87px; left: 681px; right: auto;
z-index: 1000; height: auto; overflow: visible; display: none;" id="popup_2" dijitpopupparent=""><table class="dijit dijitReset dijitMenuTable
dijitMenuPassive dijitMenu dijitMenuSelected dijitSelected dijitMenuFocused dijitMenuSelectedFocused dijitSelectedFocused dijitFocused" role="menu"
tabindex="-1" cellspacing="0" id="mainMenu" widgetid="mainMenu" style="top: 0px; visibility: visible;">
<tbody class="dijitReset" data-dojo-attach-point="containerNode"><tr class="dijitReset dijitMenuItem dijitMenuItemFocused dijitFocused
dijitMenuItemSelected" data-dojo-attach-point="focusNode" role="menuitem" tabindex="0" id="about" aria-label="About " widgetid="about" style="-
webkit-user-select: none;">
<td class="dijitReset dijitMenuItemIconCell" role="presentation">
<span role="presentation" class="dijitInline dijitIcon dijitMenuItemIcon dijitNoIcon" data-dojo-attach-point="iconNode"></span>
</td>
<td class="dijitReset dijitMenuItemLabel" colspan="2" data-dojo-attach-point="containerNode,textDirNode" role="presentation"
id="about_text">About</td>
<td class="dijitReset dijitMenuItemAccelKey" style="display: none" data-dojo-attach-point="accelKeyNode" id="about_accel"></td>
<td class="dijitReset dijitMenuArrowCell" role="presentation">
<span data-dojo-attach-point="arrowWrapper" style="visibility: hidden">
<span class="dijitInline dijitIcon dijitMenuExpand"></span>
<span class="dijitMenuExpandA11y">+</span>
</span>
</td>
</tr><tr class="dijitReset dijitMenuItem dijitPopupMenuItem dijitMenuItemDisabled dijitPopupMenuItemDisabled dijitDisabled" data-dojo-attach-
point="focusNode" role="menuitem" tabindex="-1" id="task" aria-label="Task " aria-disabled="true" widgetid="task" aria-haspopup="true" style="-
webkit-user-select: none;">
<td class="dijitReset dijitMenuItemIconCell" role="presentation">
<span role="presentation" class="dijitInline dijitIcon dijitMenuItemIcon dijitNoIcon" data-dojo-attach-point="iconNode"></span>
</td>
<td class="dijitReset dijitMenuItemLabel" colspan="2" data-dojo-attach-point="containerNode,textDirNode" role="presentation"
id="task_text">Task</td>
<td class="dijitReset dijitMenuItemAccelKey" style="display: none" data-dojo-attach-point="accelKeyNode" id="task_accel"></td>
<td class="dijitReset dijitMenuArrowCell" role="presentation">
<span data-dojo-attach-point="arrowWrapper">
<span class="dijitInline dijitIcon dijitMenuExpand"></span>
<span class="dijitMenuExpandA11y">+</span>
</span>
</td>
143
</tr></tbody>
</table></div></body></html>
7. MenuBars and More Declarative Demo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo: Dijit Menus</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h3>MenuBar Demo</h3>
<div id="mainMenu" data-dojo-type="dijit/MenuBar">
<div id="edit" data-dojo-type="dijit/MenuBarItem">Edit</div>
<div id="view" data-dojo-type="dijit/MenuBarItem">View</div>
<div id="task" data-dojo-type="dijit/PopupMenuBarItem">
<span>Task</span>
<div id="taskMenu" data-dojo-type="dijit/Menu">
<div id="complete" data-dojo-type="dijit/MenuItem">Mark as Complete</div>
<div id="cancel" data-dojo-type="dijit/MenuItem">Cancel</div>
<div id="begin" data-dojo-type="dijit/MenuItem">Begin</div>
</div>
</div><!-- end of sub-menu -->
</div>
<p>Last selected: <span id="lastSelected">none</span></p>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
<script>
require([
"dojo/dom",
"dojo/parser",
"dijit/registry",
"dijit/WidgetSet", // for registry.byClass
"dijit/Menu",
"dijit/MenuItem",
"dijit/MenuBar",
"dijit/MenuBarItem",
"dijit/PopupMenuBarItem",
"dojo/domReady!"
], function(dom, parser, registry){
// a menu item selection handler
var onItemSelect = function(event){
dom.byId("lastSelected").innerHTML = this.get("label");
};
parser.parse();
144
var setClickHandler = function(item){
item.on("click", onItemSelect);
};
registry.byClass("dijit.MenuItem").forEach(setClickHandler);
registry.byClass("dijit.MenuBarItem").forEach(setClickHandler);
});
</script>
</body>
</html>
8. MenuBars and More Programmatic Demo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo: Dijit Menus</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h3>MenuBar Demo</h3>
<div id="mainMenu"></div>
<p>Last selected: <span id="lastSelected">none</span></p>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
<script>
require([
"dojo/dom",
"dijit/registry",
"dijit/Menu",
"dijit/MenuItem",
"dijit/MenuBar",
"dijit/MenuBarItem",
"dijit/PopupMenuBarItem",
"dojo/domReady!"
], function(dom, registry, Menu, MenuItem, MenuBar, MenuBarItem, PopupMenuBarItem){
// a menu item selection handler
var onItemSelect = function(event){
dom.byId("lastSelected").innerHTML = this.get("label");
};
// create the Menu container
var mainMenu = new MenuBar({}, "mainMenu");
// create Menu container and child MenuItems for our sub-menu
// (no srcNodeRef; we will add it under a PopupMenuItem)
var taskMenu = new Menu({
id: "taskMenu"
145
});
// define the task sub-menu items
taskMenu.addChild(new MenuItem({
id: "complete",
label: "Mark as Complete",
onClick: onItemSelect
}) );
taskMenu.addChild(new MenuItem({
id: "cancel",
label: "Cancel",
onClick: onItemSelect
}) );
taskMenu.addChild(new MenuItem({
id: "begin",
label: "Begin",
onClick: onItemSelect
}) );
// create and add main menu items
mainMenu.addChild(new MenuBarItem({
id: "edit",
label: "Edit",
onClick: onItemSelect
}) );
mainMenu.addChild(new MenuBarItem({
id: "view",
label: "View",
onClick: onItemSelect
}) );
// make task menu item open the sub-menu we defined above
mainMenu.addChild(new PopupMenuBarItem({
id: "task",
label: "Task",
popup: taskMenu
}) );
mainMenu.startup();
taskMenu.startup();
});
</script>
</body>
</html>
9. Menus in Widgets
146
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo: Dijit Menus</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<p>This page demonstrates declarative and programmatic usage of
<code>dijit/Menu</code> inside <code>dijit/form/ComboButton</code> and
<code>dijit/form/DropDownButton</code>.
</p>
<h3>Declarative Demo</h3>
<div id="comboButton" data-dojo-type="dijit/form/ComboButton">
<span>Do Something</span>
<div data-dojo-type="dijit/Menu">
<div data-dojo-type="dijit/MenuItem">Edit</div>
<div data-dojo-type="dijit/MenuItem">View</div>
<div data-dojo-type="dijit/MenuItem">Task</div>
</div>
</div>
<div id="dropDownButton" data-dojo-type="dijit/form/DropDownButton">
<span>Select Action</span>
<div data-dojo-type="dijit/Menu">
<div data-dojo-type="dijit/MenuItem">Edit</div>
<div data-dojo-type="dijit/MenuItem">View</div>
<div data-dojo-type="dijit/MenuItem">Task</div>
</div>
</div>
<h3>Programmatic Demo</h3>
<div id="comboBtn"></div>
<div id="dropDownBtn"></div>
<p>Last selected: <span id="lastSelected">none</span></p>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug:1, async:1"></script>
<script>
require([
"dojo/dom",
"dojo/parser",
"dijit/registry",
"dijit/Menu",
"dijit/MenuItem",
"dijit/form/ComboButton",
"dijit/form/DropDownButton",
"dijit/WidgetSet", // for registry.byClass
"dojo/domReady!"
], function(dom, parser, registry, Menu, MenuItem, ComboButton, DropDownButton){
// a menu item selection handler
var onItemSelect = function(evt){
147
dom.byId("lastSelected").innerHTML = this.get("label");
};
var menu = new Menu({ id: "mainMenu" });
// create child item widgets for each
// of 'edit','view','task'
menu.addChild(new MenuItem({
label: "Edit"
}) );
menu.addChild(new MenuItem({
label: "View"
}) );
menu.addChild(new MenuItem({
label: "Task"
}) );
// create a ComboButton and DropDownButton and add the Menu to each
var comboBtn = new ComboButton({
label: "Do Something",
dropDown: menu
}, "comboBtn");
var dropDownBtn = new DropDownButton({
label: "Select Action",
dropDown: menu
}, "dropDownBtn");
menu.startup();
comboBtn.startup();
dropDownBtn.startup();
parser.parse();
registry.byClass("dijit.MenuItem").forEach(function(item){
item.on("click", onItemSelect);
});
});
</script>
</body>
</html>
E2. Dojo Widgets Contd.. : Getting Selective with Dijit
1. Select
<!DOCTYPE html>
148
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Dijit Select</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<div style="width:50%;">
<div style="width:50%;float: left;">
<h1>dijit/form/Select</h1>
<label for="stateSelect">State:</label>
<select id="stateSelect" data-dojo-type="dijit/form/Select" name="stateSelect"
data-dojo-props="
onChange: function(value){
document.getElementById('value').innerHTML = value;
document.getElementById('displayedValue').innerHTML = this.get('displayedValue');
}">
<option value="" selected="selected">Select a state</option>
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
</select>
</div>
<div style="width:50%;float: right;"><h1>Values:</h1>
<div><strong>value:</strong> <span id="value"></span></div>
<div><strong>displayedValue:</strong> <span id="displayedValue"></span></div>
<h5>*Note how the submitted value will be the internal option value</h5>
</div>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
require(["dijit/form/Select", "dojo/parser"]);
</script>
</body>
</html>
2. FilteringSelect
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Dijit FilteringSelect</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
149
</head>
<body class="claro">
<div style="width:50%;">
<div style="width:50%;float: left;">
<h1>dijit/form/FilteringSelect</h1>
<label for="stateSelect">State:</label>
<select id="stateSelect" name="stateSelect" data-dojo-type="dijit/form/FilteringSelect"
data-dojo-props="
value: '',
placeHolder: 'Select a State',
onChange: function(value){
document.getElementById('value').innerHTML = value;
document.getElementById('displayedValue').innerHTML = this.get('displayedValue');
}">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
</select>
</div>
<div style="width:50%;float: right;"><h1>Values:</h1>
<div><strong>value:</strong> <span id="value"></span></div>
<div><strong>displayedValue:</strong> <span id="displayedValue"></span></div>
<h5>*Note how the submitted value will be the internal option value</h5>
</div>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
require(["dijit/form/FilteringSelect", "dojo/parser"]);
</script>
</body>
</html>
3. ComboBox
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Dijit ComboBox</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<div style="width:50%;">
<div style="width:50%;float: left;">
<h1>dijit/form/ComboBox</h1>
150
<label for="stateSelect">State:</label>
<select id="stateSelect" name="stateSelect" data-dojo-type="dijit/form/ComboBox"
data-dojo-props="
value: '',
placeHolder: 'Select a State',
onChange: function(value){ document.getElementById('value').innerHTML = value; }">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
</select>
</div>
<div style="width:50%;float: right;"><h1>Submitted Value: </h1>
<div id="value"></div>
<h5>*Note how the submitted value will be the displayed value</h5>
</div>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
require(["dijit/form/ComboBox", "dojo/parser"]);
</script>
</body>
</html>
E3. Dojo Widgets Contd.. : Advanced Dijit Selects using Stores
1. Select Widgets
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Dijit Select</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<div style="width:540px;">
<h1 style="text-align: center;">Programmatic Example</h1>
<div style="width:50%;float: left;">
<h1>dijit/form/Select</h1>
<label for="stateSelect">State:</label>
<div id="stateSelect"></div>
</div>
<div style="width:50%;float: right;"><h1>Values:</h1>
<div><strong>value:</strong> <span id="value"></span></div>
<div><strong>displayedValue:</strong> <span id="displayedValue"></span></div>
151
<h5>*Note how the submitted value will be the identity of the store item</h5>
</div>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
<script>
require(["dijit/form/Select", "dojo/store/Memory",
"dojo/json", "dojo/text!./states.json", "dojo/domReady!"],
function(Select, Memory, json, states){
// create store instance referencing data from states.json
var stateStore = new Memory({
idProperty: "abbreviation",
data: json.parse(states)
});
// create Select widget, populating its options from the store
var select = new Select({
name: "stateSelect",
store: stateStore,
style: "width: 200px;",
labelAttr: "name",
maxHeight: -1, // tells _HasDropDown to fit menu within viewport
onChange: function(value){
document.getElementById("value").innerHTML = value;
document.getElementById("displayedValue").innerHTML = this.get("displayedValue");
}
}, "stateSelect");
select.startup();
});
</script>
</body>
</html>
2. FilteringSelect
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Dijit FilteringSelect</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<div style="width:50%;">
<div style="width:50%;float: left;">
152
<h1>dijit/form/FilteringSelect</h1>
<label for="stateSelect">State:</label>
<select id="stateSelect" name="stateSelect" data-dojo-type="dijit/form/FilteringSelect"
data-dojo-props="
value: '',
placeHolder: 'Select a State',
onChange: function(value){
document.getElementById('value').innerHTML = value;
document.getElementById('displayedValue').innerHTML = this.get('displayedValue');
}">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
</select>
</div>
<div style="width:50%;float: right;"><h1>Values:</h1>
<div><strong>value:</strong> <span id="value"></span></div>
<div><strong>displayedValue:</strong> <span id="displayedValue"></span></div>
<h5>*Note how the submitted value will be the internal option value</h5>
</div>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
require(["dijit/form/FilteringSelect", "dojo/parser"]);
</script>
</body>
</html>
3. ComboBox
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Dijit ComboBox</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<div style="width:50%;">
<div style="width:50%;float: left;">
<h1>dijit/form/ComboBox</h1>
<label for="stateSelect">State:</label>
<select id="stateSelect" name="stateSelect" data-dojo-type="dijit/form/ComboBox"
data-dojo-props="
value: '',
153
placeHolder: 'Select a State',
onChange: function(value){ document.getElementById('value').innerHTML = value; }">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
</select>
</div>
<div style="width:50%;float: right;"><h1>Submitted Value: </h1>
<div id="value"></div>
<h5>*Note how the submitted value will be the displayed value</h5>
</div>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
require(["dijit/form/ComboBox", "dojo/parser"]);
</script>
</body>
</html>
4. Select without a Store
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Dijit Select using options</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<div style="width:540px;">
<h1 style="text-align: center;">Programmatic Example</h1>
<div style="width:50%;float: left;">
<h1>dijit/form/Select</h1>
<label for="stateSelect">State:</label>
<div id="stateSelect"></div>
</div>
<div style="width:50%;float: right;"><h1>Values:</h1>
<div><strong>value:</strong> <span id="value"></span></div>
<div><strong>displayedValue:</strong> <span id="displayedValue"></span></div>
<h5>*Note how the submitted value will be the internal option value</h5>
</div>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
<script>
154
require(["dijit/form/Select", "dojo/store/Memory", "dojo/domReady!"],
function(Select, Memory){
var select = new Select({
name: "stateSelect",
options: [
{
value: "",
label: "Select a state",
selected: true
},
{
value: "AL",
label: "Alabama"
},
{
value: "AK",
label: "Alaska"
},
{
value: "AZ",
label: "Arizona"
},
{
value: "AR",
label: "Arkansas"
},
// ... more states would go here ...
{
value: "DC",
label: "Washington, D.C.",
disabled: true // can't pick this; it's not a state!
},
{
value: "WY",
label: "Wyoming"
}
],
onChange: function(value){
document.getElementById("value").innerHTML = value;
document.getElementById("displayedValue").innerHTML = this.get("displayedValue");
}
}, "stateSelect");
select.startup();
});
</script>
</body>
</html>
E4. Dojo Widgets Contd.. : Sliders with Dijit
155
1. CreatingSliders Declarative
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Simple Horizontal and Vertical Sliders</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Simple Horizontal and Vertical Sliders</h1>
<h3>Horizontal Slider</h3>
<p>This horizontal slider ranges in value from 0-10, incrementing by 1.</p>
<div style="width: 400px;">
<!-- declaratively create a slider with buttons, values from 0-10 -->
<input id="hslider" value="3" type="range"
data-dojo-type="dijit/form/HorizontalSlider"
data-dojo-props="
minimum: 0,
maximum: 10,
discreteValues: 11">
<!-- Create an element showing the value -->
<div style="padding-top: 10px; text-align: center;">Value: <strong id="decValue"></strong></div>
<!-- Controls to play with slider -->
<div style="padding-top: 10px;">
<!-- button to enable and disable slider -->
<button id="disableButton" data-dojo-type="dijit/form/Button"
data-dojo-props="onClick: updateHorizontalState">Disable Slider</button>
</div>
</div>
<p> </p>
<h3>Vertical Slider</h3>
<p>This vertical slider ranges in value from 0-100 with no discrete values,
so the widget is freely draggable.</p>
<div id="vertSlider"></div>
<!-- Create an element showing the value -->
<div style="padding-top: 10px;">Value: <strong id="vertValue"></strong></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
<script>
// Require all dependencies
require(["dijit/form/HorizontalSlider", "dijit/form/VerticalSlider", "dijit/form/Button", "dojo/aspect", "dijit/registry", "dojo/parser",
"dojo/domReady!"],
function(HorizontalSlider, VerticalSlider, Button, aspect, registry, parser) {
// Function for updating the enabled/disabled state of the slider
updateHorizontalState = function() {
// Get the slider's current state
156
var currentState = registry.byId("hslider").get("disabled");
// Update its state
registry.byId("hslider").set("disabled", !currentState);
// Update the button text
registry.byId("disableButton").set("label", (currentState ? "Disable" : "Enable") + " Slider");
};
// Parse the page
parser.parse();
// Get access to nodes/widgets we need to get/set values
var hSlider = registry.byId("hslider"), label = document.getElementById("decValue");
// Create function that updates label when changed
function updateHorizontalLabel() {
// Update label
label.innerHTML = hSlider.get("value");
}
aspect.after(hSlider, "onChange", updateHorizontalLabel, true);
// Update label right away
updateHorizontalLabel();
// Create the vertical slider programmatically
var vertSlider = new VerticalSlider({
minimum: 0,
maximum: 100,
pageIncrement: 20,
value: 20,
intermediateChanges: true,
style: "height: 200px;"
}, "vertSlider");
var vertLabel = document.getElementById("vertValue");
function updateVerticalLabel() {
// Update label
vertLabel.innerHTML = vertSlider.get("value");
}
aspect.after(vertSlider, "onChange", updateVerticalLabel, true);
// Update label right away
updateVerticalLabel();
// Start up the widget
vertSlider.startup();
});
</script>
</body>
</html>
2. CreatingSliders Programmatically
<!DOCTYPE HTML>
157
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Simple Horizontal and Vertical Sliders</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Simple Horizontal and Vertical Sliders</h1>
<h3>Horizontal Slider</h3>
<p>This horizontal slider ranges in value from 0-10, incrementing by 1.</p>
<div style="width: 400px;">
<!-- declaratively create a slider with buttons, values from 0-10 -->
<input id="hslider" value="3" type="range"
data-dojo-type="dijit/form/HorizontalSlider"
data-dojo-props="
minimum: 0,
maximum: 10,
discreteValues: 11">
<!-- Create an element showing the value -->
<div style="padding-top: 10px; text-align: center;">Value: <strong id="decValue"></strong></div>
<!-- Controls to play with slider -->
<div style="padding-top: 10px;">
<!-- button to enable and disable slider -->
<button id="disableButton" data-dojo-type="dijit/form/Button"
data-dojo-props="onClick: updateHorizontalState">Disable Slider</button>
</div>
</div>
<p> </p>
<h3>Vertical Slider</h3>
<p>This vertical slider ranges in value from 0-100 with no discrete values,
so the widget is freely draggable.</p>
<div id="vertSlider"></div>
<!-- Create an element showing the value -->
<div style="padding-top: 10px;">Value: <strong id="vertValue"></strong></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
<script>
// Require all dependencies
require(["dijit/form/HorizontalSlider", "dijit/form/VerticalSlider", "dijit/form/Button", "dojo/aspect", "dijit/registry", "dojo/parser",
"dojo/domReady!"],
function(HorizontalSlider, VerticalSlider, Button, aspect, registry, parser) {
// Function for updating the enabled/disabled state of the slider
updateHorizontalState = function() {
// Get the slider's current state
var currentState = registry.byId("hslider").get("disabled");
// Update its state
registry.byId("hslider").set("disabled", !currentState);
// Update the button text
registry.byId("disableButton").set("label", (currentState ? "Disable" : "Enable") + " Slider");
158
};
// Parse the page
parser.parse();
// Get access to nodes/widgets we need to get/set values
var hSlider = registry.byId("hslider"), label = document.getElementById("decValue");
// Create function that updates label when changed
function updateHorizontalLabel() {
// Update label
label.innerHTML = hSlider.get("value");
}
aspect.after(hSlider, "onChange", updateHorizontalLabel, true);
// Update label right away
updateHorizontalLabel();
// Create the vertical slider programmatically
var vertSlider = new VerticalSlider({
minimum: 0,
maximum: 100,
pageIncrement: 20,
value: 20,
intermediateChanges: true,
style: "height: 200px;"
}, "vertSlider");
var vertLabel = document.getElementById("vertValue");
function updateVerticalLabel() {
// Update label
vertLabel.innerHTML = vertSlider.get("value");
}
aspect.after(vertSlider, "onChange", updateVerticalLabel, true);
// Update label right away
updateVerticalLabel();
// Start up the widget
vertSlider.startup();
});
</script>
</body>
</html>
3. Adding Rules and Rule Labels
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Horizontal and Vertical Sliders with Rules and RuleLabels</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
159
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Simple Horizontal and Vertical Sliders</h1>
<h3>Horizontal Slider</h3>
<p>This horizontal slider ranges in value from 0-10, incrementing by 1.</p>
<div style="width: 400px;">
<!-- create rules and labels above horizontal slider -->
<ol data-dojo-type="dijit/form/HorizontalRuleLabels"
data-dojo-props="
container: 'topDecoration',
count: 11,
numericMargin: 1"
style="height: 1.2em; font-weight: bold">
</ol>
<div data-dojo-type="dijit/form/HorizontalRule"
data-dojo-props="
container: 'topDecoration',
count: 11"
style="height: 5px; margin: 0 12px;"></div>
<!-- declaratively create a slider without buttons, values from 0-10 -->
<input id="hslider" type="range" value="3"
data-dojo-type="dijit/form/HorizontalSlider"
data-dojo-props="
minimum: 0,
maximum: 10,
showButtons: false,
discreteValues: 11">
<!-- create rules and labels below horizontal slider -->
<div data-dojo-type="dijit/form/HorizontalRule"
data-dojo-props="
container: 'bottomDecoration',
count: 5"
style="height: 5px; margin: 0 12px;"></div>
<ol data-dojo-type="dijit/form/HorizontalRuleLabels"
data-dojo-props="
container: 'bottomDecoration'"
style="height: 1em; font-weight: bold;">
<li>lowest</li>
<li>normal</li>
<li>highest</li>
</ol>
<!-- Create an element showing the value -->
<div style="padding-top: 10px; text-align: center;">Value: <strong id="decValue"></strong></div>
<!-- Controls to play with slider -->
<div style="padding-top: 10px;">
<!-- button to enable and disable slider -->
<button id="disableButton" data-dojo-type="dijit/form/Button"
data-dojo-props="onClick: updateHorizontalState">Disable Slider</button>
160
</div>
</div>
<p> </p>
<h3>Vertical Slider</h3>
<p>This vertical slider ranges in value from 0-100 with no discrete values,
so the widget is freely draggable.</p>
<div id="vertSlider"></div>
<!-- Create an element showing the value -->
<div style="padding-top: 10px;">Value: <strong id="vertValue"></strong></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
<script>
// Load the dependencies
require(["dijit/form/HorizontalSlider", "dijit/form/VerticalSlider", "dijit/form/HorizontalRuleLabels", "dijit/form/HorizontalRule",
"dijit/form/VerticalRuleLabels", "dijit/form/VerticalRule", "dijit/form/Button", "dojo/dom-construct", "dojo/aspect", "dijit/registry",
"dojo/parser", "dojo/dom", "dojo/domReady!"],
function(HorizontalSlider, VerticalSlider, HorizontalRuleLabels, HorizontalRule, VerticalRuleLabels, VerticalRule, Button,
domConstruct, aspect, registry, parser, dom){
// Function for updating the enabled/disabled state of the slider
updateHorizontalState = function() {
// Get the slider's current state
var currentState = registry.byId("hslider").get("disabled");
// Update its state
registry.byId("hslider").set("disabled", !currentState);
// Update the button text
registry.byId("disableButton").set("label", (currentState ? "Disable" : "Enable") + " Slider");
};
// Parse the page
parser.parse();
// Get access to nodes/widgets we need to get/set values
var hSlider = registry.byId("hslider"), label = dom.byId("decValue");
// Create function that updates label when changed
function updateHorizontalLabel() {
// Update label
label.innerHTML = hSlider.get("value");
}
aspect.after(hSlider, "onChange", updateHorizontalLabel, true);
// Update label right away
updateHorizontalLabel();
// Create the rules
var rulesNode = domConstruct.create("div", {}, dom.byId("vertSlider"), "first");
var sliderRules = new VerticalRule({
container: "leftDecoration",
count: 11,
161
style: "width: 5px;"
}, rulesNode);
// Create the labels
var labelsNode = domConstruct.create( "div", {}, dom.byId("vertSlider"), "first");
var sliderLabels = new VerticalRuleLabels({
container: "rightDecoration",
labelStyle: "font-style: italic; font-size: 0.75em"
}, labelsNode);
// Create the vertical slider programmatically
var vertSlider = new VerticalSlider({
minimum: 0,
maximum: 100,
pageIncrement: 20,
value: 20,
intermediateChanges: true,
style: "height: 200px;"
}, "vertSlider");
var vertLabel = dom.byId("vertValue");
function updateVerticalLabel() {
// Update label
vertLabel.innerHTML = vertSlider.get("value");
}
aspect.after(vertSlider, "onChange", updateVerticalLabel, true);
// Update label right away
updateVerticalLabel();
// Start up the widgets
vertSlider.startup();
sliderRules.startup();
sliderLabels.startup();
});
</script>
</body>
</html>
4. Augment Rules and Rule Labels
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Horizontal and Vertical Sliders with Rules and RuleLabels</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Simple Horizontal and Vertical Sliders</h1>
162
<h3>Horizontal Slider</h3>
<p>This horizontal slider ranges in value from 0-10, incrementing by 1.</p>
<div style="width: 400px;">
<!-- create rules and labels above horizontal slider -->
<ol data-dojo-type="dijit/form/HorizontalRuleLabels"
data-dojo-props="
container: 'topDecoration',
count: 11,
numericMargin: 1"
style="height: 1.2em; font-weight: bold">
</ol>
<div data-dojo-type="dijit/form/HorizontalRule"
data-dojo-props="
container: 'topDecoration',
count: 11"
style="height: 5px; margin: 0 12px;"></div>
<!-- declaratively create a slider without buttons, values from 0-10 -->
<input id="hslider" type="range" value="3"
data-dojo-type="dijit/form/HorizontalSlider"
data-dojo-props="
minimum: 0,
maximum: 10,
showButtons: false,
discreteValues: 11">
<!-- create rules and labels below horizontal slider -->
<div data-dojo-type="dijit/form/HorizontalRule"
data-dojo-props="
container: 'bottomDecoration',
count: 5"
style="height: 5px; margin: 0 12px;"></div>
<ol data-dojo-type="dijit/form/HorizontalRuleLabels"
data-dojo-props="
container: 'bottomDecoration'"
style="height: 1em; font-weight: bold;">
<li>lowest</li>
<li>normal</li>
<li>highest</li>
</ol>
<!-- Create an element showing the value -->
<div style="padding-top: 10px; text-align: center;">Value: <strong id="decValue"></strong></div>
<!-- Controls to play with slider -->
<div style="padding-top: 10px;">
<!-- button to enable and disable slider -->
<button id="disableButton" data-dojo-type="dijit/form/Button"
data-dojo-props="onClick: updateHorizontalState">Disable Slider</button>
</div>
</div>
<p> </p>
<h3>Vertical Slider</h3>
163
<p>This vertical slider ranges in value from 0-100 with no discrete values,
so the widget is freely draggable.</p>
<div id="vertSlider"></div>
<!-- Create an element showing the value -->
<div style="padding-top: 10px;">Value: <strong id="vertValue"></strong></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
<script>
// Load the dependencies
require(["dijit/form/HorizontalSlider", "dijit/form/VerticalSlider", "dijit/form/HorizontalRuleLabels", "dijit/form/HorizontalRule",
"dijit/form/VerticalRuleLabels", "dijit/form/VerticalRule", "dijit/form/Button", "dojo/dom-construct", "dojo/aspect", "dijit/registry",
"dojo/parser", "dojo/dom", "dojo/domReady!"],
function(HorizontalSlider, VerticalSlider, HorizontalRuleLabels, HorizontalRule, VerticalRuleLabels, VerticalRule, Button,
domConstruct, aspect, registry, parser, dom){
// Function for updating the enabled/disabled state of the slider
updateHorizontalState = function() {
// Get the slider's current state
var currentState = registry.byId("hslider").get("disabled");
// Update its state
registry.byId("hslider").set("disabled", !currentState);
// Update the button text
registry.byId("disableButton").set("label", (currentState ? "Disable" : "Enable") + " Slider");
};
// Parse the page
parser.parse();
// Get access to nodes/widgets we need to get/set values
var hSlider = registry.byId("hslider"), label = dom.byId("decValue");
// Create function that updates label when changed
function updateHorizontalLabel() {
// Update label
label.innerHTML = hSlider.get("value");
}
aspect.after(hSlider, "onChange", updateHorizontalLabel, true);
// Update label right away
updateHorizontalLabel();
// Create the rules
var rulesNode = domConstruct.create("div", {}, dom.byId("vertSlider"), "first");
var sliderRules = new VerticalRule({
container: "leftDecoration",
count: 11,
style: "width: 5px;"
}, rulesNode);
// Create the labels
164
var labelsNode = domConstruct.create( "div", {}, dom.byId("vertSlider"), "first");
var sliderLabels = new VerticalRuleLabels({
container: "rightDecoration",
labelStyle: "font-style: italic; font-size: 0.75em"
}, labelsNode);
// Create the vertical slider programmatically
var vertSlider = new VerticalSlider({
minimum: 0,
maximum: 100,
pageIncrement: 20,
value: 20,
intermediateChanges: true,
style: "height: 200px;"
}, "vertSlider");
var vertLabel = dom.byId("vertValue");
function updateVerticalLabel() {
// Update label
vertLabel.innerHTML = vertSlider.get("value");
}
aspect.after(vertSlider, "onChange", updateVerticalLabel, true);
// Update label right away
updateVerticalLabel();
// Start up the widgets
vertSlider.startup();
sliderRules.startup();
sliderLabels.startup();
});
</script>
</body>
</html>
E5. Dojo Widgets Contd.. : Dijit Themes, Buttons, and Textboxes
1. Buttons in Dijit Declarative
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Dijit Buttons</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: dijit/form/Button</h1>
<p>
165
Below, we see <code>dijit/form/Button</code> in two forms: as a standard button, and
using an icon with no label. Be sure to open the console to see messages when clicking
the buttons!
</p>
<div>
<button id="btn" data-dojo-type="dijit/form/Button"
data-dojo-props="
onClick:function(){ console.log('First button was clicked!'); }">
Click Me!
</button>
<button id="btn2" data-dojo-type="dijit/form/Button"
data-dojo-props="
iconClass:'dijitIconNewTask',
showLabel:false,
onClick:function(){ console.log('Second button was clicked!'); }">
Click Me!
</button>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
// load requirements for declarative widgets in page content
require(["dojo/parser", "dijit/form/Button", "dojo/domReady!"]);
</script>
</body>
</html>
2. Buttons in Dijit Programmatic
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Dijit Buttons</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: dijit/form/Button</h1>
<p>
Below, we see <code>dijit/form/Button</code> in two forms: as a standard button, and
using an icon with no label. Be sure to open the console to see messages when clicking
the buttons!
</p>
<div>
<button id="btn"></button>
<button id="btn2"></button>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
166
<script>
require(["dijit/form/Button", "dojo/domReady!"], function(Button) {
var button = new Button({
label: "Click Me!",
onClick: function(){ console.log("First button was clicked!"); }
}, "btn");
button.startup();
var button2 = new Button({
iconClass:"dijitIconNewTask",
showLabel:false,
label: "Click Me!", // analogous to title when showLabel is false
onClick: function(){ console.log("Second button was clicked!"); }
}, "btn2");
button2.startup();
});
</script>
</body>
</html>
3. More Buttons in Dijit Declarative
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: More Dijit Buttons</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<style>
.dj_ie8 .dijitMenuItemLabel {
position: static;
}
</style>
</head>
<body class="claro">
<h1>Demo: More dijit/form/Button(s)!</h1>
<p>
In this demo, we see three other types of buttons included in the
<code>dijit/form</code> namespace.
</p>
<div>
<button id="toggle" data-dojo-type="dijit/form/ToggleButton"
data-dojo-props="iconClass:'dijitCheckBoxIcon', checked:true">
Toggle
</button>
167
<div id="combo" data-dojo-type="dijit/form/ComboButton"
data-dojo-props="
optionsTitle:'Save Options',
iconClass:'dijitIconFile',
onClick:function(){ console.log('Clicked ComboButton'); }">
<span>Combo</span>
<div id="saveMenu" data-dojo-type="dijit/Menu">
<div data-dojo-type="dijit/MenuItem"
data-dojo-props="
iconClass:'dijitEditorIcon dijitEditorIconSave',
onClick:function(){ console.log('Save'); }">
Save
</div>
<div data-dojo-type="dijit/MenuItem"
data-dojo-props="onClick:function(){ console.log('Save As'); }">
Save As
</div>
</div>
</div>
<div id="dropDown" data-dojo-type="dijit/form/DropDownButton"
data-dojo-props="iconClass:'dijitIconApplication'">
<span>DropDown</span>
<div data-dojo-type="dijit/TooltipDialog">
This is a TooltipDialog. You could even put a form in here!
</div>
</div>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
// load requirements for declarative widgets in page content
require(["dojo/parser", "dijit/form/ToggleButton", "dijit/form/ComboButton", "dijit/Menu", "dijit/MenuItem", "dijit/form/DropDownButton",
"dijit/TooltipDialog"]);
</script>
</body>
</html>
4. More Buttons in Dijit Programmatic
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: More Dijit Buttons</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<style>
.dj_ie8 .dijitMenuItemLabel {
position: static;
168
}
</style>
</head>
<body class="claro">
<h1>Demo: More dijit/form/Button(s)!</h1>
<p>
In this demo, we see three other types of buttons included in the
<code>dijit/form</code> namespace.
</p>
<div>
<button id="toggle"></button>
<button id="combo"></button>
<button id="dropDown"></button>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
<script>
require(["dijit/form/ToggleButton", "dijit/form/ComboButton", "dijit/Menu", "dijit/MenuItem", "dijit/form/DropDownButton",
"dijit/TooltipDialog"], function(ToggleButton, ComboButton, Menu, MenuItem, DropDownButton, TooltipDialog) {
var toggleButton = new ToggleButton({
iconClass: "dijitCheckBoxIcon",
label: "Toggle",
checked: true
}, "toggle");
toggleButton.startup();
var menu = new Menu({
id: "saveMenu"
});
var menuItem1 = new MenuItem({
label: "Save",
iconClass: "dijitEditorIcon dijitEditorIconSave",
onClick: function() { console.log("Save"); }
});
var menuItem2 = new MenuItem({
label: "Save As",
onClick: function() { console.log("Save As"); }
});
menu.addChild(menuItem1);
menu.addChild(menuItem2);
var comboButton = new ComboButton({
optionsTitle: "Save Options",
iconClass: "dijitIconFile",
label: "Combo",
dropDown: menu,
onClick:function(){ console.log("Clicked ComboButton"); }
}, "combo");
comboButton.startup();
menu.startup(); // this also starts up its child MenuItems
var tooltip = new TooltipDialog({
169
content: "This is a TooltipDialog. You could even put a form in here!"
});
var dropDownButton = new DropDownButton({
iconClass: "dijitIconApplication",
label: "DropDown",
dropDown: tooltip
}, "dropDown");
dropDownButton.startup();
tooltip.startup();
});
</script>
</body>
</html>
5. Dijit TextBox Family Declarative
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Dijit TextBoxes</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>dijit/form/TextBox and dijit/form/SimpleTextarea</h1>
<div>
<label for="text">Name:</label>
<input id="text" data-dojo-type="dijit/form/TextBox"
data-dojo-props="placeHolder:'Enter text here.'">
</div>
<div>
<label for="textarea">Description:</label>
<textarea id="textarea" rows="5" cols="50"
data-dojo-type="dijit/form/SimpleTextarea"
data-dojo-props="
onFocus:function(){ console.log('textarea focus handler') },
onBlur:function(){ console.log('textarea blur handler') },
selectOnClick:true
">This is a sample SimpleTextarea.</textarea>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
// load requirements for declarative widgets in page content
require(["dojo/parser", "dijit/form/TextBox", "dijit/form/SimpleTextarea", "dojo/domReady!"]);
</script>
</body>
170
</html>
6. Dijit TextBox Family Programmatic
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Dijit TextBoxes</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>dijit/form/TextBox and dijit/form/SimpleTextarea</h1>
<div>
<label for="text">Name:</label>
<input id="text">
</div>
<div>
<label for="textarea">Description:</label>
<textarea id="textarea"></textarea>
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
<script>
require(["dijit/form/TextBox", "dijit/form/SimpleTextarea", "dojo/domReady!"], function(TextBox, SimpleTextarea) {
var textbox = new TextBox({
placeHolder: "Enter text here."
}, "text");
textbox.startup();
var textarea = new SimpleTextarea({
rows: 5,
cols: 50,
onFocus: function(){ console.log("textarea focus handler"); },
onBlur: function(){ console.log("textarea blur handler"); },
selectOnClick: true,
value: "This is a sample SimpleTextarea."
}, "textarea");
textarea.startup();
});
</script>
</body>
</html>
171
7. Functionality of Dijit TextBox Declarative
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: More Dijit TextBoxes</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<style>
body > div { margin-bottom:20px; }
</style>
</head>
<body class="claro">
<h1>dijit/form/NumberTextBox, dijit/form/CurrencyTextBox, dijit/form/TimeTextBox, dijit/form/DateTextBox</h1>
<div>
<label for="number">Age:</label>
<input id="number" type="text" value="54" required="true" data-dojo-type="dijit/form/NumberTextBox">
</div>
<div>
<label for="currency">Annual Salary:</label>
<input id="currency" value="54775.53" required="true"
data-dojo-type="dijit/form/CurrencyTextBox"
data-dojo-props="
constraints:{fractional:true},
currency:'USD',
invalidMessage:'Invalid amount. Cents are mandatory.'">
</div>
<div>
<label for="time">Start Time:</label>
<input id="time" required="true" data-dojo-type="dijit/form/TimeTextBox"
data-dojo-props="
constraints: {
timePattern: 'HH:mm:ss',
clickableIncrement: 'T00:15:00',
visibleIncrement: 'T00:15:00',
visibleRange: 'T01:00:00'
},
invalidMessage:'Invalid time.'">
</div>
<div>
<label for="date">Start Date:</label>
<input id="date" data-dojo-type="dijit/form/DateTextBox" value="2011-09-15">
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
// load requirements for declarative widgets in page content
require(["dojo/parser", "dijit/form/NumberTextBox", "dijit/form/CurrencyTextBox", "dijit/form/TimeTextBox", "dijit/form/DateTextBox",
"dojo/domReady!"]);
</script>
172
</body>
</html>
8. Functionality of Dijit textBox Programmatic
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: More Dijit TextBoxes</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<style>
body > div { margin-bottom:20px; }
</style>
</head>
<body class="claro">
<h1>dijit/form/NumberTextBox, dijit/form/CurrencyTextBox, dijit/form/TimeTextBox, dijit/form/DateTextBox</h1>
<div>
<label for="number">Age:</label>
<input id="number">
</div>
<div>
<label for="currency">Annual Salary:</label>
<input id="currency">
</div>
<div>
<label for="time">Start Time:</label>
<input id="time">
</div>
<div>
<label for="date">Start Date:</label>
<input id="date">
</div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
<script>
// load requirements for declarative widgets in page content
require(["dijit/form/NumberTextBox", "dijit/form/CurrencyTextBox", "dijit/form/TimeTextBox", "dijit/form/DateTextBox", "dojo/domReady!"],
function(NumberTextBox, CurrencyTextBox, TimeTextBox, DateTextBox) {
var number = new NumberTextBox({
value: 54,
required: true
}, "number");
number.startup();
var currency = new CurrencyTextBox({
value:54775.53,
required:true,
constraints:{fractional:true},
173
currency:"USD",
invalidMessage:"Invalid amount. Cents are mandatory."
}, "currency");
currency.startup();
var time = new TimeTextBox({
constraints: {
timePattern: "HH:mm:ss",
clickableIncrement: "T00:15:00",
visibleIncrement: "T00:15:00",
visibleRange: "T01:00:00"
},
required: true,
invalidMessage:"Invalid time."
},"time");
time.startup();
var date = new DateTextBox({
value: new Date(2011, 8, 15)
}, "date");
date.startup();
});
</script>
</body>
</html>
E6. Dojo Widgets Contd.. : Forms and Validation
1. Using dojox with HTML-based forms
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: DojoX Validate and HTML Forms</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<style type="text/css">
label {
display: inline-block;
width: 140px;
}
</style>
</head>
<body>
<h1>Demo: DojoX Validate and HTML Forms</h1>
<p>
What follows is a simple HTML form that is checked using validate.check, as well
as common validate functions. Give it a shot!
174
</p>
<p style="font-size: x-small">
* denotes required fields. Results will not be posted anywhere.
</p>
<form>
<div>
<label for="firstName">First Name*</label>
<input type="text" name="firstName" id="firstName" value="" />
</div>
<div>
<label for="lastName">Last Name*</label>
<input type="text" name="lastName" id="lastName" value="" />
<div>
</div>
<label for="email">Email Address*</label>
<input type="text" name="email" id="email" value="" />
</div>
<div>
<label for="emailConfirm">Confirm Email*</label>
<input type="text" name="emailConfirm" id="emailConfirm" value="" />
</div>
<div>
<label for="password">Password*</label>
<input type="password" name="password" id="password" value="" />
</div>
<div>
<label for="password2">Confirm Password*</label>
<input type="password" name="password2" id="password2" value="" />
</div>
<div>
<label for="phone">Phone</label>
<input type="text" name="phone" id="phone" value="" />
</div>
<input type="submit" value="Post!" />
</form>
<h3>Form validation results</h3>
<div id="result" style="border-top:1px solid #999;"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
<script>
require(["dojo/dom", "dojo/_base/array", "dojo/_base/event", "dojo/query", "dojox/validate/web", "dojox/validate/us", "dojox/validate/check",
"dojo/domReady!"],
function(dom, arrayUtil, baseEvent, query, validate) {
function doCheck(form){
var results = validate.check(form, profile),
r = dom.byId("result");
if(results.isSuccessful()){
// everything passed, log it to the result div
r.innerHTML = "Everything passed validation!";
} else {
175
var s = "";
var missing = results.getMissing();
if(missing.length){
s += '<h4>The following fields are missing:</h4>'
+ '<ol>';
arrayUtil.forEach(missing, function(field){
s += '<li>' + field + '</li>';
});
s += '</ol>';
}
var invalid = results.getInvalid();
if(invalid.length){
s += '<h4>The following fields are invalid:</h4>'
+ '<ol>';
arrayUtil.forEach(invalid, function(field){
s += '<li>' + field + '</li>';
});
s += '</ol>';
}
r.innerHTML = s;
}
}
// wait until after our requires are actually loaded.
profile = {
trim: ["firstName", "lastName"],
required: ["firstName", "lastName", "email", "emailConfirm", "password", "password2"],
constraints: {
firstName: validate.isText,
lastName: validate.isText,
password: validate.isText,
password2: validate.isText,
email: [validate.isEmailAddress, false, true],
emailConfirm: [validate.isEmailAddress, false, true],
phone: validate.us.isPhoneNumber
},
confirm: {
"emailConfirm": "email",
"password2": "password"
}
};
// set up the form handler.
var f = query("form")[0];
f.onsubmit = function(e){
baseEvent.stop(e);
doCheck(f);
};
});
</script>
176
</body>
</html>
2. Using dojox with Dijit-based Forms
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: DojoX Validation with Dijit Forms</title>
<link rel="stylesheet" href="style.css" media="screen" />
<link rel="stylesheet" href="../../_common/demo.css" media="screen" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/form/resources/CheckedMultiSelect.css" />
</head>
<body class="claro">
<h1>Demo: DojoX Validation with Dijit Forms</h1>
<p style="font-size: x-small;">
* denotes required fields. Page will simply reload on a successful form submission.
</p>
<form data-dojo-type="dijit/form/Form" method="post">
<script type="dojo/method" event="onSubmit">
if(this.validate()){
return confirm('Form is valid, press OK to submit');
}else{
alert('Form contains invalid data. Please correct first');
return false;
}
return true;
</script>
<table cellpadding="0" cellspacing="2">
<tr>
<td valign="top"><strong>First Name*: </strong></td>
<td><input type="text" required="true" name="firstName" id="firstName" placeholder="Your Name"
data-dojo-type="dijit/form/ValidationTextBox" missingMessage="Ooops! You forgot your first name!" /></td>
</tr>
<tr>
<td valign="top"><strong>Website*: </strong></td>
<td><input type="text" required="true" name="website" id="website" placeholder="Your Website"
data-dojo-type="dijit/form/ValidationTextBox" validator="dojox.validate.isUrl" /></td>
</tr>
<tr>
<td valign="top"><strong>Email*: </strong></td>
<td><input type="text" required="true" name="email" id="email" data-dojo-type="dijit/form/ValidationTextBox"
validator="dojox.validate.isEmailAddress" /></td>
</tr>
<tr>
<td valign="top"><strong>Date of Birth*: </strong></td>
<td><input type="text" required="true" name="bday" id="bday" data-dojo-type="dijit/form/DateTextBox" value="7/5/1983" /></td>
177
</tr>
<tr>
<td valign="top"><strong>Favorite Color: </strong></td>
<td>
<select name="color" id="color" data-dojo-type="dijit/form/FilteringSelect">
<option value="">Select a Color</option>
<option value="Red">Red</option>
<option value="Green">Green</option>
<option value="Blue">Blue</option>
</select>
</td>
</tr>
<tr>
<td valign="top"><strong>Favorite Toolkits: </strong></td>
<td>
<select name="toolkits" id="toolkits" data-dojo-type="dojox/form/CheckedMultiSelect" multiple="multiple"
style="width:200px;">
<option value="Dojo" selected="selected">Dojo Toolkit</option>
<option value="Moo" selected="selected">MooTools</option>
<option value="Prototype">Prototype</option>
<option value="YUI">YUI</option>
<option value="jQuery" disabled>jQuery</option>
</select>
</td>
</tr>
<tr>
<td valign="top"><strong>Send Emails? </strong></td>
<td><input type="checkbox" id="checkbox" checked="checked" data-dojo-type="dijit/form/CheckBox" /></td>
</tr>
<tr>
<td valign="top"><strong>Email Format: </strong></td>
<td>
<input type="radio" id="radio1" name="format" checked="checked" data-dojo-type="dijit/form/RadioButton" />
<label for="radio1">HTML</label>
<input type="radio" id="radio2" name="format" data-dojo-type="dijit/form/RadioButton" />
<label for="radio2">Text</label>
</td>
</tr>
</table>
<!-- submit buttons -->
<input type="submit" value="Submit Form" label="Submit Form" id="submitButton" data-dojo-type="dijit/form/Button" />
<input type="submit" value="Submit Form" id="busyButton" data-dojo-type="dojox/form/BusyButton"
label="Submit Form (Busy Button)" busyLabel="Submitting Form..." timeout="2000" />
</form>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
<script>
require(["dojo/parser",
/* dojox/ validate resources */
"dojox/validate/us", "dojox/validate/web",
178
/* basic dijit classes */
"dijit/form/CheckBox", "dijit/form/Textarea", "dijit/form/FilteringSelect", "dijit/form/TextBox", "dijit/form/ValidationTextBox",
"dijit/form/DateTextBox", "dijit/form/TimeTextBox", "dijit/form/Button", "dijit/form/RadioButton", "dijit/form/Form", "dijit/form/DateTextBox",
/* basic dojox classes */
"dojox/form/BusyButton", "dojox/form/CheckedMultiSelect",
"dojo/domReady!"]);
</script>
</body>
</html>
E7. Dojo Widgets Contd.. : Working with the Grid
1. The Grid’s Event System
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: DataGrid Events</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/grid/resources/Grid.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/grid/resources/claroGrid.css" />
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body class="claro">
<h1>Demo: DataGrid events</h1>
<p>
The following shows how to connect to and handle the <em>onRowClick</em> event in a DataGrid.
</p>
<div id="grid"></div>
<div id="results" class="results"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
<script>
require(["dojo/request",
"dojo/store/Memory",
"dojo/data/ObjectStore",
"dojox/grid/DataGrid",
"dojox/math/round",
"dojo/domReady!"],
function(request, Memory, ObjectStore, DataGrid, mathRound){
request("hof-batting.json", { handleAs: "json" }).then(function(data){
var store = new Memory({ data: data, idProperty: "id" });
// global var "test_store"
179
test_store = new ObjectStore({objectStore: store});
var grid = new DataGrid({
"class": "grid",
store: test_store,
query: { id: "*" },
structure: [
{
name: "Name", fields: ["first", "last"], width: "30%",
formatter: function(fields, rowIndex, cell){
var first = fields[0],
last = fields[1];
return last + ", " + first;
}
},
{
name: "G", field: "totalG", width: "10%",
formatter: function(games, rowIndex, cell){
return games + " <em>games</em>";
}
},
{ name: "AB", field: "totalAB", width: "10%" },
{ name: "R", field: "totalR", width: "8%" },
{ name: "H", field: "totalH", width: "9%" },
{ name: "RBI", field: "totalRBI", width: "8%" },
{
name: "Batting Average", field: "_item", width: "12%",
formatter: function(item, rowIndex, cell){
var rowData = grid.getItem(rowIndex);
return mathRound((rowData.totalH / rowData.totalAB), 3);
}
},
{
name: "Slugging %", width: "13%",
get: function(rowIndex, item){
if(!item){
return;
}
var rowData = grid.getItem(rowIndex),
hits = rowData.totalH,
doubles = rowData.total2B,
triples = rowData.total3B,
homeruns = rowData.totalHR,
total_bases = hits + doubles + (triples * 2) + (homeruns * 3),
at_bats = rowData.totalAB;
return total_bases / at_bats;
},
formatter: function(slugging){
return mathRound(slugging, 3);
}
}
180
]
}, "grid");
grid.startup();
grid.on("RowClick", function(evt){
var idx = evt.rowIndex,
rowData = grid.getItem(idx);
document.getElementById("results").innerHTML =
"You have clicked on " + rowData.last + ", " + rowData.first + ".";
}, true);
});
});
</script>
</body>
</html>
2. Getting selections from the Grid
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Selections in a Grid</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/grid/resources/Grid.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/grid/resources/claroGrid.css" />
<link rel="stylesheet" href="style.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Selections in a Grid</h1>
<p>The following grids demonstrate how selections work in a dojox/grid/DataGrid.</p>
<h2>Grid with <code>rowSelector</code></h2>
<p>
In the following Grid, no special selector view is used, but
<code>rowSelector</code> is specified in the arguments to the constructor.
</p>
<p>
The row selector behaves according to the rules of the grid's
<code>selectionMode</code>.
</p>
<div id="grid"></div>
<div id="results" class="results"></div>
<h2>Grid with <code>dojox/grid/_CheckBoxSelector</code></h2>
<p>
In the following Grid, the leftmost column is actually a separate view of type
<code>dojox/grid/_CheckBoxSelector</code>.
181
</p>
<p>
Notice how using the checkbox selectors follows its own behavior—in
this case, although the Grid is in <code>extended</code> selection mode,
which is still in effect when selecting rows via other data cells,
clicking on the checkboxes does not follow that behavior.
(In fact, it's closer to the behavior of the <code>multiple</code>
selection mode.)
</p>
<div id="grid2"></div>
<div id="results2" class="results"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
<script>
require([
"dojox/grid/DataGrid",
"dojox/grid/cells",
"dojo/store/Memory",
"dojo/data/ObjectStore",
"dojo/_base/array",
"dojo/_base/lang",
"dojox/grid/_CheckBoxSelector",
"dojo/domReady!"
], function(DataGrid, gridCells, Memory, ObjectStore, baseArray, lang, _CheckBoxSelector){
var cells = [
[
new gridCells.RowIndex({ width: "10%" }),
{ name: "Column 1", field: "col1", width: "30%" },
{ name: "Column 2", field: "col2", width: "30%" },
{ name: "Column 3", field: "col3", width: "30%" }
],[
{ name: "Column 4", field: "col4", colSpan: 4 }
]
];
gridLayout = [{
// First, our view using the _CheckBoxSelector custom type
type: "dojox.grid._CheckBoxSelector"
},
cells
];
var data = [
{ id: 0, col1: "normal", col2: false, col3: "new", col4: "But are not followed by two hexadecimal"},
{ id: 1, col1: "important", col2: false, col3: "new", col4: "Because a % sign always indicates"},
{ id: 2, col1: "important", col2: false, col3: "read", col4: "Signs can be selectively"},
{ id: 3, col1: "note", col2: false, col3: "read", col4: "However the reserved characters"},
{ id: 4, col1: "normal", col2: false, col3: "replied", col4: "It is therefore necessary"},
{ id: 5, col1: "important", col2: false, col3: "replied", col4: "To problems of corruption by"},
{ id: 6, col1: "note", col2: false, col3: "replied", col4: "Which would simply be awkward in"}
];
var objectStore = new Memory({data:data});
182
var test_store = new ObjectStore({objectStore: objectStore});
// create the grids.
var grid = new DataGrid({
store: test_store,
structure: cells,
rowSelector: "20px",
"class": "grid"
}, "grid");
grid.startup();
var grid2 = new DataGrid({
store: test_store,
structure: gridLayout,
"class": "grid"
}, "grid2");
grid2.startup();
function reportSelection(node){
var items = this.selection.getSelected();
var tmp = baseArray.map(items, function(item){
return item.id;
}, this);
var msg = "You have selected row" + ((tmp.length > 1) ? "s ": " ");
node.innerHTML = msg + tmp.join(", ");
}
grid.on("SelectionChanged",
lang.hitch(grid, reportSelection, document.getElementById("results")), true);
grid2.on("SelectionChanged",
lang.hitch(grid2, reportSelection, document.getElementById("results2")), true);
});
</script>
</body>
</html>
3. Editing data with the Grid
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Editing in a Grid</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/grid/resources/Grid.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/grid/resources/claroGrid.css" />
<link rel="stylesheet" href="style.css" media="screen">
183
</head>
<body class="claro">
<h1>Demo: Editing in a Grid</h1>
<p>The following grid shows the multiple editing capabilities built into dojox/grid/DataGrid.</p>
<div id="grid"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
<script>
require([
"dojox/grid/DataGrid",
"dojox/grid/cells",
"dojox/grid/cells/dijit",
"dojo/store/Memory",
"dojo/data/ObjectStore",
"dojo/date/locale",
"dojo/currency",
"dijit/form/DateTextBox",
"dijit/form/CurrencyTextBox",
"dijit/form/HorizontalSlider",
"dojo/domReady!"
], function(DataGrid, cells, cellsDijit, Memory, ObjectStore, locale, currency,
DateTextBox, CurrencyTextBox, HorizontalSlider){
var grid;
function formatCurrency(inDatum){
return isNaN(inDatum) ? '...' : currency.format(inDatum, this.constraint);
}
function formatDate(inDatum){
return locale.format(new Date(inDatum), this.constraint);
}
gridLayout = [{
defaultCell: { width: 8, editable: true, type: cells._Widget, styles: 'text-align: right;' },
cells: [
{ name: 'Id', field: 'id', editable: false /* Can't edit ID's of dojo/data items */ },
{ name: 'Date', field: 'col8', width: 10, editable: true,
widgetClass: DateTextBox,
formatter: formatDate,
constraint: {formatLength: 'long', selector: "date"}},
{ name: 'Priority', styles: 'text-align: center;', field: 'col1', width: 10,
type: cells.ComboBox,
options: ["normal","note","important"]},
{ name: 'Mark', field: 'col2', width: 5, styles: 'text-align: center;',
type: cells.CheckBox},
{ name: 'Status', field: 'col3',
styles: 'text-align: center;',
type: cells.Select,
options: ["new", "read", "replied"] },
{ name: 'Message', field: 'col4', styles: '', width: 10 },
{ name: 'Amount', field: 'col5', formatter: formatCurrency, constraint: {currency: 'EUR'},
widgetClass: CurrencyTextBox },
{ name: 'Amount', field: 'col5', formatter: formatCurrency, constraint: {currency: 'EUR'},
widgetClass: HorizontalSlider, width: 10}
]
184
}];
var data = [
{ id: 0, col1: "normal", col2: false, col3: "new", col4: 'But are not followed by two hexadecimal', col5: 29.91, col6: 10,
col7: false, col8: new Date() },
{ id: 1, col1: "important", col2: false, col3: "new", col4: 'Because a % sign always indicates', col5: 9.33, col6: -5, col7:
false, col8: new Date() },
{ id: 2, col1: "important", col2: false, col3: "read", col4: 'Signs can be selectively', col5: 19.34, col6: 0, col7: true,
col8: new Date() },
{ id: 3, col1: "note", col2: false, col3: "read", col4: 'However the reserved characters', col5: 15.63, col6: 0, col7: true,
col8: new Date() },
{ id: 4, col1: "normal", col2: false, col3: "replied", col4: 'It is therefore necessary', col5: 24.22, col6: 5.50, col7: true,
col8: new Date() },
{ id: 5, col1: "important", col2: false, col3: "replied", col4: 'To problems of corruption by', col5: 9.12, col6: -3, col7:
true, col8: new Date() },
{ id: 6, col1: "note", col2: false, col3: "replied", col4: 'Which would simply be awkward in', col5: 12.15, col6: -4, col7:
false, col8: new Date() }
];
var objectStore = new Memory({data:data});
// global var "test_store"
test_store = new ObjectStore({objectStore: objectStore});
// create the grid.
grid = new DataGrid({
store: test_store,
structure: gridLayout,
escapeHTMLInData: false,
"class": "grid"
}, "grid");
grid.startup();
});
</script>
</body>
</html>
F1. Working with Data: Data Modeling for MVC Applications
1. Collection Data Binding part 1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: MVC</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
185
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<style>
#container div {
cursor: pointer;
padding: 5px;
}
</style>
</head>
<body>
<h1>Demo: MVC</h1>
<h2>Store Contents</h2>
<div id="container"></div>
<p>Click any item above to load it into the editor below.</p>
<form id="form">
<div>Name:
<input type="text" name="name" />
</div>
<div>Quantity:
<input type="text" name="quantity" />
</div>
<div>Category:
<input type="text" name="category" />
</div>
</form>
<button id="sell">Sell One</button><button id="save">Save</button>
<h2>Other Actions</h2>
<button id="add">Add Shoes</button>
<button id="put-negative">Put Negative Quantity (should cause validation error)</button>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
var inventoryStore, masterStore, cacheStore, results, currentProduct;
require([
"dojo/on",
"dojo/dom",
"dojo/dom-construct",
"dojo/query",
"dojo/_base/Deferred",
"dojo/store/JsonRest",
"dojo/store/Memory",
"dojo/store/Cache",
"dojo/store/Observable",
"dojo/Stateful",
"dojo/domReady!"
], function(on, dom, domConstruct, query, Deferred, JsonRest, Memory, Cache, Observable, Stateful){
function viewResults(results){
var container = dom.byId("container");
var rows = [];
186
// results object provides a forEach method for iteration
results.forEach(insertRow);
results.observe(function(item, removedIndex, insertedIndex){
// this will be called any time an item is added, removed, and updates
if(removedIndex > -1){
removeRow(removedIndex);
}
if(insertedIndex > -1){
insertRow(item, insertedIndex);
}
}, true); // we can indicate to be notified of object updates as well
function insertRow(item, i){
var row = domConstruct.create("div", {
className: "item",
innerHTML: item.name + " quantity: " + item.quantity
});
row.itemIdentity = item.id;
rows.splice(i, 0, container.insertBefore(row, rows[i] || null));
}
function removeRow(i){
domConstruct.destroy(rows.splice(i, 1)[0]);
}
}
function viewInForm(object, form){
// copy initial values into form inputs
for(var i in object){
updateInput(i, null, object.get(i));
}
// watch for any future changes in the object
object.watch(updateInput);
function updateInput(name, oldValue, newValue){
var input = query("input[name=" + name + "]", form)[0];
if(input){
input.value = newValue;
}
}
}
var nextId = 10;
cacheStore = new Memory({});
masterStore = new JsonRest({
target: "data/",
// in order to do client side caching properly, the master store needs to be aware of the query engine to client
side filtering
queryEngine: cacheStore.queryEngine,
// a client side impl of the query we send to the server, just allows everything (unfiltered) here
"some-query": function(){
return true;
187
},
put: function(object, options){
// override this because there's no backend to handle it, assign our own id and return the object with
an id
if(!("id" in object)){
object.id = nextId++;
}
return object;
}
});
masterStore = new Observable(masterStore);
inventoryStore = new Cache(masterStore, cacheStore, {});
var oldPut = inventoryStore.put;
inventoryStore.put = function(object, options){
if(object.quantity < 0){
throw new Error("quantity must not be negative");
}
// now call the original
oldPut.call(this, object, options);
};
results = inventoryStore.query("some-query");
viewResults(results);
on(dom.byId("add"), "click", function(){
inventoryStore.add({
name: "Shoes",
category: "Clothing",
quantity: 40
});
});
on(dom.byId("put-negative"), "click", function(){
try{
inventoryStore.put({
name: "Donuts",
category: "Food",
quantity: -1
});
}catch(e){
alert(e);
}
});
on(dom.byId("sell"), "click", function(){
currentProduct && currentProduct.set("quantity", currentProduct.quantity - 1);
save();
});
function save(){
if(!currentProduct){ return; }
for(var i in currentProduct){
188
if(i != "id" && typeof currentProduct[i] != "function" && currentProduct.hasOwnProperty(i)){
console.log(i);
currentProduct[i] = query("#form input[name=" + i + "]")[0].value;
}
}
try{
inventoryStore.put(currentProduct);
}catch(e){
alert(e);
}
}
on(dom.byId("save"), "click", save);
on(dom.byId("container"), ".item:click", function(evt){
Deferred.when(inventoryStore.get(this.itemIdentity), function(item){
viewInForm(currentProduct = new Stateful(item), dom.byId("form"));
});
});
});
</script>
</body>
</html>
2. Collection Data Binding part 2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: MVC</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<style>
#container div {
cursor: pointer;
padding: 5px;
}
</style>
</head>
<body>
<h1>Demo: MVC</h1>
<h2>Store Contents</h2>
<div id="container"></div>
<p>Click any item above to load it into the editor below.</p>
<form id="form">
<div>Name:
<input type="text" name="name" />
</div>
<div>Quantity:
189
<input type="text" name="quantity" />
</div>
<div>Category:
<input type="text" name="category" />
</div>
</form>
<button id="sell">Sell One</button><button id="save">Save</button>
<h2>Other Actions</h2>
<button id="add">Add Shoes</button>
<button id="put-negative">Put Negative Quantity (should cause validation error)</button>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
var inventoryStore, masterStore, cacheStore, results, currentProduct;
require([
"dojo/on",
"dojo/dom",
"dojo/dom-construct",
"dojo/query",
"dojo/_base/Deferred",
"dojo/store/JsonRest",
"dojo/store/Memory",
"dojo/store/Cache",
"dojo/store/Observable",
"dojo/Stateful",
"dojo/domReady!"
], function(on, dom, domConstruct, query, Deferred, JsonRest, Memory, Cache, Observable, Stateful){
function viewResults(results){
var container = dom.byId("container");
var rows = [];
// results object provides a forEach method for iteration
results.forEach(insertRow);
results.observe(function(item, removedIndex, insertedIndex){
// this will be called any time an item is added, removed, and updates
if(removedIndex > -1){
removeRow(removedIndex);
}
if(insertedIndex > -1){
insertRow(item, insertedIndex);
}
}, true); // we can indicate to be notified of object updates as well
function insertRow(item, i){
var row = domConstruct.create("div", {
className: "item",
innerHTML: item.name + " quantity: " + item.quantity
});
row.itemIdentity = item.id;
190
rows.splice(i, 0, container.insertBefore(row, rows[i] || null));
}
function removeRow(i){
domConstruct.destroy(rows.splice(i, 1)[0]);
}
}
function viewInForm(object, form){
// copy initial values into form inputs
for(var i in object){
updateInput(i, null, object.get(i));
}
// watch for any future changes in the object
object.watch(updateInput);
function updateInput(name, oldValue, newValue){
var input = query("input[name=" + name + "]", form)[0];
if(input){
input.value = newValue;
}
}
}
var nextId = 10;
cacheStore = new Memory({});
masterStore = new JsonRest({
target: "data/",
// in order to do client side caching properly, the master store needs to be aware of the query engine to client
side filtering
queryEngine: cacheStore.queryEngine,
// a client side impl of the query we send to the server, just allows everything (unfiltered) here
"some-query": function(){
return true;
},
put: function(object, options){
// override this because there's no backend to handle it, assign our own id and return the object with
an id
if(!("id" in object)){
object.id = nextId++;
}
return object;
}
});
masterStore = new Observable(masterStore);
inventoryStore = new Cache(masterStore, cacheStore, {});
var oldPut = inventoryStore.put;
inventoryStore.put = function(object, options){
if(object.quantity < 0){
throw new Error("quantity must not be negative");
}
// now call the original
191
oldPut.call(this, object, options);
};
results = inventoryStore.query("some-query");
viewResults(results);
on(dom.byId("add"), "click", function(){
inventoryStore.add({
name: "Shoes",
category: "Clothing",
quantity: 40
});
});
on(dom.byId("put-negative"), "click", function(){
try{
inventoryStore.put({
name: "Donuts",
category: "Food",
quantity: -1
});
}catch(e){
alert(e);
}
});
on(dom.byId("sell"), "click", function(){
currentProduct && currentProduct.set("quantity", currentProduct.quantity - 1);
save();
});
function save(){
if(!currentProduct){ return; }
for(var i in currentProduct){
if(i != "id" && typeof currentProduct[i] != "function" && currentProduct.hasOwnProperty(i)){
console.log(i);
currentProduct[i] = query("#form input[name=" + i + "]")[0].value;
}
}
try{
inventoryStore.put(currentProduct);
}catch(e){
alert(e);
}
}
on(dom.byId("save"), "click", save);
on(dom.byId("container"), ".item:click", function(evt){
Deferred.when(inventoryStore.get(this.itemIdentity), function(item){
viewInForm(currentProduct = new Stateful(item), dom.byId("form"));
});
});
});
192
</script>
</body>
</html>
3. Richer Data Models
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: MVC</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<style>
#container div {
cursor: pointer;
padding: 5px;
}
</style>
</head>
<body>
<h1>Demo: MVC</h1>
<h2>Store Contents</h2>
<div id="container"></div>
<p>Click any item above to load it into the editor below.</p>
<form id="form">
<div>Name:
<input type="text" name="name" />
</div>
<div>Quantity:
<input type="text" name="quantity" />
</div>
<div>Category:
<input type="text" name="category" />
</div>
</form>
<button id="sell">Sell One</button><button id="save">Save</button>
<h2>Other Actions</h2>
<button id="add">Add Shoes</button>
<button id="put-negative">Put Negative Quantity (should cause validation error)</button>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
var inventoryStore, masterStore, cacheStore, results, currentProduct;
require([
"dojo/on",
"dojo/dom",
193
"dojo/dom-construct",
"dojo/query",
"dojo/_base/Deferred",
"dojo/store/JsonRest",
"dojo/store/Memory",
"dojo/store/Cache",
"dojo/store/Observable",
"dojo/Stateful",
"dojo/domReady!"
], function(on, dom, domConstruct, query, Deferred, JsonRest, Memory, Cache, Observable, Stateful){
function viewResults(results){
var container = dom.byId("container");
var rows = [];
// results object provides a forEach method for iteration
results.forEach(insertRow);
results.observe(function(item, removedIndex, insertedIndex){
// this will be called any time an item is added, removed, and updates
if(removedIndex > -1){
removeRow(removedIndex);
}
if(insertedIndex > -1){
insertRow(item, insertedIndex);
}
}, true); // we can indicate to be notified of object updates as well
function insertRow(item, i){
var row = domConstruct.create("div", {
className: "item",
innerHTML: item.name + " quantity: " + item.quantity
});
row.itemIdentity = item.id;
rows.splice(i, 0, container.insertBefore(row, rows[i] || null));
}
function removeRow(i){
domConstruct.destroy(rows.splice(i, 1)[0]);
}
}
function viewInForm(object, form){
// copy initial values into form inputs
for(var i in object){
updateInput(i, null, object.get(i));
}
// watch for any future changes in the object
object.watch(updateInput);
function updateInput(name, oldValue, newValue){
var input = query("input[name=" + name + "]", form)[0];
if(input){
194
input.value = newValue;
}
}
}
var nextId = 10;
cacheStore = new Memory({});
masterStore = new JsonRest({
target: "data/",
// in order to do client side caching properly, the master store needs to be aware of the query engine to client
side filtering
queryEngine: cacheStore.queryEngine,
// a client side impl of the query we send to the server, just allows everything (unfiltered) here
"some-query": function(){
return true;
},
put: function(object, options){
// override this because there's no backend to handle it, assign our own id and return the object with
an id
if(!("id" in object)){
object.id = nextId++;
}
return object;
}
});
masterStore = new Observable(masterStore);
inventoryStore = new Cache(masterStore, cacheStore, {});
var oldPut = inventoryStore.put;
inventoryStore.put = function(object, options){
if(object.quantity < 0){
throw new Error("quantity must not be negative");
}
// now call the original
oldPut.call(this, object, options);
};
results = inventoryStore.query("some-query");
viewResults(results);
on(dom.byId("add"), "click", function(){
inventoryStore.add({
name: "Shoes",
category: "Clothing",
quantity: 40
});
});
on(dom.byId("put-negative"), "click", function(){
try{
inventoryStore.put({
name: "Donuts",
category: "Food",
195
quantity: -1
});
}catch(e){
alert(e);
}
});
on(dom.byId("sell"), "click", function(){
currentProduct && currentProduct.set("quantity", currentProduct.quantity - 1);
save();
});
function save(){
if(!currentProduct){ return; }
for(var i in currentProduct){
if(i != "id" && typeof currentProduct[i] != "function" && currentProduct.hasOwnProperty(i)){
console.log(i);
currentProduct[i] = query("#form input[name=" + i + "]")[0].value;
}
}
try{
inventoryStore.put(currentProduct);
}catch(e){
alert(e);
}
}
on(dom.byId("save"), "click", save);
on(dom.byId("container"), ".item:click", function(evt){
Deferred.when(inventoryStore.get(this.itemIdentity), function(item){
viewInForm(currentProduct = new Stateful(item), dom.byId("form"));
});
});
});
</script>
</body>
</html>
4. Object Data Binding part 1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: MVC</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<style>
#container div {
cursor: pointer;
196
padding: 5px;
}
</style>
</head>
<body>
<h1>Demo: MVC</h1>
<h2>Store Contents</h2>
<div id="container"></div>
<p>Click any item above to load it into the editor below.</p>
<form id="form">
<div>Name:
<input type="text" name="name" />
</div>
<div>Quantity:
<input type="text" name="quantity" />
</div>
<div>Category:
<input type="text" name="category" />
</div>
</form>
<button id="sell">Sell One</button><button id="save">Save</button>
<h2>Other Actions</h2>
<button id="add">Add Shoes</button>
<button id="put-negative">Put Negative Quantity (should cause validation error)</button>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
var inventoryStore, masterStore, cacheStore, results, currentProduct;
require([
"dojo/on",
"dojo/dom",
"dojo/dom-construct",
"dojo/query",
"dojo/_base/Deferred",
"dojo/store/JsonRest",
"dojo/store/Memory",
"dojo/store/Cache",
"dojo/store/Observable",
"dojo/Stateful",
"dojo/domReady!"
], function(on, dom, domConstruct, query, Deferred, JsonRest, Memory, Cache, Observable, Stateful){
function viewResults(results){
var container = dom.byId("container");
var rows = [];
// results object provides a forEach method for iteration
results.forEach(insertRow);
results.observe(function(item, removedIndex, insertedIndex){
197
// this will be called any time an item is added, removed, and updates
if(removedIndex > -1){
removeRow(removedIndex);
}
if(insertedIndex > -1){
insertRow(item, insertedIndex);
}
}, true); // we can indicate to be notified of object updates as well
function insertRow(item, i){
var row = domConstruct.create("div", {
className: "item",
innerHTML: item.name + " quantity: " + item.quantity
});
row.itemIdentity = item.id;
rows.splice(i, 0, container.insertBefore(row, rows[i] || null));
}
function removeRow(i){
domConstruct.destroy(rows.splice(i, 1)[0]);
}
}
function viewInForm(object, form){
// copy initial values into form inputs
for(var i in object){
updateInput(i, null, object.get(i));
}
// watch for any future changes in the object
object.watch(updateInput);
function updateInput(name, oldValue, newValue){
var input = query("input[name=" + name + "]", form)[0];
if(input){
input.value = newValue;
}
}
}
var nextId = 10;
cacheStore = new Memory({});
masterStore = new JsonRest({
target: "data/",
// in order to do client side caching properly, the master store needs to be aware of the query engine to client
side filtering
queryEngine: cacheStore.queryEngine,
// a client side impl of the query we send to the server, just allows everything (unfiltered) here
"some-query": function(){
return true;
},
put: function(object, options){
// override this because there's no backend to handle it, assign our own id and return the object with
an id
198
if(!("id" in object)){
object.id = nextId++;
}
return object;
}
});
masterStore = new Observable(masterStore);
inventoryStore = new Cache(masterStore, cacheStore, {});
var oldPut = inventoryStore.put;
inventoryStore.put = function(object, options){
if(object.quantity < 0){
throw new Error("quantity must not be negative");
}
// now call the original
oldPut.call(this, object, options);
};
results = inventoryStore.query("some-query");
viewResults(results);
on(dom.byId("add"), "click", function(){
inventoryStore.add({
name: "Shoes",
category: "Clothing",
quantity: 40
});
});
on(dom.byId("put-negative"), "click", function(){
try{
inventoryStore.put({
name: "Donuts",
category: "Food",
quantity: -1
});
}catch(e){
alert(e);
}
});
on(dom.byId("sell"), "click", function(){
currentProduct && currentProduct.set("quantity", currentProduct.quantity - 1);
save();
});
function save(){
if(!currentProduct){ return; }
for(var i in currentProduct){
if(i != "id" && typeof currentProduct[i] != "function" && currentProduct.hasOwnProperty(i)){
console.log(i);
currentProduct[i] = query("#form input[name=" + i + "]")[0].value;
}
199
}
try{
inventoryStore.put(currentProduct);
}catch(e){
alert(e);
}
}
on(dom.byId("save"), "click", save);
on(dom.byId("container"), ".item:click", function(evt){
Deferred.when(inventoryStore.get(this.itemIdentity), function(item){
viewInForm(currentProduct = new Stateful(item), dom.byId("form"));
});
});
});
</script>
</body>
</html>
5. Object Data Binding part 2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: MVC</title>
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<style>
#container div {
cursor: pointer;
padding: 5px;
}
</style>
</head>
<body>
<h1>Demo: MVC</h1>
<h2>Store Contents</h2>
<div id="container"></div>
<p>Click any item above to load it into the editor below.</p>
<form id="form">
<div>Name:
<input type="text" name="name" />
</div>
<div>Quantity:
<input type="text" name="quantity" />
</div>
<div>Category:
<input type="text" name="category" />
200
</div>
</form>
<button id="sell">Sell One</button><button id="save">Save</button>
<h2>Other Actions</h2>
<button id="add">Add Shoes</button>
<button id="put-negative">Put Negative Quantity (should cause validation error)</button>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
<script>
var inventoryStore, masterStore, cacheStore, results, currentProduct;
require([
"dojo/on",
"dojo/dom",
"dojo/dom-construct",
"dojo/query",
"dojo/_base/Deferred",
"dojo/store/JsonRest",
"dojo/store/Memory",
"dojo/store/Cache",
"dojo/store/Observable",
"dojo/Stateful",
"dojo/domReady!"
], function(on, dom, domConstruct, query, Deferred, JsonRest, Memory, Cache, Observable, Stateful){
function viewResults(results){
var container = dom.byId("container");
var rows = [];
// results object provides a forEach method for iteration
results.forEach(insertRow);
results.observe(function(item, removedIndex, insertedIndex){
// this will be called any time an item is added, removed, and updates
if(removedIndex > -1){
removeRow(removedIndex);
}
if(insertedIndex > -1){
insertRow(item, insertedIndex);
}
}, true); // we can indicate to be notified of object updates as well
function insertRow(item, i){
var row = domConstruct.create("div", {
className: "item",
innerHTML: item.name + " quantity: " + item.quantity
});
row.itemIdentity = item.id;
rows.splice(i, 0, container.insertBefore(row, rows[i] || null));
}
201
function removeRow(i){
domConstruct.destroy(rows.splice(i, 1)[0]);
}
}
function viewInForm(object, form){
// copy initial values into form inputs
for(var i in object){
updateInput(i, null, object.get(i));
}
// watch for any future changes in the object
object.watch(updateInput);
function updateInput(name, oldValue, newValue){
var input = query("input[name=" + name + "]", form)[0];
if(input){
input.value = newValue;
}
}
}
var nextId = 10;
cacheStore = new Memory({});
masterStore = new JsonRest({
target: "data/",
// in order to do client side caching properly, the master store needs to be aware of the query engine to client
side filtering
queryEngine: cacheStore.queryEngine,
// a client side impl of the query we send to the server, just allows everything (unfiltered) here
"some-query": function(){
return true;
},
put: function(object, options){
// override this because there's no backend to handle it, assign our own id and return the object with
an id
if(!("id" in object)){
object.id = nextId++;
}
return object;
}
});
masterStore = new Observable(masterStore);
inventoryStore = new Cache(masterStore, cacheStore, {});
var oldPut = inventoryStore.put;
inventoryStore.put = function(object, options){
if(object.quantity < 0){
throw new Error("quantity must not be negative");
}
// now call the original
oldPut.call(this, object, options);
};
results = inventoryStore.query("some-query");
202
viewResults(results);
on(dom.byId("add"), "click", function(){
inventoryStore.add({
name: "Shoes",
category: "Clothing",
quantity: 40
});
});
on(dom.byId("put-negative"), "click", function(){
try{
inventoryStore.put({
name: "Donuts",
category: "Food",
quantity: -1
});
}catch(e){
alert(e);
}
});
on(dom.byId("sell"), "click", function(){
currentProduct && currentProduct.set("quantity", currentProduct.quantity - 1);
save();
});
function save(){
if(!currentProduct){ return; }
for(var i in currentProduct){
if(i != "id" && typeof currentProduct[i] != "function" && currentProduct.hasOwnProperty(i)){
console.log(i);
currentProduct[i] = query("#form input[name=" + i + "]")[0].value;
}
}
try{
inventoryStore.put(currentProduct);
}catch(e){
alert(e);
}
}
on(dom.byId("save"), "click", save);
on(dom.byId("container"), ".item:click", function(evt){
Deferred.when(inventoryStore.get(this.itemIdentity), function(item){
viewInForm(currentProduct = new Stateful(item), dom.byId("form"));
});
});
});
</script>
</body>
</html>
203
F2. Working with Data: Introduction to Datagrid
1. Data Grid Cells part 1
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: dojox/grid/DataGrid Simple Structure</title>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/resources/dojo.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/grid/resources/claroGrid.css" />
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body class="claro">
<h1>Demo: dojox/grid/DataGrid Simple Structure</h1>
<br/>
<div id="grid"></div>
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
var grid, dataStore, store;
require([
"dojox/grid/DataGrid",
"dojo/store/Memory",
"dojo/data/ObjectStore",
"dojo/request",
"dojo/domReady!"
], function(DataGrid, Memory, ObjectStore,request){
request.get("hof-batting.json", {
handleAs: "json"
}).then(function(data){
store = new Memory({ data: data.items });
dataStore = new ObjectStore({ objectStore: store });
grid = new DataGrid({
store: dataStore,
query: { id: "*" },
structure: [
{ name: "First Name", field: "first", width: "84px" },
{ name: "Last Name", field: "last", width: "84px" },
{ name: "Bats", field: "bats", width: "70px" },
{ name: "Throws", field: "throws", width: "70px" },
{ name: "G", field: "totalG", width: "60px" },
{ name: "AB", field: "totalAB", width: "60px" },
{ name: "Games as Batter", field: "totalGAB", width: "120px" },
{ name: "R", field: "totalR", width: "60px" },
204
{ name: "RBI", field: "totalRBI", width: "60px" },
{ name: "BB", field: "totalBB", width: "60px" },
{ name: "K", field: "totalK", width: "60px" },
{ name: "H", field: "totalH", width: "60px" },
{ name: "2B", field: "total2B", width: "60px" },
{ name: "3B", field: "total3B", width: "60px" },
{ name: "HR", field: "totalHR", width: "60px" }
]
}, "grid");
// since we created this grid programmatically, call startup to render it
grid.startup();
});
});
</script>
</body>
</html>
2. Data Grid Cells part 2
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: dojox/grid/DataGrid Cell Styles</title>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/resources/dojo.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/grid/resources/claroGrid.css" />
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<style>
.firstName {
font-style: italic;
}
.lastName {
font-weight: bold;
}
</style>
</head>
<body class="claro">
<h1>Demo: dojox/grid/DataGrid Cell Styles</h1>
<br/>
<div id="grid"></div>
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
var grid, dataStore, store;
require([
"dojox/grid/DataGrid",
205
"dojo/store/Memory",
"dojo/data/ObjectStore",
"dojo/request",
"dojo/domReady!"
], function(DataGrid, Memory, ObjectStore, request){
request.get("hof-batting.json", {
handleAs: "json"
}).then(function(data){
store = new Memory({ data: data.items });
dataStore = new ObjectStore({ objectStore: store });
grid = new DataGrid({
store: dataStore,
query: { id: "*" },
structure: [
{ name: "First Name", field: "first", width: "84px", classes: "firstName" },
{ name: "Last Name", field: "last", width: "84px", cellClasses: "lastName" },
{ name: "Bats", field: "bats", width: "70px", cellStyles: "text-align: right;" },
{ name: "Throws", field: "throws", width: "70px" },
{ name: "G", field: "totalG", width: "60px" },
{ name: "AB", field: "totalAB", width: "60px" },
{ name: "Games as Batter", field: "totalGAB", width: "120px", styles: "text-align: center;" },
{ name: "R", field: "totalR", width: "60px" },
{ name: "RBI", field: "totalRBI", width: "60px" },
{ name: "BB", field: "totalBB", width: "60px" },
{ name: "K", field: "totalK", width: "60px" },
{ name: "H", field: "totalH", width: "60px" },
{ name: "2B", field: "total2B", width: "60px" },
{ name: "3B", field: "total3B", width: "60px" },
{ name: "HR", field: "totalHR", width: "60px" }
]
}, "grid");
// since we created this grid programmatically, call startup to render it
grid.startup();
});
});
</script>
</body>
</html>
3. Data Grid Sub-rows
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: dojox/grid/DataGrid Sub-rows</title>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/resources/dojo.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/grid/resources/claroGrid.css" />
<link rel="stylesheet" href="style.css" media="screen">
206
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body class="claro">
<h1>Demo: dojox/grid/DataGrid Sub-rows</h1>
<br/>
<div id="grid"></div>
<!-- load dojo and provide config via data attribute -->
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
var grid, dataStore, store;
require([
"dojox/grid/DataGrid",
"dojo/store/Memory",
"dojo/data/ObjectStore",
"dojo/request",
"dojo/domReady!"
], function(DataGrid, Memory, ObjectStore, request){
request.get("hof-batting.json", {
handleAs: "json"
}).then(function(data){
store = new Memory({ data: data.items });
dataStore = new ObjectStore({ objectStore: store });
grid = new DataGrid({
store: dataStore,
query: { id: "*" },
structure: [
[
{ name: "First Name", field: "first", width: "84px", rowSpan: 2 },
{ name: "Last Name", field: "last", width: "84px", rowSpan: 2 },
{ name: "Bats", field: "bats", width: "70px", rowSpan: 2 },
{ name: "Throws", field: "throws", width: "70px", rowSpan: 2 },
{ name: "G", field: "totalG", width: "60px" },
{ name: "AB", field: "totalAB", width: "60px" },
{ name: "R", field: "totalR", width: "60px" },
{ name: "RBI", field: "totalRBI", width: "60px" },
{ name: "BB", field: "totalBB", width: "60px" },
{ name: "K", field: "totalK", width: "60px" }
],[
{ name: "Games as Batter", field: "totalGAB", colSpan: 2 },
{ name: "H", field: "totalH" },
{ name: "2B", field: "total2B" },
{ name: "3B", field: "total3B" },
{ name: "HR", field: "totalHR" }
]
]
}, "grid");
// since we created this grid programmatically, call startup to render it
grid.startup();
207
});
});
</script>
</body>
</html>
4. Data Grid Views part 1
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: dojox/grid/DataGrid Locking Columns</title>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/resources/dojo.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/grid/resources/claroGrid.css" />
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body class="claro">
<h1>Demo: dojox/grid/DataGrid Locking Columns</h1>
<br/>
<div id="grid"></div>
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
var grid, dataStore, store;
require([
"dojox/grid/DataGrid",
"dojo/store/Memory",
"dojo/data/ObjectStore",
"dojo/request",
"dojo/domReady!"
], function(DataGrid, Memory, ObjectStore, request){
request.get("hof-batting.json",{
handleAs: "json"
}).then(function(data){
store = new Memory({ data: data.items });
dataStore = new ObjectStore({ objectStore: store });
grid = new DataGrid({
store: dataStore,
query: { id: "*" },
structure: [
{
noscroll: true,
cells: [
{ name: "First Name", field: "first", width: "84px" },
{ name: "Last Name", field: "last", width: "84px" }
208
]
},{
cells: [
[
{ name: "Bats", field: "bats", width: "70px", rowSpan: 2 },
{ name: "Throws", field: "throws", width: "70px", rowSpan: 2 },
{ name: "G", field: "totalG", width: "60px" },
{ name: "AB", field: "totalAB", width: "60px" },
{ name: "R", field: "totalR", width: "60px" },
{ name: "RBI", field: "totalRBI", width: "60px" },
{ name: "BB", field: "totalBB", width: "60px" },
{ name: "K", field: "totalK", width: "60px" }
],[
{ name: "Games as Batter", field: "totalGAB", colSpan: 2 },
{ name: "H", field: "totalH" },
{ name: "2B", field: "total2B" },
{ name: "3B", field: "total3B" },
{ name: "HR", field: "totalHR" }
]
]
}
]
}, "grid");
// since we created this grid programmatically, call startup to render it
grid.startup();
});
});
</script>
</body>
</html>
5. Data Grid Views part 2
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: dojox/grid/DataGrid View's defaultCell</title>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/resources/dojo.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojox/grid/resources/claroGrid.css" />
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body class="claro">
<h1>Demo: dojox/grid/DataGrid View's defaultCell</h1>
<br/>
<div id="grid"></div>
<!-- load dojo -->
209
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
var grid, dataStore, store;
require([
"dojox/grid/DataGrid",
"dojo/store/Memory",
"dojo/data/ObjectStore",
"dojo/request",
"dojo/domReady!"
], function(DataGrid, Memory, ObjectStore, request){
request.get("hof-batting.json", {
handleAs: "json"
}).then(function(data){
store = new Memory({ data: data.items });
dataStore = new ObjectStore({ objectStore: store });
grid = new DataGrid({
store: dataStore,
query: { id: "*" },
structure: [
{
noscroll: true,
defaultCell: { width: "84px" },
cells: [
{ name: "First Name", field: "first" },
{ name: "Last Name", field: "last" }
]
},{
defaultCell: { width: "60px" },
cells: [
[
{ name: "Bats", field: "bats", width: "70px", rowSpan: 2 },
{ name: "Throws", field: "throws", width: "70px", rowSpan: 2 },
{ name: "G", field: "totalG" },
{ name: "AB", field: "totalAB" },
{ name: "R", field: "totalR" },
{ name: "RBI", field: "totalRBI" },
{ name: "BB", field: "totalBB" },
{ name: "K", field: "totalK" }
],[
{ name: "Games as Batter", field: "totalGAB", colSpan: 2 },
{ name: "H", field: "totalH" },
{ name: "2B", field: "total2B" },
{ name: "3B", field: "total3B" },
{ name: "HR", field: "totalHR" }
]
]
}
]
}, "grid");
// since we created this grid programmatically, call startup to render it
grid.startup();
210
});
});
</script>
</body>
</html>
F3. Working with Data: Dojo Object Store and Tree
1. Getting Started
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Object Store Demonstration</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen" type="text/css">
</head>
<body>
<h1>Object Store Demonstration</h1>
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="isDebug: 1, async: 1, parseOnLoad:
1"></script>
</script>
<script>
require(["dojo/store/Memory"], function(Memory){
var employees = [
{name:"Jim", department:"accounting"},
{name:"Bill", department:"engineering"},
{name:"Mike", department:"sales"},
{name:"John", department:"sales"}
];
employeeStore = new Memory({data:employees, idProperty: "name"});
employeeStore.query({department:"sales"}).forEach(function(employee){
// this is called for each employee in the sales department
alert(employee.name);
});
});
</script>
</body>
</html>
2. Tree with a Static Store
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
211
<title>Demo: Dijit Tree</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="style.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Dijit Tree</h1>
<div class="column" id="tree">
<h1>Tree</h1>
<div id="divTree"></div>
</div>
<div class="column">
<h1>Image</h1>
<img id="image" />
</div>
<!-- load dojo -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script>
require([
"dojo/dom",
"dojo/json",
"dojo/store/Memory",
"dijit/tree/ObjectStoreModel",
"dijit/Tree",
"dojo/text!./data/small.json",
"dojo/domReady!"
], function(dom, json, Memory, ObjectStoreModel, Tree, data){
// set up the store to get the tree data
var governmentStore = new Memory({
data: [ json.parse(data) ],
getChildren: function(object){
return object.children || [];
}
});
// set up the model, assigning governmentStore, and assigning method to identify leaf nodes of tree
var governmentModel = new ObjectStoreModel({
store: governmentStore,
query: {id: 'root'},
mayHaveChildren: function(item){
return "children" in item;
}
});
// set up the tree, assigning governmentModel;
var governmentTree = new Tree({
model: governmentModel,
onOpenClick: true,
onLoad: function(){
dom.byId('image').src = '../resources/images/root.jpg';
212
},
onClick: function(item){
dom.byId('image').src = '../resources/images/'+item.id+'.jpg';
},
persist: false
}, "divTree");
governmentTree.startup();
});
</script>
</body>
</html>
F4. Working with Data: Internationalization with the Dojo Toolkit
1. Consuming resource bundles
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Demo: i18n</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css" media="screen">
</head>
<body class="claro">
<h1>Demo: Internationalization</h1>
<h2>Change locale</h2>
<ul>
<li><a href="?en-us">en-us</a></li>
<li><a href="?de-de">de-de</a></li>
<li><a href="?fr-ca">fr-ca</a></li>
<li><a href="?pt-pt">pt-pt</a></li>
<li><a href="?es-es">es-es</a></li>
<li><a href="?zh-cn">zh-cn</a></li>
</ul>
<p>Leave your cursor over the various editor buttons in order to see the internationalized tooltips</p>
<div id="editor" data-dojo-type="dijit/Editor" data-dojo-props="style: 'height: 400px; width: 400px;', height: 400, width: 400"></div>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, locale:
location.search.substring(1)"></script>
<script>
require(["dijit/Editor", "dojo/parser", "dojo/i18n", "dojo/domReady!"]);
</script>
</body>
</html>
F5. Working with Data: Real-time Stores
213
1. Getting Started
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Real-Time Stores</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body>
<h1>Demo: Real-Time Stores</h1>
<div id="container"></div>
<button id="dow-jones">put() Dow Jones index</button>
<button id="timed-notifications">Start Timed Notifications</button>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true"></script>
<script>
var marketStore;
require(["dojo/store/Memory", "dojo/store/Observable", "dojo/query", "dojo/dom", "dojo/dom-construct", "dojo/domReady!"],
function(Memory, Observable, query, dom, domConstruct){
var data = [
{"name": "Dow Jones", "index": 12197.88, "date": new Date()},
{"name": "Nasdaq", "index": 2730.68, "date": new Date()},
{"name": "S&P 500", "index": 1310.19, "date": new Date()}
];
// create the store with the data
marketStore = new Memory({data: data, idProperty: "name"});
// wrap the store with Observable to make it possible to monitor:
marketStore = Observable(marketStore);
function viewResults(results){
var container = dom.byId("container");
var rows = [];
// functions called within observe callback below
function addRow(market, i){
// insert row into DOM, and also into our internal array
rows.splice(i, 0, domConstruct.create("div", {
innerHTML: market.name + " index: " + market.index.toFixed(2) + " at: " +
market.date.toLocaleTimeString()
}, container, i));
}
function removeRow(i){
// remove row from DOM and array (splice returns the removed items)
domConstruct.destroy(rows.splice(i, 1)[0]);
}
// add initial items, and handle future changes
results.forEach(addRow);
results.observe(function(market, removedFrom, insertedInto){
// this will be called any time a market is added, removed, or updated
if(removedFrom > -1){
214
removeRow(removedFrom);
}
if(insertedInto > -1){
addRow(market, insertedInto);
}
}, true); // we can indicate to be notified of object updates as well
}
var results = marketStore.query({});
viewResults(results);
query("#timed-notifications").on("click", function(){
setInterval(function(){
// choose a market randomly
var market = data[Math.floor(Math.random() * 3)];
// change it randomly
market.index += Math.random() - 0.5;
// update date
market.date = new Date();
// notify of the change
marketStore.notify(market, market.name);
}, 1000); // every second
});
query("#dow-jones").on("click", function(){
var dowJones = marketStore.get("Dow Jones");
dowJones.index = parseFloat(prompt("New index for Dow Jones")) || 0;
dowJones.date = new Date();
// we just do a put, the viewer automatically updates
marketStore.put(dowJones);
});
});
</script>
</body>
</html>
2. Remotely-Initiated Notifications
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Demo: Real-Time Stores</title>
<link rel="stylesheet" href="../../_common/demo.css" media="screen">
</head>
<body>
<h1>Demo: Real-Time Stores</h1>
<div id="container"></div>
<button id="dow-jones">put() Dow Jones index</button>
<button id="timed-notifications">Start Timed Notifications</button>
<!-- load dojo and provide config via data attribute -->
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js" data-dojo-config="async: true"></script>
215
<script>
var marketStore;
require(["dojo/store/Memory", "dojo/store/Observable", "dojo/query", "dojo/dom", "dojo/dom-construct", "dojo/domReady!"],
function(Memory, Observable, query, dom, domConstruct){
var data = [
{"name": "Dow Jones", "index": 12197.88, "date": new Date()},
{"name": "Nasdaq", "index": 2730.68, "date": new Date()},
{"name": "S&P 500", "index": 1310.19, "date": new Date()}
];
// create the store with the data
marketStore = new Memory({data: data, idProperty: "name"});
// wrap the store with Observable to make it possible to monitor:
marketStore = Observable(marketStore);
function viewResults(results){
var container = dom.byId("container");
var rows = [];
// functions called within observe callback below
function addRow(market, i){
// insert row into DOM, and also into our internal array
rows.splice(i, 0, domConstruct.create("div", {
innerHTML: market.name + " index: " + market.index.toFixed(2) + " at: " +
market.date.toLocaleTimeString()
}, container, i));
}
function removeRow(i){
// remove row from DOM and array (splice returns the removed items)
domConstruct.destroy(rows.splice(i, 1)[0]);
}
// add initial items, and handle future changes
results.forEach(addRow);
results.observe(function(market, removedFrom, insertedInto){
// this will be called any time a market is added, removed, or updated
if(removedFrom > -1){
removeRow(removedFrom);
}
if(insertedInto > -1){
addRow(market, insertedInto);
}
}, true); // we can indicate to be notified of object updates as well
}
var results = marketStore.query({});
viewResults(results);
query("#timed-notifications").on("click", function(){
setInterval(function(){
// choose a market randomly
var market = data[Math.floor(Math.random() * 3)];
// change it randomly
market.index += Math.random() - 0.5;
216
// update date
market.date = new Date();
// notify of the change
marketStore.notify(market, market.name);
}, 1000); // every second
});
query("#dow-jones").on("click", function(){
var dowJones = marketStore.get("Dow Jones");
dowJones.index = parseFloat(prompt("New index for Dow Jones")) || 0;
dowJones.date = new Date();
// we just do a put, the viewer automatically updates
marketStore.put(dowJones);
});
});
</script>
</body>
</html>