You are on page 1of 100

1

!
Carol McDonald
1
Carol cDonald:
>
Java Architect at Sun Microsystems
>
Before Sun, worked on software development of:
>Application to manage car Loans for Toyota (>10 million loans)
>Pharmaceutical Intranet apps (Roche Switzerland)
>Telecom Network Mgmt (Digital France)
>X.400 Email Server (IBM Germany)
AJAX Basics
>
AJAX Interaction:Using Sample Application
AJAX Toolkits and Frameworks
>
Dojo Client-side JavaScript Library
>
AJAX-enabled JavaServer Faces components
AJAX= acronym for:
>
Asynchronous JavaScript and XML
Browser client uses JavaScript to Asynchronously
get XML data from a server
Now ~ DHTML
User operation
stops while
the data is being
fetched
Stateless
HTML View
Browser
Stateful
Server
Synchronous call
New HTML page
01100110
01111001
01101011
011001101101
111110010100
011010111101
110011010110
Stateful
JavaScript UI
Browser
Stateless
Server
Asynchronous call
Data only, not HTML
Events
handled
locally
0110
0111
0110
1001
1011
AJAX
No interruption in user interface display
Only new information updated on page
within a browser,
there is AJAX engine
JavaScript
>
inconsistent support among browsers
>
requires cross browser testing
>
code is visible to a hacker
>
Can be difficult to develop , debug, and
maintain
>Mozilla FireBug debugger (add-on)
>
automatic testing is hard
>Selenium
Open Source set of JavaScript libraries
Simplifies adding AJAX into web pages!
Major industry support (Sun, IBM, AOL)
http://dojotoolkit.com/
Server side technology independent
source: dojotoolkit.org
features
Object Oriented Class Helpers
Modules
Events
XHR (Ajax)
Drag and Drop
Dojo.data
Dojo.query
Back button handling
i18n
Browser detection
JSON encoding/decoding
Package loading
Unified events
Animation
Asynchronous programming support (dojo.Deferred)
High-performance CSS3 query engine
Language utilities
CSS style and positioning utilities
Object-oriented programming (OOP) support
Memory leak protection
Firebug integration
data access (dojo.data)
debugging tools (integrated Firebug Lite)
Drag and drop
i18n support, Localizations
Date formatting,Number formatting, String utilities
Progressive-enhancement behavior engine
Cookie handling
Extended animations
Remote procedure calling (RPC), including JSON-P
Back button handling
Baseline CSS styling
dijit and dojox
dijit
Interface widgets
Advanced UI controls
Template driven
Inventive, innovative

dojo.require("dojo.module");
>
Load a module

dojo.byId("id")
>
Same as
document.getElementById("someid");

dijit.byId("id")
> returns a Dijit widget instance;

dojo.addOnLoad("functionname")
>
defers script execution until all
the HTML is loaded.
// Query by tag. Equivalent to
// document.getElementsByTagName("IMG");
dojo.query("img");

// Query by class.
dojo.query(".progressIndicator");

// Query by id. Equivalent to
// document.getElementById("widget123");
// or dojo.byId("widget123")
dojo.query("widgetId");

