Upload
sampetruda
View
3.920
Download
0
Embed Size (px)
Citation preview
1
●Carol McDonald
1
Ajax Frameworks and Toolkits:dojo , dynafaces, woodstock
Speaker’s Qualifications
• 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)
Agenda• AJAX Basics
> AJAX Interaction:Using Sample Application • AJAX Toolkits and Frameworks
> Dojo Client-side JavaScript Library> AJAX-enabled JavaServer Faces components
AJAX Basics:AJAX Basics:What is AJAX?What is AJAX?
What is AJAX?• AJAX= acronym for:
> Asynchronous JavaScript and XML• Browser client uses JavaScript to Asynchronously
get XML data from a server • Now ~ DHTML
User Interface: Traditional Web vs. AJAX
User operation stops whilethe data is beingfetched
StatelessHTML View
Browser
Stateful Server
Synchronous call
New HTML page
011001100111100101101011
011001101101111110010100011010111101110011010110
StatefulJavaScript™ UI
Browser
Stateless Server
Asynchronous call
Data only, not HTML
Events handled locally
01100111
011010011011
AJAX No interruption in user interface displayOnly new information updated on page
Traditional Web AJAX
within a browser, there is AJAX engine
Current Issues with AJAX• 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
Dojo Client SideDojo Client SideJavaScript LibraryJavaScript Library
What is Dojo Toolkit?• 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
Dojo features
• Object Oriented Class Helpers• Modules• Events• XHR (Ajax)• Drag and Drop• Dojo.data• Dojo.query• Back button handling• i18n
Dojo Toolkit Libraries
Dojo base • 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
Dojo core • 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
Dojo dijit and dojox dijit • Interface widgets • Advanced UI controls• Template drivendojoX• Inventive, innovative
Dojo Functions Everywhere• 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.
Dojo Query// 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 For Each Function• 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
Quick Installation• 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
Run File themeTester.html
Try out dojo dijit widgets
dijit dijit ddojo Widgetsojo Widgets
dijit is a UI widget system layered on top of dojoThe dojo Widget Library
What is a dojo Widget?• 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
Form Widgets• CheckBox, RadioButton,ComboBox,
CurrencyTextBox, DateTextBox, NumberTextBox, Slider, ValidationTextBox, Textarea
• Attributes: disabled, intermediateChanges, tabIndex• Methods: focus, getValue, setValue, setDisabled,
undo, isValid• Extension Points: onChange, execute
Example dijit.form.DateTextBox<script>
dojo.require("dijit.form.DateTextBox");</script>
<body><input type="text" name="date1"
value="2005-12-30"dojoType="dijit.form.DateTextBox"required="true" />
Dijit Layout• Accordion Container,Content Pane, Layout
Container, Split Container, Stack Container, Tab Container
Example 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>
Dijit Command Control• Button, ComboButton, DropDownButton, Menu,
Toolbar
Example 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 systemDojo Event system
dojo Event HandlingDojo 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 Topicsvar 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] );
XMLHttpRequest (XHR)XMLHttpRequest (XHR)
Dojo Hello WorldDojo Hello World
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
The sayHello Servlet
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
Dojo dataDojo data
Passing Data with JSONvar 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 JSONdojo.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...});
Example dijit.form.FilteringSelectstates.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"}]}
Example dijit.form.FilteringSelect<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
Dojo rpcDojo rpc
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 DropDrag and Drop
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
Dojo backDojo back
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>
Dojo Pro's And Con's
• 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
Summary
• AJAX helps make applications more interactive> But AJAX does not come for free> Start small and don’t overdo it> Choose the right Toolkits and Frameworks for your
application
Dojo 1.0• 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
For More Information
• http://dojotoolkit.org/
AJAX Toolkits andAJAX Toolkits andFrameworks:Frameworks:AJAX-EnabledAJAX-EnabledJavaServer FacesJavaServer Faces ComponentsComponents
JSF : 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()
BusinessService
guess()Next view XML File
What is a JSF UI Component?Some Standard Components
Some Open Source Components
Custom Components
NetBeans Visual Web Pack
Components> So... what is a component?
ComponentJava Class
JSP Custom Tag
Renderer
Handles input
Displays HTML
Use in yourJSP page
UIComponents and Binding to a Managed Bean
Client Server
A
B
C
BackingBeanForm
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
JSF Web Framework
View
Client
Faces Servlet
ManagedBean
ActionFormJSP
Controller Model
RequestService Interface
Component
config(xml)
Renderer
BusinessService
Events
AJAX-enabled JSF Components• 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
““ AutoComplete” AutoComplete” Sample Using a Sample Using a JavaServer Faces JavaServer Faces ComponentComponent
Example Ajax enabled JSF • JSF AJAX Auto Complete Component
JSP View of JavaServer Faces 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
Ajax JSF Component Renderer> 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
ComponentJava Class
JSP Custom Tag
Renderer
HTML Rendered in Browser
<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.
anatomy• 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
anatomy• 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.
Ajax & JSF• 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/
Dynamic Faces• 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
DynaFaces Usage Patterns
• 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
Views and Partial Views
The Importance of the Lifecycle
DynaFaces and the JSF LifecycleLifecycle Review
” execute‘ portion of Lifecycle
” render‘ portion of Lifecycle
2007 JavaOne SM Conference | Session TS - 6410 | 89
Dynamic Faces—AjaxZone componentajaxZone
● 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
ajaxZone<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 inthis zone
Render in this zone
DynaFaces <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
Executethese components
Render this component
Project Woodstock• 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
Woodstock Architecture
Orange: Orange: component component developerdeveloperYellow: JSF-Yellow: JSF-ExtensionsExtensions
Demonstration
>Woodstock components: Ajax enabled JavaServer Faces components
Future directions• 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 And Con's• 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 3rd 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
Summary & Summary & ResourcesResources
Summary
• AJAX helps make applications more interactive> But AJAX does not come for free> Start small and don’t overdo it> Choose the right Toolkits and Frameworks for your
application
For More Information• 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
Dojo 1.0