Take control of your SAP testing with UiPath Test Suite
Ajax tutorial
1. ion ’s
n an d D Ajax
Be
Tutorial
ajaxians@ajaxian.com
2. Ben Galbraith Kevin Lynch
Chief Software Architect Dion Almaer
Co-founder, Ajaxian.com Adobe Co-founder, Ajaxian.com
Independent Consultant Google Shill
Conservative Liberal
3. Ajax: A New Approach to Web Applications
by Jesse James Garrett February 18, 2005
“Google Suggest and Google Maps are
two examples of a new approach to web
applications that we at Adaptive Path have
been calling Ajax. The name is shorthand
for Asynchronous JavaScript + XML, and it
represents a fundamental shift in what’s
possible on the Web.”
4. Ajax: A New Approach to Web Applications
by Jesse James Garrett February 18, 2005
“Google Suggest and Google Maps are
two examples of a new approach to web
applications that we at Adaptive Path have
been calling Ajax. The name is shorthand
for Asynchronous JavaScript + XML, and it
represents a fundamental shift in what’s
possible on the Web.”
5. Ajax: A New Approach to Web Applications
by Jesse James Garrett February 18, 2005
“Google Suggest and Google Maps are
two examples of a new approach to web
applications that we at Adaptive Path have
been calling Ajax. The name is shorthand
for Asynchronous JavaScript + XML, and it
represents a fundamental shift in what’s
possible on the Web.”
6. Ajax: A New Approach to Web Applications
by Jesse James Garrett February 18, 2005
8. Ajax == DHTML
• Key Ajax ingredient:
• XMLHttpRequest (a.k.a. XMLHTTP)
• Introduced by MS in 1997
• Copied by Mozilla 1.0 in 2002
• innerHTML helps a great deal
• DOM API snobs notwithstanding
9. XMLHttpRequest
Method Description
open("method", "URL"[, asyncFlag[, "userName"[,
"password"]]])
Setup the request (note the asyncFlag parameter)
send(content) Send the request; “content” is request body (i.e. POST data)
abort() Stop a request in process
getAllResponseHeaders() Return a hash of header/value pairs
getResponseHeader(”header”) Retrieve a response header value
setRequestHeader(”label”, “value”) Set header (overriding browser headers allowed)
10. XMLHttpRequest
Property Description
onreadystatechange Reference to callback function
Current state of XHR; one of:
0 = uninitialized
1 = loading
readyState
2 = loaded
3 = interactive
4= complete
responseText Text value of response body
responseXML DOM tree of response body
status Numeric status code (e.g., 200, 404)
statusText Text status message corresponding to status code
11. Three Main Ajaxian
Architectures
Return HTML
Return Data Return JavaScript
(responseText +
(JSON / XML) (eval)
innerHTML)
22. Web / Ajax Myths
• Ajax is hard
• Cross-browser differences are painful
• Rich effects (and widgets) are best left to
desktop applications
• Off-line mode isn’t possible
• Client-side validation is a pain
23. dojo.gfx
• A graphics library built on top of SVG and
VML
• Think portable SVG subset for IE
• Like SVG, exposes a DOM for accessing
and manipulating paths
24. dojo.gfx
var node = document.createElement("div");
document.body.appendChild(node);
var surfaceWidth = 120;
var surfaceHeight = 220;
var surface = dojo.gfx.createSurface(node,surfaceWidth,
surfaceHeight);
var rect = { x: 100, y: 0, width: 100, height: 100 };
var circle = { cx: 150, cy: 160, r: 50 };
var group = surface.createGroup();
var blueRect = group.createRect(rect)
.setFill([0, 0, 255, 0.5])
.applyTransform(dojo.gfx.matrix.identity);
var greenCircle = group.createCircle(circle)
.setFill([0, 255, 0, 1.0])
.setStroke({color: "black", width: 4, cap: "butt",
join: 4})
.applyTransform(dojo.gfx.matrix.identity);
25. Ajax vs. Desktop Apps
Ajax Advantages Desktop Advantages
Ease of development model Much faster than JavaScript
Ease of deployment Advanced graphical capabilities
Mash-ups Tight integration with OS
Separation of concerns Mature UI toolkits
Hackability (e.g., Greasemonkey) Lack of hackability (e.g., security)
27. Ajaxian Frameworks
RAD High-level Tools
(TIBCO, Backbase)
Server-side Web Frameworks
(ASP.NET, JSF + ICEfaces, Tapestry, Rails)
JavaScript
Client-side Frameworks Tools
(Effects + Remoting) and
(Dojo, Prototype + Script.aculo.us, jQuery, Moo.fx + other Moo tools)
Utilities
XMLHttpRequest IFrame ...
28. Ajaxian Client-side
Frameworks
Prototype Script.aculo.us Dojo
DWR GWT jQuery moo tools
Behaviour MochiKit Rico qooxdoo Yahoo! UI
and a thousand other frameworks...
29. Prototype
• Prototype takes the pain out of common Ajax
tasks
• Tightly integrated with Ruby-on-Rails
• Can be used with any backend
• Now documented! (by the community)
• Reclusive maintainer
30. Prototype Contents
• Prototype provides three levels of
functionality:
• Utility functions (globally scoped)
• Custom objects
• Extended properties on JavaScript native
and hosted objects
• Some folks consider this a no-no
31. Basic Utilities
• Prototype contains a number of tools that take the pain out of
DOM manipulation:
• $() function - shortcut for Document.getElementById
• Can take multiple arguments and will return all matching
elements
• $F() function - returns the value of any form control
• Pass it either the element id or the element object
• $$() function - select elements based on CSS selectors
• Pass it a CSS selector expression
32. More Basic Utilities
• Try.these() function - takes functions as
arguments and returns the return value of the
first function that doesn’t throw an exception.
var returnValue;
for (var i = 0; i < arguments.length; i++) {
var lambda = arguments[i];
try {
returnValue = lambda();
break;
} catch (e) {}
}
return returnValue;
33. Ajax Helpers
• The Ajax object provides a number of
helpful Ajax-related functionality
• At its simplest, can be used to obtain XHR
in a cross-browser way:
var xhr = Ajax.getTransport()
34. Ajax Helpers
• Implementation of Ajax.getTransport():
var Ajax = {
getTransport: function() {
return Try.these(
function() {return new XMLHttpRequest()},
function() {return new ActiveXObject('Msxml2.XMLHTTP')},
function() {return new ActiveXObject('Microsoft.XMLHTTP')}
) || false;
}
}
35. Ajax Helpers
• Provides higher-level functionality for
performing Ajax operations:
• Ajax.Request() object - takes a url and
an “options” object as arguments
• Performs an XHR request
• Options argument specifies XHR
configuration parameters and one or more
callbacks
37. Ajax.Request Example
var request = new Ajax.Request(
‘/someUrl’,
{ method: get, onComplete; myCallBack }
);
function myCallBack(xhr) {
$(‘someElementId’).innerHTML = xhr.responseText;
}
38. Ajax Helpers
• Ajax.Updater() object - takes an element id,
a url and an “options” object as arguments
• Executes XHR and displays response as
contents (innerHTML) of specified element
• First argument can be an anonymous object with
a success property and a failure property
set to the ids of elements
• Executes JavaScripts contained in response
HTML
40. Ajax Helpers
• Ajax.PeriodicalUpdater() object - takes
an element id, a url and an “options” object as
arguments
• Same behavior as Ajax.Updater() but
continuously performs request every 2 seconds
• frequency property on options object
controls the update frequency in seconds
• stop() function halts the updating; start()
function can restart it
41. JavaScript Extensions
• Number.toColorPart() function -
converts decimal to hex
• String.stripTags() function - removes
any tags from the string
• String.escapeHTML(),
String.unescapeHTML()
• Document.getElementsByClassName()
42. Custom Objects
• Element object makes manipulating elements
much easier:
• Element.show(), Element.hide(),
Element.toggle() - take an unlimited
number of element id or references
• Show/hide based on CSS display attribute
• Element.remove() - nukes element by id
or reference from the DOM
43. Custom Objects
• Element.addClassName(),
Element.hasClassName(),
Element.removeClassName() - take two arguments:
element id (or reference) and the class name
• Field.clear() - takes an unlimited number of form
element ids or references and clears their values
• Field.present() - takes form elements ids or references;
returns true if all are non-blank
• Field.focus(), Field.select(),
Field.activate() - takes an element id/ref, and focuses,
selects, or focuses/selects
44. Custom Objects
• Form.serialize() - takes form element id/
ref; returns the HTTP query string
• Form.getElements() - takes form element
id/ref; returns array with all form elements
• Form.disable(), Form.enable(),
Form.focusFirstElement(),
Form.reset() - take form element id/ref
45. And Much More...
• Prototype also contains utilities for
inserting values into existing HTML
content, event handling, JavaScript object
definition, HTML element positioning, and
more
48. Comet
• Server-push for the Web
• Not really, but a close approximation: a
persistent XHR connection
• Overkill for most “push” applications (i.e., just do
polling)
• Dojo’s Comet implementation is cometd
• Jetty supports cometd
49. DWR
• DWR (Direct Web Remoting) provides
tight integration with Java
• DWR provides two major functions:
• A dynamic Java→JavaScript proxy
generation library (engine.js)
• Utility library of miscellaneous JavaScript
functionality (util.js)
50. Using DWR
• Step 1: Add the DWR servlet to your
project
• Step 2: Create a DWR configuration file
• Step 3: Add DWR JavaScript to your HTML
51. JavaScript Example
<script type="text/javascript" src="/dwr/engine.js"></script>
<script type="text/javascript" src="/dwr/Validator.js"></script>
<script type=”text/javascript”>
Validator.echoMethod(‘Hello, world!’, callback);
function callback(data) {
alert(data);
}
</script>
public String echoMethod(String arg) {
return arg;
}
52. Additional Features
• Worried about latency? DWR allows you to
batch opereations:
• DWREngine.beginBatch()
• DWREngine.endBatch()
• Race conditions caused by asynchronicity got you
down?
• DWREngine.setOrdered(true) forces serial
FIFO execution of DWR requests
53. DWR “Reverse Ajax”
WebContext wctx = WebContextFactory.get();
String chatPage = wctx.getCurrentPage();
// Find all the browser on window open on the chat page:
Collection sessions = wctx.getScriptSessionsByPage(chatPage);
// Use the Javascript Proxy API to empty the chatlog
// <ul> element and re-fill it with new messages
Util utilAll = new Util(sessions);
utilAll.removeAllOptions("chatlog");
utilAll.addOptions("chatlog", messages, "text");
59. Offline Web via Open Web
• Why just solve this problem for Google?
• Why not solve it for others?
• Solution: Make it open source with a liberal license
• New BSD
60. Why?
“How often are you on a plane?”
• Reliability
• 1% of downtime can hurt at the wrong time
• Performance
• Local acceleration
• Convenience
• Not having to find a connection
• You are offline more than you think!
61. What is the philosophy?
• One application, one URL
• Seamless transitions between online and offline
• Ability to use local data, even when online
• Available to all users on all platforms
• ... and a pony
63. What is the philosophy?
Do for offline what XMLHttpRequest did for web apps
Ajax Libraries Gears Libraries
Dojo, jQuery, Prototype, GWT Dojo Offline, GWT
XMLHttpRequest Gears
Open Web Open Web
64. Gears Architecture
• Read and write using local store
• Changes are queued for later synchronization
• Server communication is completely decoupled from UI actions, happens
periodically whenever there is a connection
66. Database
Embedded using SQLite
Contributed Full Text Search
var db = google.gears.factory.create('beta.database', '1.0');
db.open('database-demo');
db.execute('create table if not exists Demo (Phrase varchar(255),
Timestamp int)');
db.execute('insert into Demo values (?, ?)', [phrase, currTime]);
var rs = db.execute('select * from Demo order by Timestamp desc');
67. Mouse Moved
Mouse Pressed
Mouse Released
Key Pressed
Operating System Key Released
Event Queue
User Code Painting, etc.
“UI Thread”
68. Mouse Moved
Mouse Pressed
Mouse Released
Key Pressed
Operating System Key Released
Event Queue
Web
JavaScript
Browsing
Browser
69. Jakob Nielsen
Noted Usability Expert
Prolific Author
“The basic advice regarding response times has been about
the same for thirty years:
“0.1 second is about the limit for having the user feel
that the system is reacting instantaneously, meaning that no
special feedback is necessary except to display the result.
“1.0 second is about the limit for the user's flow of
thought to stay uninterrupted, even though the user will
notice the delay. Normally, no special feedback is necessary
during delays of more than 0.1 but less than 1.0 second, but
the user does lose the feeling of operating directly on the
data.”
70. 1
“UI Thread”
User Interface
2
Background
Thread
71. 1
Browser
User Interface
X
2
Background
Thread
73. Firefox Off-line Details
• <link rel="offline-resource"> to put
resources into the browser's off-line cache
• Entire applications can live in a JAR bundle,
which can then be cached off-line
• Off-line mode driven by browser-generated
off-line / online events
74. function loaded() {
updateOnlineStatus("load", false);
document.body.addEventListener ("offline",
function () { updateOnlineStatus("offline", true) },
false);
document.body.addEventListener("online",
function () { updateOnlineStatus("online", true) },
false);
if (typeof globalStorage != "undefined") {
var storage = globalStorage[storageDomain];
if (storage && storage.taskStorage) {
taskStorage = storage.taskStorage ;
}
}
fetchList();
}
function fetchList() {
if (navigator.onLine ) {
httpRequest("GET", null, loadList);
} else {
loadList(4, 200, taskStorage);
}
}
81. Fancy-pants browser
graphics are here today
• SVG was widely anticipated but hasn’t
made an impact
• Canvas has started to appear
• Google’s ExplorerCanvas project brings it
to IE
84. The Server-less Ajax
Application
• Amazon S3 provides storage
• Amazon EC2 provides hosting
• Local persistent storage is here
• And more options around the corner...
• Growing popularity of web services
85. Imagine the Power of
Client-side SQL!
<script language="javascript">
// First we precompile the query language object with the schema...
var queryLang = TrimPath.makeQueryLang(columnDefs);
// Next, we do a SELECT statement.
var statement = queryLang.parseSQL(
"SELECT Customer.id, Customer.acctBalance, Invoice.total " +
"FROM Customer, Invoice " +
"WHERE Customer.id = Invoice.custId " +
"ORDER BY Customer.id ASC");
// Here we run the query...
var results = statement.filter(tableData);
// Tada! That's it -- the results now holds the joined,
// filtered, and sorted output of our first query.
// Also, we can convert the statement back to a SQL string...
statement.toString() ==
"SELECT Customer.id, Customer.acctBalance, Invoice.total " +
"FROM Customer, Invoice " +
"WHERE Customer.id = Invoice.custId " +
"ORDER BY Customer.id ASC"
</script>
86. We used to hate when
people asked us about
accessibility...
87. Enter Unobtrusive
JavaScript
Goals:
Keep the HTML Increase Reusable
clean Accessibility Components
(JS out of it) (Degrade) (Tie with CSS)
89. Creating an Unobtrusive
Component
<abbr class="searchterm using:news" title="ajax">
Ajax
</abbr>
Steps for creating nice unobtrusive code:
1) What would look good in HTML (create the microformat)
2) Create a JavaScript component that can create what you need
3) Have a builder that bridges the HTML and the Components
90. Step 1: Microformat
<abbr class="searchterm
using:blog
withstyle:expanded
orderby:relevance"
title="search for ajax">
Ajax
</abbr>
• abbr plays nice in browsers
• although a better title.You do the work in the JS
• options to tweak the component directly from HTML
92. Step 3: Bridge Builder
var RelatedSearchFinder = {
find: function() {
var count = 0;
$$('.searchterm').each(function(node) {
new RelatedSearch(node, ++count);
});
}
};
Event.observe(window, 'load',
RelatedSearchFinder.find, false);
• Selectors are the future (Dom.minimize!)
• Also add functionality via: $('comments').addClassName('active')
93. Accessibility
• W3C Accessible Rich Internet Applications (WAI-ARIA)
• IBM is leading the charge
• A lot of their work is donated to the Dojo Toolkit
• We overload HTML elements with meaning that
readers and other devices don’t understand
• WAI-ARIA defines Roles
• A role helps define WHAT something is
• <div role="wairole:slider">
• progressbar, slider, button, tree, textfield, checkbox,
alert, and dialog
• WAI-ARIA defines Stats
• A state helps add meaning
• <input type="text" name="email" aaa:required="true" />
• <div role="wairole:button" aaa:controls="price">
• <h2 id="price" aaa:sort="descending">price</h2>
94. The Future?
• Apollo as the Web+ Platform?
• Off-line Ajax Abundant
• Abundant custom rendering
• Microformats?
• Fast JavaScript interpreters
• “Wow” versus the Web
• HTML 5