dojo.forEach(queueEntries,
function(oneEntry) {
console.debug(oneEntry);
}
);
>
Execute a function in a for loop
dojo.query ("select", document). forEach ("item.disabled
= true;");
>
disables all SELECT tags on the page
Download from http://dojotoolkit.org/downloads
Unzip the file, rename top folder to src
Create a Netbeans project. Copy src folder into the
web folder of your Netbeans project :
Setting up javascript in the page
<head>
<title>Dojo: Hello World!</title>
<!-- SECTION 1 -->
<style type="text/css">
@import "src/dijit/themes/tundra/tundra.css";
@import "dojoroot/dojo/resources/dojo.css"
</style>
<script type="text/javascript"
djConfig="parseOnLoad: true"
src="src/dojo/dojo.js" >
</script>
</head>
<body class="tundra">
</body>
script element is responsible for
loading the base Dojo script
dijit is a UI widget system layered on top of dojo
Is a UI element such as a button, text box, scroll
bar, calendar, tree etc
>
Easy to use
>
Event handlers can be registered on widget
>
handle browser incompatibilities
HTML+CSS bound by JavaScript
CheckBox, RadioButton,ComboBox,
CurrencyTextBox, DateTextBox, NumberTextBox,
Slider, ValidationTextBox, Textarea
Attributes: disabled, intermediateChanges, tabIndex
Methods: focus, getValue, setValue, setDisabled,
undo, isValid
Extension Points: onChange, execute
<script>
dojo.require("dijit.form.DateTextBox");
</script>
<body>
<input type="text" name="date1"
value="2005-12-30"
dojoType="dijit.form.DateTextBox"
required="true" />
Accordion Container,Content Pane, Layout
Container, Split Container, Stack Container, Tab
Container
dijit.layout.AccordionContainer
<script>
dojo.require("dojo.parser ");
dojo.require("dijit.layout.Accordi onContainer ");
</script>
<body>
<div dojoType="dijit.layout.AccordionContainer" duration="200"
style="margin-right: 30px; width: 400px; height: 300px; overflow: hidden">
<div dojoType="dijit.layout.AccordionPane" selected="true" title="Pane1">
<p > some text ...</p > <!-- content inline -->
</div>

<div dojoType="dijit.layout.AccordionPane" title="Pane2"
href="tab1.html" > <!-- content reference -->
</div>
</div>
Button, ComboButton, DropDownButton, Menu,
Toolbar
dijit.Menu
<script>
dojo.require("dojo.parser ");
dojo.require("dijit.Menu ");
</script>
<body>
<div dojoType="dijit.Menu " id="submenu1"
contextMenuForWindow="true" style="display: none;">
<div dojoType="dijit.MenuItem " iconClass="myIcon"
onClick="alert('Hello world');"> Enabled Item </div>
<div dojoType="dijit.PopupMenuItem " id="submenu2">
Enabled Submenu
<div dojoType="dijit.Menu ">
<div dojoType="dijit.MenuItem "
onClick="alert('Submenu 1!')">
Submenu Item One</div>
. . .
</div>
Dojo Event System
Makes the JavaScript event system easier to use
connect a function of your own to:
>
a DOM event, such as when a link is clicked
>
an event of an object, such as an animation starting or
stopping
>
function call of your own, such as bar();
>
topic, which other objects can publish objects to.
dojo.event.connect(srcObj,"srcFunc",
targetFunc);
function myFunction () {
alert("dojo.connect handler");
}
var link = dojo.byId("mylink");
dojo.event.connect(link, "onclick", myFunction );
<a href="#" id="mylink">Click Me</a>
Connecting Objects and Functions
var someObject = {
bar: function() { console.debug("Bar fired!"); return 14; }
}
var anotherObject = {
anotherBar: function () { console.debug("anotherBar fired!"); }
}
dojo.connect(someObject, "bar", anotherObject, "anotherBar");
sourceObj, "sourceFunc", targetObj, targetFunc
disonnecting Functions
objectConnections[1] = dojo.connect (someObject, "baz",
anotherObject, "afterBaz");
dojo.disconnect (objectConnections[1] );
Subscribing and Publishing Topics
var someObject = {
bar : (first, second) {
console.debug("Bar fired with: "+first+" and: "+second); return;
},
}
topics[1] = dojo.subscribe ("fullNames ", "someObject ", bar);
dojo.publish ("fullNames ", ["Alex", "Russell"]);
dojo.unsubscribe (topics[1] );
Setting up javascript in the page
<head>
<title>Dojo: Hello World!</title>
<!-- SECTION 1 -->
<style type="text/css">
@import "src/dijit/themes/tundra/tundra.css";
@import "dojoroot/dojo/resources/dojo.css"
</style>
<script type="text/javascript"
djConfig="parseOnLoad: true"
src="src/dojo/dojo.js" >
</script>
</head>
<body class="tundra">
</body>
script element is responsible for
loading the base Dojo script
Creating a Button Widget
<head>
...
<script type="text/javascript">
dojo.require("dijit.form.Button");
</script>
...
</head>
<body class="tundra">
<button dojoType="dijit.form.Button"
id="helloButton">Hello World!
</button>
</body>
load the appropriate modules
dojoType = widget
Connecting an Event to the Widget
<head>
...
<script type="text/javascript">
dojo.require("dijit.form.Button");
</script>
...
</head>
<body class="tundra">
Name: <input name="Name" id="name" type="text" />
<button dojoType="dijit.form.Button" id="helloButton">
Hello World!
<script type="dojo/method" event="onClick">
makeAjaxCall();
</script>
</button>
</body>
attach an event to button through
a script type of dojo/method
Getting Data from the Server
<head>
<script type="text/javascript">
function makeAjaxCall(){
dojo.xhrGet({
url: 'sayHello',
load: helloCallback,
error: helloError,
content: {name: dojo.byId('name').value }
});
}
function helloCallback(data,ioArgs) {
dojo.byId("returnMsg").innerHTML = data;
}
</script>
</head>
<body>
Name: <input name="Name" id="name" type="text" />
<button dojoType="dijit.form.Button"
<script type="dojo/method" event="onClick">
makeAjaxCall();
...
<p id=returnMsg></p>
</body>
call url
Callback function
Content to send
On error function
public class sayHello extends HttpServlet {
. . .
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException {

response.setContentType("text/html;charset=UTF-8");
String returnString = request.getParameter("name");
PrintWriter out = response.getWriter();
if (returnString == null || returnString.isEmpty()) {
returnString = "<br>Name is required.";
out.println("Error: " + returnString);
} else {
out.println("Hello: " + returnString);
}
}
Content type text/xml
dojo.xhrPost a Form
<head>
<script type="text/javascript">
function makeAjaxCall(){
dojo.xhrPost({
url: 'sayHello',
load: helloCallback,
error: helloError,
form: 'myForm'
});
}
function helloCallback(data,ioArgs) {
dojo.byId("returnMsg").innerHTML = data;
}
</script>
</head>
<body>
<form id="myForm" method="POST">
Name: <input type="text" name="name">
</form>
<button dojoType="dijit.form.Button"
<script type="dojo/method" event="onClick">
makeAjaxCall();
<p id=returnMsg></p>
</body>
xhrPost
Form
Passing Data with JSON
var cobblers = [
{"filling": "peach", "timeToBake": 30 },
{"filling": "cherry", "timeToBake": 35 },
{"filling": "blueberry", "timeToBake": 30}
];
{ "cobblers": [
{"filling": "peach", "timeToBake": 30 },
{"filling": "cherry", "timeToBake": 35 },
{"filling": "blueberry", "timeToBake": 30}
]
}
Java script objects
in code
Java Script object
notation
over the wire
Passing Data with JSON
dojo.xhrGet( {
// The following URL must match that used to test the server.
url: "http://server/ajax.txt",
handleAs: "json",
load: function( responseObject , ioArgs) {
// Now you can just use the object
console.dir(responseObject .cobblers[0].filling ); // Prints "peach"
return responseObject;
}
// More properties for xhrGet...
});
states.json JSON content :
{identifier: "abbreviation",
items: [
{name: "Alabama", label: "Alabama", abbreviation: "AL"},
{name:"Alaska", label:"Alaska",abbreviation:"AK"},
. . .
{name:"Wisconsin", label:"Wisconsin",abbreviation:"WI"},
{name:"Wyoming", label:"Wyoming",abbreviation:"WY"}
]}
<script>
dojo.require("dojo.parser");
dojo.require("dijit.form.FilteringSelect");
dojo.require("dojo.data.ItemFileReadStore");
</script>
</head>
<body>
<div dojoType= " dojo.data.ItemFileReadStore " jsId=" stateStore "
url=" states.json "></div>
<form method="post">
<input dojoType="dijit.form.FilteringSelect"
store=" stateStore "
searchAttr="name"
name="state1"
autocomplete="true"
/>
<input type="submit" value="Go!" />
</form>
Use states in select menu
Read states
Simple data source pantry_items.json
{ identifier: 'name',
items: [
{ name: 'Adobo', aisle: 'Mexican' },
{ name: 'Balsamic vinegar', aisle: 'Condiments' },
{ name: 'Basil', aisle: 'Spices' },
{ name: 'Bay leaf', aisle: 'Spices' },
{ name: 'Beef Bouillon Granules', aisle: 'Soup' },
{ name: 'Vinegar', aisle: 'Condiments' },
{ name: 'White cooking wine', aisle: 'Condiments' },
{ name: 'Worcestershire Sauce', aisle: 'Condiments' }
]}
Data in json format in
a file on server
Simple data source read store
<script>
dojo.require("dojo.parser");
dojo.require("dijit.form.FilteringSelect");
dojo.require("dojo.data.ItemFileReadStore");
</script>
<div dojoType=" dojo.data.ItemFileReadStore " jsId=" pantryStore "
url=" pantry_items.json ">
</div>
<label for="setvaluetest">spices :</label>
<div name="pantry_item" dojoType=" dijit.form.Filteri ngSelect "
store=" pantryStore " searchAttr="name"
value="Vinegar" autoComplete="true">
</div>
Read from Data store
Use data in select menu
Simple Method Description (SMD) file
{
"serviceType": "JSON-RPC",
"serviceURL": "rpcProcessor.jsp",
"methods":[
{
"name": "add",
"parameters":[
{"name": "x"},
{"name": "y"}
]
}
]
}
Simple Method Description
(SMD)
Remote Procedure Call (RPC)
var myObject = new
dojo.rpc.JsonService("definition.smd");
var myDeferred =
myObject.add(3,5).addCallback(myCallbackMethod);
rpc method
Call back
Smd file
Simple Method Description (SMD) file
{
"SMDVersion":".1",
"objectName":"yahoo",
"serviceType":"JSON-P",
"required": {
"appId": "dojotoolkit",
"output": "json"
},
"methods":[ // WEB SEARCH
{
// http://developer.yahoo.com/search/web/V1/webSearch.html
"name":"webSearch",
"serviceURL":
"http://api.search.yahoo.com/WebSearchService/V1/webSearch",
"parameters":[
{ "name":"query", "type":"STRING" },
{ "name":"type", "type":"STRING" }, // defaults to "all"
{ "name":"region", "type":"STRING" }, // defaults to "us"
...
]
},...
]
}
Simple Method Description
(SMD)
Remote Procedure Call (RPC)
var svc = new
dojo.rpc.JsonpService(dojo.moduleUrl("dojox.rpc",
"yahoo.smd"), {appid: "dojoApp"});
var td = svc.webSearch({query:"dojotoolkit"});

td.addCallbacks(function(result){
alert("callback 1st result "+
result["ResultSet"]["Result"][0]
["DisplayUrl"]);
});
JSON-P style service
Call back
Drag and Drop
<script>
dojo.require("dojo.dnd.source");
dojo.require("dojo.parser");
</script>
<h3>Source 1</h3>
<div dojoType="dojo.dnd.Source" jsId="c1" class="container">
<div class="dojoDndItem">Item Alpha</div>
<div class="dojoDndItem">Item Beta</div>
<div class="dojoDndItem">Item Gamma</div>
<div class="dojoDndItem">Item Delta</div>
</div>
<h3>Pure Target 2</h3>
<div dojoType="dojo.dnd.Target" jsId="c2" class="container">
<div class="dojoDndItem">One item</div>
</div>
source
target
Preventing losing state on back
<head>
<script type="text/javascript"
src="src/dojo/dojo.js"
djConfig="preventBackButtonFix: false">
</script>
<script>
dojo.require("dojo.back");
dojo.back.setInitialState(state);
var state = {
back: function() {
alert("Back was clicked!"); },
forward: function() {
alert("Forward was clicked!"); }
};
function myFunction() {
dojo.back.addToHistory(state);
}
</script>
</head>
<body>
Pro's
>
You can use it with any server side technology
>
Make Ajax easier, takes care of browser problems
>
Can mix with other Javascript frameworks
Con's
>
Developer still has to learn some JavaScript (Jmaki can
make this easier)
When to use
>
You need to work with multiple server side technologies
>
You want to use JavaScript and make it easier
AJAX helps make applications more interactive
>
But AJAX does not come for free
>
Start small and dont overdo it
>
Choose the right Toolkits and Frameworks for your
application

The material for this presentation comes


from the Book of dojo at:
>
http://dojotoolkit.org/

There is a Free AJAX Programming online


course at:
http:www.javapassion.com/ajaxcodecamp

http://dojotoolkit.org/
server side Component, Event Driven
Framework
!
Pages composed of server side components
!
Component events handled by JavaBeans
UIIput id=guessNum
UICommand id=submit
View Root
Form id=guess
Backing Bean
getUserNumber()
setUserNumber(..)
guess()
Business
Service
guess()
Next view
XML File
Some Standard Components
>
So... what is a component?
Component
Java Class
JSP Custom
Tag
Renderer
Handles input
Displays HTML
Use in your
JSP page
and Binding to a Managed
Bean
Client Server
A
B
C
Backing
Bean
Form
c1 A
c2 B
c3 C
c1
c2
c3
A
B
C
Page
public class UserNumberBean {
int number = 0;
String getNumber();
void setNumber(int number) ;
. . .
}

<h:inputText id="userNo" label="User Number"
value ="#{UserNumberBean .number }"
Bean property
View
Client
Faces
Servlet
Managed
Bean
Action
Form
JSP

Controller
Model
Request
Service
Interface
Component
config
(xml)
Renderer
Business
Service
Events
Enables Rapid Application Development (RAD) :
>
drag and drop AJAX-enabled Faces components within IDE's
>
Sun NetBeans Visual Web Pack, Oracle JDeveloper, IBM
websphere jsf, BEA Workshop for JSF, Exadel, Borland,
JetBrains, Genuietc, others
hides complexity of AJAX programming
>
Don't need to know JavaScript
third-party UI component market:
>
AJAX enabled: Tomahawk,Tobago,Trinidad, ICEfaces,
RCFaces, Netadvantage, WebGalileoFaces, QuipuKit,
BluePrints, Exadel, Backbase, Simplica, Ajax4jsf, Dynafaces
JSF AJAX Auto Complete Component
!
<%@taglib prefix="ui" uri="http://java.sun.com/blueprints/ui/14"%>
2.
3.<h:form id="autofillform">
4. <h:outputText value="City:" />
5.<ui:completionField id="cityField"
6. value="#{SessionBean.city}"
7. completionMethod="#{AutoCompleteBean.completeCity}"
8. ondisplay="function(item) { return extractCity(item); }"
9. onchoose="function(item) { return chooseCity(item); }"
10. />
Remotely Calling Managed Bean Method
event handler
>
When page is displayed the first time:
>
Renders the HTML for the form elements
>
Renders the reference to the JavaScript code that handles the form
events
Component
Java Class
JSP Custom
Tag
Renderer
<script type=" text/javascript " src=" /autocomplete1/faces/static/META-
INF/autocomplete/script.js "></ script >
<input
id="autofillform:cityFiel d" type="text"
onfocus ="autofillform_cityField.start()""
/>
rendered by the custom component:
JavaScript handlers which call methods
to initiate & handle asynchronous calls when
keys are pressed.
onkeyup event occurs
>
JavaScript function mapped to this event:
>
creates an XMLHttpRequest object
>
XMLHttpRequest.open() with URL=
faces/autocomplete&id=San.
>
This XMLHttpRequest.send() calls FacesServlet
Server side: FacesServlet calls AutoComplete
bean, which provides the completion logic.
>
returns XML document
Client side: The XMLHttpRequest callback
function (set by generated javascript handlers)
updates the DOM based on the contents of the
XML document that was returned.
Three AJAX integration strategies:
>
Add AJAX support to existing components:
>Ajax4jsf
>DynaFaces, Woodstock
>
Integrate AJAX support into JSF extension
>ICEsoft ICEfaces, Shale
>
Wrap existing AJAX widgets
>jMaki
Full listing at http://www.jsfcentral.com/

Brings the power of AJAX to JSF

Expose the JSF Lifecycle to the browser via Ajax


"
Allow operating on the entire view, or a part of it
mark one or more AJAX
zones within a page
Zones will refresh via
AJAX, without full page
refresh.
Using AjaxZones
1. Click something in here
2. See update here
Action in one
zone
causes reaction in
another zone
Lifecycle Review
execute
portion of Lifecycle
render
portion of Lifecycle
2007 JavaOne
SM
Conference | Session TS - 6410 | 89

Dynamic FacesAjaxZone component
ajaxZone
!
Renders JavaScript for components
!
<input>, <option>, <button> ...(customizable)
!
Default event type is click (customizable)
!
Default interactions (all are customizable):
!
Execute inputs within this zone only
!
Re-render this zone only
<jsfExt:ajaxZone id="zone1">
<h:panelGrid columns="2">
Base Price
<h: outputText binding="#{ currentModel.basePrice }"/>
</h:panelGrid>
</jsfExt:ajaxZone>
<jsfExt:ajaxZone id="zone2" render =" zone1" execute="zone2"
action="#{carstore.currentModel.updatePricing}">
Option Packages <h:panelGrid columns="4">
<h:commandButton value="Custom"
actionListener ="#{carstore.choosePackage}"/>
..
</jsfExt:ajaxZone>
Execute in
this zone
Render in this zone
<h:form id="form" prependId="false">
<h:inputText id="input" value="#{testBean.name}"/>
<h:commandButton id="button"
actionListener="#{testBean.changeText}"
onclick="DynaFaces.fireAjaxTransaction(this,
{execute: 'input', 'button',
render: 'text'}); return false;"
value="click"/>
<h:outputText id="text" value="#{testBean.text}"/>
</h:form>
Using DynaFaces.fireAjaxTransaction
Execute
these
components
Render this
component
JSF Custom Components: extend Dynafaces with
Dojo
Features like auto-validation, auto-save can
automatically update other widgets
https://woodstock.dev.java.net/index.html
Orange: Orange:
component component
developer developer
Yellow: JSF- Yellow: JSF-
Extensions Extensions
>
Woodstock components: Ajax enabled
JavaServer Faces components
JSF 2.0 will incorporate features from:
>
DynaFaces
>Single, integrated API for Ajax component developers
>Will include JavaScript bindings
>
Apache Shale
>
JBoss Seam
>
Facelets

Informal collaboration agreement with Exadel


(Ajax4JSF), ICESoft (ICEFaces)
Pro's
>
Drag-and-dropping AJAX-enabled JavaServer Faces
components within an IDE for building AJAX application
>
Page authors do not need to know JavaScript
>
Can take advantage of JSF features (rich framework)
Con's
>
programming AJAX-enabled JavaServer Faces
components is not easy for component developer (can
use 3
rd
party)
When to use
>
When you want to build AJAX apps by drag-and-dropp'ing
>
When want to use JavaServer Faces
>
When you want to avoid JavaScript coding
AJAX helps make applications more interactive
>
But AJAX does not come for free
>
Start small and dont overdo it
>
Choose the right Toolkits and Frameworks for your
application
Web 2.0 & ajax
>
http://developers.sun.com/web/
>
http://developers.sun.com/ajax/
JSF Dynafaces
>
https://jsf-extensions.dev.java.net/
Woodstock
>
https://woodstock.dev.java.net/
100
!
Carol McDonald

100

You might also like