w ritin g w ith y u i - webguiw ritin g w ith y u i d o u g b e ll d e v e lo p e r / j a n ito r d...
TRANSCRIPT
Writing with YUIDoug Bell
Developer / [email protected]
JavaScriptAn Epic Tale
Interface with Java Applets
Has been standardized (EMCAScript)
Annoying “features” being avoided / disabled
Featureful, Intuitive, Dynamic User Interfaces
Break out of Stagnant Static Sites
From Harmful To Helpful
JavaScriptAn Epic Tale
Programmer’s Perspective
JavaScript Sucks in Web Browsers
Non-standard Implementations
Different behaviors between “standard” implementations
Some simple tasks are made difficult
Into the gap: JavaScript Libraries
Which One?
Dojo, Prototype, Scriptaculous, jQuery
October 2006 - Community weighs in
Consensus: Yahoo User Interface (YUI)
Why YUI?
Free as in Speech
Free as in Beer
Backed by Yahoo
Fully-featured API
Extensible API
Well-Documented
Well-Supported
Well-defined Levels of Support (Graded Support)
What is YUI?A satellite view
YUI Components
YUI Core
Base of the system
DOM and Event handling
Normalization
Utilities
Components to build applications
Connection Manager for XmlHttpRequest(aka AJAX)
Animation and Drag and Drop
YUI Components
Controls / Widgets
AutoComplete
Calendar, Color Picker, Rich Text Editor, Slider
TabView
TreeView
CSS Tools
Reset
Base
Font
Grids
In this Session
YUI Core
DOM
Event
Animation
Connection
We’ll create a functional, if a bit silly, Asset...
Shoutbox
Users can chat real-time on your website
ShoutboxUnder the hood
Default view
Handles the normal view of the asset
Creates the form for input
JSON view
Gets the asset’s information in JSON
Will be very useful later on
YUI + DOMChocolate + Peanut Butter
Before
HTML in the template
Useful but not re-useful
Let’s make something New!
Before<div id="shoutbox"><tmpl_if chat><ul><tmpl_loop chat><li> <span class="timestamp">
^D("%z %Z",<tmpl_var timestamp>);</span>
- <span class="from"><tmpl_var from></span>: <tmpl_var bodyText>
</li></tmpl_loop></ul></tmpl_if>
<tmpl_var form_start>From: <tmpl_var form_from><br/>Text: <tmpl_var form_bodyText><tmpl_var form_submit><tmpl_var form_end>
</div>
Before<div id="shoutbox"><tmpl_if chat><ul><tmpl_loop chat><li> <span class="timestamp">
^D("%z %Z",<tmpl_var timestamp>);</span>
- <span class="from"><tmpl_var from></span>: <tmpl_var bodyText>
</li></tmpl_loop></ul></tmpl_if>
<tmpl_var form_start>From: <tmpl_var form_from><br/>Text: <tmpl_var form_bodyText><tmpl_var form_submit><tmpl_var form_end>
</div>
Before<div id="shoutbox"><tmpl_if chat><ul><tmpl_loop chat><li> <span class="timestamp">
^D("%z %Z",<tmpl_var timestamp>);</span>
- <span class="from"><tmpl_var from></span>: <tmpl_var bodyText>
</li></tmpl_loop></ul></tmpl_if>
<tmpl_var form_start>From: <tmpl_var form_from><br/>Text: <tmpl_var form_bodyText><tmpl_var form_submit><tmpl_var form_end>
</div>
Before<div id="shoutbox"><tmpl_if chat><ul><tmpl_loop chat><li> <span class="timestamp">
^D("%z %Z",<tmpl_var timestamp>);</span>
- <span class="from"><tmpl_var from></span>: <tmpl_var bodyText>
</li></tmpl_loop></ul></tmpl_if>
<tmpl_var form_start>From: <tmpl_var form_from><br/>Text: <tmpl_var form_bodyText><tmpl_var form_submit><tmpl_var form_end>
</div>
Our Task
Replace the loop generating the chat with a JavaScript one
Reuse our new function
Good practice when interacting with content
Pretext to show off YUI DOM functionsflimsy
Beginning Our App
Some rules to live by
Document, Document, Document
<script type="text/javascript">
/******************************************************* * Shoutbox - User chat on your site ******************************************************/
Beginning Our App
Some rules to live by
Use Namespaces to keep away from overlap
<script type="text/javascript">
/******************************************************* * Shoutbox - User chat on your site ******************************************************/
// Create a "namespace" to hold our functionsvar Shoutbox = {}; // Just a blank object!
Beginning Our App
Some rules to live by
Document, Document, Document
* Shoutbox - User chat on your site ******************************************************/
// Create a "namespace" to hold our functionsvar Shoutbox = {}; // Just a blank object!
/******************************************************* * Shoutbox.addChatRow ( timestamp, from, bodyText ) * Adds a row to the chat box. timestamp, from, and * bodyText are directly from the Shoutbox asset */
Beginning Our App
Import YUI
All of YUI requires yahoo.js
<script type=”text/javascript” src=”^Extras(yui/build/yahoo/yahoo-min.js);”></script>
<script type="text/javascript">
/******************************************************* * Shoutbox - User chat on your site ******************************************************/
// Create a "namespace" to hold our functionsvar Shoutbox = {}; // Just a blank object!
Beginning Our App
Import YUI
We want dom.js
<script type=”text/javascript” src=”^Extras(yui/build/yahoo/yahoo-min.js);”></script>
<script type=”text/javascript” src=”^Extras(yui/build/dom/dom-min.js);”></script>
<script type="text/javascript">
/******************************************************* * Shoutbox - User chat on your site ******************************************************/
// Create a "namespace" to hold our functionsvar Shoutbox = {}; // Just a blank object!
Beginning Our App
addChatRow
Adds a row to the list
<div id="shoutbox"><tmpl_if chat><ul><tmpl_loop chat><li> <span class="timestamp">
^D("%z %Z",<tmpl_var timestamp>);</span>
- <span class="from"><tmpl_var from></span>: <tmpl_var bodyText>
</li></tmpl_loop></ul></tmpl_if>
Beginning Our App
addChatRow
Adds a row to the list
<div id="shoutbox"><tmpl_if chat><ul><tmpl_loop chat><li> <span class="timestamp">
^D("%z %Z",<tmpl_var timestamp>);</span>
- <span class="from"><tmpl_var from></span>: <tmpl_var bodyText>
</li></tmpl_loop></ul></tmpl_if>
Beginning Our App
addChatRow
/******************************************************* * Shoutbox.addChatRow ( timestamp, from, bodyText ) * Adds a row to the chat box. timestamp, from, and * bodyText are directly from the Shoutbox asset */Shoutbox.addChatRow = function (timestamp, from, bodyText) {
var sb = document.getElementById("shoutbox"); var ul = sb.getElementsByTagName("ul")[0]; // Nicely format our date timestamp = new Date(timestamp).toLocaleString(); // Create new DOM nodes for our chat
Beginning Our App
addChatRow
/******************************************************* * Shoutbox.addChatRow ( timestamp, from, bodyText ) * Adds a row to the chat box. timestamp, from, and * bodyText are directly from the Shoutbox asset */Shoutbox.addChatRow = function (timestamp, from, bodyText) {
var sb = document.getElementById("shoutbox"); var ul = sb.getElementsByTagName("ul")[0]; // Nicely format our date timestamp = new Date(timestamp).toLocaleString(); // Create new DOM nodes for our chat
Beginning Our App
addChatRow
/******************************************************* * Shoutbox.addChatRow ( timestamp, from, bodyText ) * Adds a row to the chat box. timestamp, from, and * bodyText are directly from the Shoutbox asset */Shoutbox.addChatRow = function (timestamp, from, bodyText) {
var sb = document.getElementById("shoutbox"); var ul = sb.getElementsByTagName("ul")[0]; // Nicely format our date var tsDate = new Date(timestamp).toLocaleString(); // Create new DOM nodes for our chat
Our First Yahoo
addChatRow
// Create new DOM nodes for our chat list var spanTimestamp = document.createElement("span"); YAHOO.util.Dom.addClass(spanTimestamp, "timestamp"); spanTimestamp.appendChild(
document.createTextNode(timestamp) );
var spanFrom = document.createElement("span"); YAHOO.util.Dom.setStyle(spanFrom, "font-weight", "bold"); spanFrom.appendChild( document.createTextNode(from) );
var li = document.createElement("li"); li.appendChild( spanTimestamp ); li.appendChild( document.createTextNode(" - ") );
Our First Yahoo
addChatRow
// Create new DOM nodes for our chat var spanTimestamp = document.createElement("span"); YAHOO.util.Dom.addClass(spanTimestamp, "timestamp"); spanTimestamp.appendChild(
document.createTextNode(timestamp) );
YAHOO.util.Dom.addClass( “id” || element, “class”);
Exists because of browser compatibility issues with setting element.className or using element.setAttribute(”class”, “classname”);
Our First Yahoo
addChatRow
// Create new DOM nodes for our chat list var spanTimestamp = document.createElement("span"); YAHOO.util.Dom.addClass(spanTimestamp, "timestamp"); spanTimestamp.appendChild(
document.createTextNode(timestamp) );
var spanFrom = document.createElement("span"); YAHOO.util.Dom.setStyle(spanFrom, "font-weight", "bold"); spanFrom.appendChild( document.createTextNode(from) );
var li = document.createElement("li"); li.appendChild( spanTimestamp ); li.appendChild( document.createTextNode(" - ") );
Our First Yahoo
addChatRow
// Create new DOM nodes for our chat list var spanTimestamp = document.createElement("span"); YAHOO.util.Dom.addClass(spanTimestamp, "timestamp"); spanTimestamp.appendChild(
document.createTextNode(timestamp) );
var spanFrom = document.createElement("span"); YAHOO.util.Dom.setStyle(spanFrom, "font-weight", "bold"); spanFrom.appendChild( document.createTextNode(from) );
var li = document.createElement("li"); li.appendChild( spanTimestamp ); li.appendChild( document.createTextNode(" - ") );
Our First Yahoo
addChatRow
var spanFrom = document.createElement("span"); YAHOO.util.Dom.setStyle(spanFrom, "font-weight", "bold"); spanFrom.appendChild( document.createTextNode(from) );
var li = document.createElement("li"); li.appendChild( spanTimestamp );
YAHOO.util.Dom.setStyle( “id” || element, “property”, “value”);
Exists because of browser compatibility issues with setting element.style or element.setAttribute()
Our First Yahoo
addChatRow
var spanFrom = document.createElement("span"); YAHOO.util.Dom.setStyle(spanFrom, "font-weight", "bold"); spanFrom.appendChild( document.createTextNode(from) );
var li = document.createElement("li"); li.appendChild( spanTimestamp ); li.appendChild( document.createTextNode(" - ") ); li.appendChild( spanFrom ); li.appendChild( document.createTextNode(": ") ); li.appendChild( document.createTextNode(bodyText) );
ul.appendChild(li);};
Our First Yahoo
addChatRow
var spanFrom = document.createElement("span"); YAHOO.util.Dom.setStyle(spanFrom, "font-weight", "bold"); spanFrom.appendChild( document.createTextNode(from) );
var li = document.createElement("li"); li.appendChild( spanTimestamp ); li.appendChild( document.createTextNode(" - ") ); li.appendChild( spanFrom ); li.appendChild( document.createTextNode(": ") ); li.appendChild( document.createTextNode(bodyText) );
ul.appendChild(li);};
Our First Yahoo
Replace our HTML
Test our code
One Way to Do It means One Code to Edit
<tmpl_if chat><ul><tmpl_loop chat><li> <span class="timestamp">
^D("%z %Z",<tmpl_var timestamp>);</span>
- <span class="from"><tmpl_var from></span>: <tmpl_var bodyText>
</li></tmpl_loop></ul></tmpl_if>
Our First Yahoo
Replace our HTML
Test our code
One Way to Do It means One Code to Edit
<tmpl_if chat><ul></ul><script type=”text/javascript”><tmpl_loop chat>Shoutbox.addChatRow(<tmpl_var timestamp>,‘<tmpl_var from escape=”JS”>’,‘<tmpl_var bodyText escape=”JS”>’ );
</tmpl_loop></script></tmpl_if>
DOM and DOMer
• Get the size of the viewport
• Different browsers, different ways
• YAHOO.util.Dom.getViewportWidth()YAHOO.util.Dom.getViewportHeight()
• Get and Set an elements position
• Difficult when other styles get in the way
• getX(el), getY(el), getXY(el)setX(el), setY(el), setXY(el)
The Result
Looks the same
But that’s what we wanted
Let’s do somethingInteresting!
EventsJohnny 5 need input
Show and Hide
Add a title bar
Click to toggle
Show and Hide
Add a title bar
Click to toggle
<div id="shoutbox"><a href="#" class="title">Shoutbox</a><tmpl_if chat><ul></ul><script type=”text/javascript”><tmpl_loop chat>Shoutbox.addChatRow(<tmpl_var timestamp>,‘<tmpl_var from escape=”JS”>’,
Where’s the onclick=””?
YUI Event
Add and remove event listeners
YAHOO.util.Event.addListener( “id” || element, “event”, callbackFunction);
click, mouseOver, mouseOut
submit, load
YUI Event
Custom Events
YAHOO.util.Event.onContentReady( “id” || element, callbackFunction);
Calls the callbackFunction when the specified element AND its next sibling is available in the DOM
Element is safe to modify in all browsers
Add an Event
Setting up
Import YUI Event
<script type=”text/javascript” src=”^Extras(yui/build/yahoo/yahoo-min.js);”></script>
<script type=”text/javascript” src=”^Extras(yui/build/dom/dom-min.js);”></script>
<script type=”text/javascript” src=”^Extras(yui/build/event/event-min.js);”></script>
<script type="text/javascript">
/******************************************************* * Shoutbox - User chat on your site ******************************************************/
Add an Event
Setting up
Save state
* Shoutbox - User chat on your site ******************************************************/
// Create a "namespace" to hold our functionsvar Shoutbox = {}; // Just a blank object!
Shoutbox.opened = 1; // Keep track if the shoutbox is open
/****************************************************** * Shoutbox.addChatRow ( timestamp, from, bodyText ) * Adds a row to the chat box. timestamp, from, and * bodyText are directly from the Shoutbox asset */
Add an Event
Create event handler to toggle that state
Document, document, document
/****************************************************** * Shoutbox.eventToggleView ( event ) * Event handler to toggle the shoutbox open or closed. */Shoutbox.eventToggleView = function (event) { if (Shoutbox.opened) { YAHOO.util.Dom.setStyle('shoutbox','height','30px'); // height + padding of title Shoutbox.opened = 0; } else { YAHOO.util.Dom.setStyle('shoutbox','height','260px'); Shoutbox.opened = 1;
Add an Event
Create event handler to toggle that state
Event handlers have one required argument
/****************************************************** * Shoutbox.eventToggleView ( event ) * Event handler to toggle the shoutbox open or closed. */Shoutbox.eventToggleView = function (event) { if (Shoutbox.opened) { YAHOO.util.Dom.setStyle('shoutbox','height','30px'); // height + padding of title Shoutbox.opened = 0; } else { YAHOO.util.Dom.setStyle('shoutbox','height','260px'); Shoutbox.opened = 1;
Add an Event
Create event handler to toggle that state
If it’s opened, close it
/****************************************************** * Shoutbox.eventToggleView ( event ) * Event handler to toggle the shoutbox open or closed. */Shoutbox.eventToggleView = function (event) { if (Shoutbox.opened) { YAHOO.util.Dom.setStyle('shoutbox','height','30px'); // height + padding of title Shoutbox.opened = 0; } else { YAHOO.util.Dom.setStyle('shoutbox','height','260px'); Shoutbox.opened = 1;
Add an Event
Create event handler to toggle that state
If it’s closed, open it
YAHOO.util.Dom.setStyle('shoutbox','height','30px'); // height + padding of title Shoutbox.opened = 0; } else { YAHOO.util.Dom.setStyle('shoutbox','height','260px'); Shoutbox.opened = 1; }
YAHOO.util.Event.preventDefault(event);};
Add an Event
Create event handler to toggle that state
Stop the default action (href=”#”)
YAHOO.util.Dom.setStyle('shoutbox','height','30px'); // height + padding of title Shoutbox.opened = 0; } else { YAHOO.util.Dom.setStyle('shoutbox','height','260px'); Shoutbox.opened = 1; }
YAHOO.util.Event.preventDefault(event);};
Add an Event
Add a listener to call the toggle method
Must be added after the entire shoutbox is loaded
onContentReady()
Create an event handler that will add the listener when the onContentReady event happens
Add an Event
Add a listener to call the toggle method
Create an initialization method
/****************************************************** * Shoutbox.init ( ) * Initialize the shoutbox */Shoutbox.init = function () { var shoutbox = document.getElementById('shoutbox');
// Add an onclick handler to the first title var title
= YAHOO.util.Dom.getElementsByClassName('title',undefined, shoutbox)[0];
YAHOO.util.Event.addListener(title, 'click', Shoutbox.eventToggleView
Add an Event
Add a listener to call the toggle method
Create an initialization method
// Add an onclick handler to the first title var title
= YAHOO.util.Dom.getElementsByClassName('title',undefined, shoutbox)[0];
YAHOO.util.Event.addListener(title, 'click', Shoutbox.eventToggleView);
};
Add an Event
Add a listener to call the toggle method
Call the initializer when ready
YAHOO.util.Event.addListener(title, 'click', Shoutbox.eventToggleView
);};
// Run the initializer when our shoutbox is safe to modifyYAHOO.util.Event.onContentReady( 'shoutbox', Shoutbox.init
);
Add an Event
Additional benefits of onContentReady handlers
“Progressive Enhancement”
Add an Event
Additional benefits of onContentReady handlers
Configurable state
* Shoutbox - User chat on your site ******************************************************/
// Create a "namespace" to hold our functionsvar Shoutbox = {}; // Just a blank object!
Shoutbox.opened = 1; // Keep track if the shoutbox is open
/****************************************************** * Shoutbox.addChatRow ( timestamp, from, bodyText ) * Adds a row to the chat box. timestamp, from, and * bodyText are directly from the Shoutbox asset */
Add an Event
Additional benefits of onContentReady handlers
Change initial state based on configuration
/****************************************************** * Shoutbox.init ( ) * Initialize the shoutbox */Shoutbox.init = function () { var shoutbox = document.getElementById('shoutbox');
// Set the initial state if (Shoutbox.opened) { YAHOO.util.Dom.setStyle(shoutbox,'height','260px'); } else { YAHOO.util.Dom.setStyle(shoutbox,'height','30px');
Add an Event
Additional benefits of onContentReady handlers
Change initial state based on configuration
// Set the initial state if (Shoutbox.opened) { YAHOO.util.Dom.setStyle(shoutbox,'height','260px'); } else { YAHOO.util.Dom.setStyle(shoutbox,'height','30px'); // height + padding of title }
// Add an onclick handler to the first title
var title = YAHOO.util.Dom.getElementsByClassName('title',undefined, shoutbox)[0];
More Event• YAHOO.util.Event.onDOMReady()
• Like onContentReady, but for when the entire DOM has been parsed.
• Happens after window load.
• Better than onLoad because of browser bugs
More Event
• Automatic addListener deferral
• When using an ID, waits until the element is ready (like onContentReady)
• Browser quirk handling
• No need to check window.event
• The event’s affected element is always correct
Results
When the title is clicked, the shoutbox opens or closes
Shoutbox.opened in the source now sets the default state.
Oh yes.It can have more awesome
AnimationNew powers for making Awesome
Adding Animation
Easier than you might think
Adding Animation
Easier than you might think
We already have the setup
Shoutbox.eventToggleView = function (event) { if (Shoutbox.opened) { YAHOO.util.Dom.setStyle('shoutbox','height','30px'); // height + padding of title Shoutbox.opened = 0; } else { YAHOO.util.Dom.setStyle('shoutbox','height','260px'); Shoutbox.opened = 1; }
YAHOO.util.Event.preventDefault(event);};
Adding Animation
Easier than you might think
Load the Animation component
src=”^Extras(yui/build/yahoo/yahoo-min.js);”></script><script type=”text/javascript” src=”^Extras(yui/build/dom/dom-min.js);”></script>
<script type=”text/javascript” src=”^Extras(yui/build/event/event-min.js);”></script>
<script type=”text/javascript” src=”^Extras(yui/build/animation/animation-min.js);”></script>
<script type="text/javascript">
/******************************************************* * Shoutbox - User chat on your site
Adding Animation
Easier than you might think
Alter the eventToggleView to use Animation
Shoutbox.eventToggleView = function (event) { Shoutbox.animation = new YAHOO.util.Anim('shoutbox'); Shoutbox.animation.duration = 1; if (Shoutbox.opened) { Shoutbox.animation.attributes.height = { to: 30 }; Shoutbox.animation.method
= YAHOO.util.Easing.bounceOut; Shoutbox.opened = 0; } else { Shoutbox.animation.attributes.height = { to: 260 }; Shoutbox.animation.method =
Adding Animation
Easier than you might think
Alter the eventToggleView to use Animation
YAHOO.util.Easing.bounceOut; Shoutbox.opened = 0; } else { Shoutbox.animation.attributes.height = { to: 260 }; Shoutbox.animation.method
= YAHOO.util.Easing.elasticOut; Shoutbox.opened = 1; }
Shoutbox.animation.animate(); YAHOO.util.Event.preventDefault(event);};
Other MethodsYAHOO.util.Easing.bounceOut
bounceIn / Out
Bounce Bounce Bounce
elasticIn / Out
Pull and snap
easeBoth
Both easeIn and easeOut
easeNone
Steady velocity
easeIn / easeOut
Smooth velocity change
backIn / backOut
Pulling a window shade
More Animation
• Make your own Easing methods
• Move an element along a path
• YAHOO.util.Motion
• Animate Colors
• YAHOO.util.ColorAnim
• Scroll elements
• YAHOO.util.Scroll
Result
That’s darn cool, but it isn’t very useful.
ConnectionXmlHttpRequest (AJAX)
The best thing to happen to WWW since Netscape
What is AJAX?
More than a buzzword
What is AJAX?
More than a buzzword
Dynamic interaction between server and user
Without expensive page loads
In the background (no leaving the screen)
Build functional, responsive user interfaces
What JavaScript is all about
Adding some AJAX
Get Shoutbox content through AJAX
Import the Connection component
src=”^Extras(yui/build/yahoo/yahoo-min.js);”></script><script type=”text/javascript” src=”^Extras(yui/build/dom/dom-min.js);”></script>
<script type=”text/javascript” src=”^Extras(yui/build/event/event-min.js);”></script>
<script type=”text/javascript” src=”^Extras(yui/build/animation/animation-min.js);”></script>
<script type=”text/javascript” src=”^Extras(yui/build/connection/connection-min.js);”></script>
<script type="text/javascript">
Adding some AJAX
Get Shoutbox content through AJAX
Create a method to request an update
Use our ?func=json asset page
JSON is easy to manipulate using JavaScriptwho knew?
Adding some AJAX
Get Shoutbox content through AJAX
Create a method to request an update
/****************************************************** * Shoutbox.requestUpdate ( ) * Submit the async request to update our shoutbox */Shoutbox.requestUpdate = function () { var callback = { success: function (o) { // Remove all old chat and replace with new removeAllChildren("shoutbox"); responseObj = eval("(" + o.responseText + ")"); for (var i in responseObj.chat) { var row = responseObj.chat[i]; Shoutbox.addChatRow(row.timestamp, row.from,
Adding some AJAX
Get Shoutbox content through AJAX
Create a method to request an update
var callback = { success: function (o) { // Remove all old chat and replace with new removeAllChildren("shoutbox"); responseObj = eval("(" + o.responseText + ")"); for (var i in responseObj.chat) { var row = responseObj.chat[i]; Shoutbox.addChatRow(row.timestamp, row.from, row.bodyText); } }, failure: function (o) { alert("Update failed! Please try again.");
Adding some AJAX
Get Shoutbox content through AJAX
Create a method to request an update
for (var i in responseObj.chat) { var row = responseObj.chat[i]; Shoutbox.addChatRow(row.timestamp, row.from, row.bodyText); } }, failure: function (o) { alert("Update failed! Please try again."); } }
YAHOO.util.Connect.asyncRequest('GET', Shoutbox.url + '?func=json', callback);
Adding some AJAX
Get Shoutbox content through AJAX
Create a method to request an update
row.bodyText); } }, failure: function (o) { alert("Update failed! Please try again."); } }
YAHOO.util.Connect.asyncRequest('GET', Shoutbox.url + '?func=json', callback);};
/****************************************************
Adding some AJAX
Get Shoutbox content through AJAX
Where did we get Shoutbox.url?
WebGUI doesn’t process Head Block
Set the right URL in the Template
<script type="text/javascript">// Can't get the template var inside Head BlockShoutbox.url = '<tmpl_var url escape="js">';</script>
<div id="shoutbox">
Adding some AJAX
Get Shoutbox content through AJAX
Where did we get removeAllChildren()?
A function useful when replacing elements/****************************************************** * removeAllChildren(nodeId) * Utility to remove all children from an element */function removeAllChildren(nodeId) { var node = document.getElementById(nodeId); if (node && node.childNodes && node.removeChild) { while (node.hasChildNodes()) node.removeChild(node.firstChild); }}
Adding some AJAX
Get Shoutbox content through AJAX
Call the method during initialization
/****************************************************** * Shoutbox.init ( ) * Initialize the shoutbox */Shoutbox.init = function () { var shoutbox = document.getElementById('shoutbox');
// Get the content for our shoutbox Shoutbox.requestUpdate();
// Add an onclick handler to the first title var title = YAHOO.util.Dom.getElementsByClassName('title',undefined, shoutbox)[0];
Adding some AJAX
Get Shoutbox content through AJAX
Clear out our old method
<tmpl_if chat><ul></ul><script type=”text/javascript”><tmpl_loop chat>Shoutbox.addChatRow(<tmpl_var timestamp>,‘<tmpl_var from escape=”JS”>’,‘<tmpl_var bodyText escape=”JS”>’ );
</tmpl_loop></script></tmpl_if>
Adding some AJAX
Get Shoutbox content through AJAX
Clear out our old method
<div id="shoutbox">
<a href="#" class="title"> Shoutbox</a>
<ul><li></li></ul>
<tmpl_var form_start>From: <tmpl_var form_from><br/>
Empty container remains as placeholder
Result
Like earlier, the functionality is the same
... Foundation laid for enhanced functionality
Background AJAX
Periodically request an update from the server
That’s what “asynchronous” is all about
No expensive page loads
Build the layout once, show multiple types of content
User interaction to pull only the content they want
Periodic Update
Add a method to maintain period
/****************************************************** * Shoutbox.doAutoUpdate ( ) * Start the timer to auto update the shoutbox. Request an * update if the shoutbox is opened. */Shoutbox.doAutoUpdate = function () { // Start another timeout to keep the chain going Shoutbox.updateTimeout = setTimeout(Shoutbox.doAutoUpdate, 4000);
if (!Shoutbox.opened) { return; }
Periodic Update
Add a method to maintain period
First call starts, subsequent calls maintain
Shoutbox.doAutoUpdate = function () { // Start another timeout to keep the chain going Shoutbox.updateTimeout = setTimeout(Shoutbox.doAutoUpdate, 4000);
if (!Shoutbox.opened) { return; } else { Shoutbox.requestUpdate(); }};
Periodic Update
Add a method to maintain period
Use our saved state
Shoutbox.doAutoUpdate = function () { // Start another timeout to keep the chain going Shoutbox.updateTimeout = setTimeout(Shoutbox.doAutoUpdate, 4000);
if (!Shoutbox.opened) { return; } else { Shoutbox.requestUpdate(); }};
Periodic Update
Add a method to maintain period
Kick off the festivities
return; } else { Shoutbox.requestUpdate(); }};
// Start the timer when the Shoutbox is readyYAHOO.util.Event.onContentReady( 'shoutbox', Shoutbox.doAutoUpdate
);
Periodic Update
Add a method to maintain period
Clean up after thyself
/****************************************************** * Shoutbox.init ( ) * Initialize the shoutbox */Shoutbox.init = function () { var shoutbox = document.getElementById('shoutbox');
// Get the content for our shoutbox Shoutbox.requestUpdate();
// Add an onclick handler to the first title var title = YAHOO.util.Dom.getElementsByClassName('title',undefined, shoutbox)[0];
Periodic Update
Add a method to maintain period
Clean up after thyself
/****************************************************** * Shoutbox.init ( ) * Initialize the shoutbox */Shoutbox.init = function () { var shoutbox = document.getElementById('shoutbox');
// Add an onclick handler to the first title var title = YAHOO.util.Dom.getElementsByClassName('title',undefined, shoutbox)[0]; YAHOO.util.Event.addListener(title, 'click', Shoutbox.eventToggleView);
Result
As new rows are added to the Shoutbox, we get updated without having to do anything
Keep track of the conversation without leaving the page
Asynchronous FormsAs much awesome as one should ingest in a single sitting
Process a form without leaving the page
YUI makes it easy!
Asynchronous Forms
Make an event handler that sends an AJAX request
/****************************************************** * Shoutbox.handleSubmit ( event ) * Handle the shoutbox form submit. Submit the form and * refresh the data. */Shoutbox.handleSubmit = function (e) { // Stop the browser from handling the submit YAHOO.util.Event.preventDefault(e);
var shoutbox = document.getElementById('shoutbox'); var form = shoutbox.getElementsByTagName("form")[0];
// Get the form and send the data off var shoutbox = document.getElementById('shoutbox'); var form = shoutbox.getElementsByTagName("form")[0];
Asynchronous Forms
Make an event handler that sends an AJAX request
Shoutbox.handleSubmit = function (e) { // Stop the browser from handling the submit YAHOO.util.Event.preventDefault(e);
// Get the form and send the data offvar shoutbox = document.getElementById('shoutbox');
var form = shoutbox.getElementsByTagName("form")[0];YAHOO.util.Connect.setForm(form);
var callback = { success: function (o) { // Clear the form form.bodyText.value = ""; if (form.from && form.from.value) { form.from.value = "";
Asynchronous Forms
Make an event handler that sends an AJAX request
Shoutbox.handleSubmit = function (e) { // Stop the browser from handling the submit YAHOO.util.Event.preventDefault(e);
// Get the form and send the data offvar shoutbox = document.getElementById('shoutbox');
var form = shoutbox.getElementsByTagName("form")[0];YAHOO.util.Connect.setForm(form);
var callback = { success: function (o) { // Clear the form form.bodyText.value = ""; if (form.from && form.from.value) { form.from.value = "";
Asynchronous Forms
Make an event handler that sends an AJAX request
var callback = { success: function (o) { // Clear the form form.bodyText.value = ""; if (form.from && form.from.value) { form.from.value = ""; } Shoutbox.requestUpdate(); }, failure: function (o) { alert("Failed to submit! Try again!"); } };
Asynchronous Forms
Make an event handler that sends an AJAX request
failure: function (o) { alert("Failed to submit! Try again!"); } }; YAHOO.util.Connect.asyncRequest(
"POST", Shoutbox.url, callback);
};
Asynchronous Forms
Attach the event handler to the form/****************************************************** * Shoutbox.init ( ) * Initialize the shoutbox */Shoutbox.init = function () { var shoutbox = document.getElementById('shoutbox');
// Add an onsubmit handler to the form var form = shoutbox.getElementsByTagName("form")[0]; YAHOO.util.Event.addListener(
form, 'submit', Shoutbox.handleSubmit);
// Set the initial state
All done without touching our HTML!
More Connection
• Set a timeout
• The timeout property of the callback object
• Asynchronous file upload
• Will Just Work(tm)
• More custom events
• start, complete, success, failure, more...
More Connection
• Transaction state
• YAHOO.util.Connect.asyncRequest() returns an object
• Store it and check its status
• Stop running requests until the first is done
• Abort a running request
Result
Whatever page our Shoutbox may be on we will be able to chat without leaving our page
AssetProxy, Page Layout, Folder
Wrapping UpYou’ve Come a Long Way, Baby
Summary
YUI DOM Component
Handles DOM incompatibilities between browsers
YUI Event Component
Handles Event incompatibilities between browsers
More efficient / intuitive interface to events
Summary
YUI Animation Component
Flashy special effects
Improve the user experience
YUI Connection Component
AJAX (XmlHttpRequest)
A magical world of usability
After
YUI Documentation
http://yourserver.com/extras/yui/docs
Current version used by your WebGUI
http://developer.yahoo.com/yui
Latest version released by Yahoo
More Resources
Resources on browser compatibilities and capabilities
http://www.quirksmode.org/dom/compatibility.htmlhttp://www.webdevout.net/browser-support
Firebug - JavaScript, CSS, HTML debugging tool
http://www.getfirebug.com
Questions?