Más contenido relacionado La actualidad más candente (17) Similar a Web Development using jQuery (20) Web Development using jQuery1. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Web Development using jQuery
JavaScript
Frameworks
Using Querying
Plugins the DOM
jQuery
Event Event
Queue Model
Manipulating
Ajax
the DOM
Bryan Basham
Software Alchemy
basham47@gmail.com
http://www.linkedin.com/in/SoftwareAlchemist
Bryan Basham – Web Development using jQuery Slide 1
2. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Assumptions
● This talk assumes basic understanding of:
– HTML
– CSS
– Core JavaScript syntax
– Functional programming principles
● See SlideShare: Introduction to JavaScript
Bryan Basham – Web Development using jQuery Slide 2
3. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
JavaScript Frameworks
Low-level
Wars frameworks High-level
& Warts frameworks
JavaScript
Frameworks
Using DEMO #1 Querying
Plugins the DOM
jQuery
Event Event
Queue Model
Manipulating
Ajax
the DOM
Bryan Basham – Web Development using jQuery Slide 3
4. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Wars and Warts
● Browser wars of the bad old days
● Uneven support for DOM standards
● Quirks and bugs of older browsers
● Supporting multiple browsers is tricky
– Esp. multiple versions of IE
Bryan Basham – Web Development using jQuery Slide 4
5. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
JavaScript Frameworks
● Dozens of frameworks grew out of the need to
build user-friendly and advanced webapps
● Wide variety of techniques:
– Modification of standard APIs: eg, Prototype
– Functional wrappers: eg, jQuery
– Object-Oriented class library: eg, ExtJS
● Best to select one library but it's possible to
use two or more together
– Beware of namespace conflicts, esp the $
function (Prototype and jQuery)
Bryan Basham – Web Development using jQuery Slide 5
6. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Low-level Frameworks
● Low-level frameworks provide:
– Cross-browser compatibility
– Advanced DOM APIs: query, traversal,
manipulation, and so on
– Advanced Ajax APIs
● Examples:
– Prototype
– jQuery
– Dojo (core modules)
● Frequently extensible using plugins
Bryan Basham – Web Development using jQuery Slide 6
7. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
High-level Frameworks
● High-level frameworks provide:
– UI Widgets
– UI Layout tools
– UI Effects
● Examples:
– Script-aculo-us (w/ Prototype, but minimal)
– jQuery UI (w/ jQuery, but minimal)
– Dijit (v1.7) (Dojo's widget library, more and
modular)
– ExtJS (all-in-one; lots of widgets, layouts, etc)
Bryan Basham – Web Development using jQuery Slide 7
8. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
jQuery
● jQuery development starts with building event
handlers for specific elements.
● Principles:
– Implicit iteration (Wikipedia)
$('SELECTOR').method(...);
// sort of like this:
$('SELECTOR').each(function (idx, element) {
method.call(element, ...);
});
– Method chaining (Wikipedia)
$('SELECTOR').action1(...).action2(...).action3(...);
// sometimes written like this:
$('SELECTOR').action1(...)
.action2(...)
.action3(...);
Bryan Basham – Web Development using jQuery Slide 8
9. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Demo #1: View an Exam
● This first demo shows several simple effects
and event handlers.
● The demo came from a webapp original built
for Sun Microsystems, certification team:
Bryan Basham – Web Development using jQuery Slide 9
10. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Querying the DOM
Low-level
Wars frameworks High-level
& Warts frameworks
JavaScript Standard APIs
Frameworks
jQuery Selectors
Using DEMO #1 Querying
Std Traversal
Plugins the DOM
jQuery Traversal
jQuery
Event Event
Queue Model
Manipulating
Ajax
the DOM
Bryan Basham – Web Development using jQuery Slide 10
11. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Standard DOM Type Hierarchy
parentNode 1
0..*
Node childNodes
1 0..*
Document documentElement
Element CharacterData
{AKA: the root node}
The relationship between the Element and
the abstract CharacterData type is implied by Text Comment
the Node's ability to contain children of any
Node subtype, such as Text or Comment.
CDATASection
Bryan Basham – Web Development using jQuery Slide 11
12. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Document Example
<html>
<head>
</head>
<body>
<div id="login">
<form action="" id="login_form">
<fieldset>
<ol>
<li>
<label for="login_id">
Login <abbr title="identification">ID</abbr>
</label>
<input id="login_id" name="username" type="text" />
</li>
<li>
<label for="password">Password</label>
<input id="password" name="userpass" type="password" />
<a href="#">go</a>
</li>
</ol>
</fieldset>
</form>
</div>
</body>
</html>
Bryan Basham – Web Development using jQuery Slide 12
13. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
DOM Example
<HTML>
<HEAD> <BODY>
<DIV>
<FORM>
<FIELDSET>
<OL>
<LI> <LI>
<LABEL> <INPUT “username”> <LABEL> <INPUT “userpass”> <A>
Bryan Basham – Web Development using jQuery Slide 13
14. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Standard DOM Query APIs
Node
1
Document Element
documentElement
{AKA: the root node} tagName : DOMString
getElementById(elementId) : Element
getElementsByTagName(tagName) : NodeList getElementsByTagName(tagName) : NodeList
getElementsByClassName(clsName) : NodeList
NodeList
length : long
[idx] : Node
item(idx) : Node
Bryan Basham – Web Development using jQuery Slide 14
15. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Using the DOM Query APIs
● Find the unique element by its id
// retrieves the <form> element with id of 'login_form'
var myForm = document.getElementById('login_form');
● Find a list of elements by tag type
– Search the whole document:
// retrieves all <input> elements in the whole document
document.getElementsByTagName('input');
– Search down from a specific element:
// retrieves all <input> elements in <form id='login_form'>...</form>
myForm.getElementsByTagName('input');
● Find a list of elements with a specific class:
myForm.getElementsByClassName('form_error');
Bryan Basham – Web Development using jQuery Slide 15
16. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
jQuery Selector Function
● The standard APIs are limited so frameworks
provide more flexible querying APIs
● jQuery allows querying for DOM elements
using CSS selector syntax
– $('#nav_bar') – select unique element
– $('td') – select all table data cells
– $('div.section_head') – all divs of a class
– $('table#myGrid th') – all heading cells
within a specific table
– and much much more...
Bryan Basham – Web Development using jQuery Slide 16
17. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
jQuery Selector Function
● The $ function always returns an array
(possibly empty) of DOM elements
● It returns is a quasi-array, the jQuery object
● It has powerful implicit iteration functions
– Execute arbitrary code:
$('div.section_head').each(function(idx, element) { /* ... */ });
– Assign event handlers:
$('a#collapse_all_sections').click(function(event) {
$('ol#section_list > li ol').slideUp('slow');
event.preventDefault();
});
– Manipulate the DOM:
$('div.section_head').addClass('hightlighted');
Bryan Basham – Web Development using jQuery Slide 17
18. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
jQuery Selector Function
● Wrap a DOM element using the $ function:
– Wrap the window object:
$(window).resize(function(event) {
var $ctrPanel = $('#control_panel'); // common naming convention: $var
var frame = $('#frame')[0]; // extract the actual DOM element object from the array
$ctrPanel.css('left', (frame.offsetWidth+ frame.offsetLeft- $ctrPanel[0].offsetWidth)+ 'px');
});
– Wrap the document object:
(function($) {
$(document).ready(function() { // execute this function when the DOM is ready
Screen.initialise();
});
})(jQuery);
– Wrap the target of an event handler:
$('ol#section_list li').dblclick(function(event) {
var $objectivesList = $(this).find('ol'); // wrap DOM element to get jQuery functionality
if ($objectivesList.is(':visible')) {
$objectivesList.fadeOut(2000);
} else {
$objectivesList.fadeIn(2000);
}
});
Bryan Basham – Web Development using jQuery Slide 18
19. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
jQuery Selector Function
● The jQuery object is the heart of the jQuery
library
● We have only scratched the surface:
– Event handler registration
– DOM manipulation
– UI effects, such as hide, fading, sliding
– Plugin enhancements
● Next, let's look at a related topic:
DOM traversal
Bryan Basham – Web Development using jQuery Slide 19
20. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Standard DOM Traversal API
● The Node provides the traversal access:
1 parentNode
Node
parentNode : Node 0..*
childNodes : NodeList
firstChild : Node childNodes
lastChild : Node
previousSibling : Node
nextSibling : Node
hasChildNodes() : boolean
Bryan Basham – Web Development using jQuery Slide 20
21. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Traversal Example
<li>
<label for="password">Password</label>
<input id="password" name="userpass" type="password" />
<a href="#">go</a>
</li>
Nod
e LI:Element
pa rent
las
d
hi l
t
stC
Ch
ild
fir
nextSibling
LABEL:Element INPUT:Element A:Element
previousSibling
"password":Text "go":Text
Bryan Basham – Web Development using jQuery Slide 21
22. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Traversal Example (reality check)
<li>
<label for="password">Password</label>
<input id="password" name="userpass" type="password" />
<a href="#">go</a>
</li>
LI:Element
h ild last
firstC Chil
d
ws:Text LABEL:Element ws:Text INPUT:Element ws:Text A:Element ws:Text
"Password":Text "go":Text
Bryan Basham – Web Development using jQuery Slide 22
23. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
jQuery Traversal APIs
● The basic jQuery traversal methods ignore text
nodes; just gives you elements
– $('X').parent() – gets the immediate
parent(s)
– $('X').children() – gets all child elements
– $('X').next() – gets the next sibling
element(s)
● You can always get to the actual DOM element
to get low-level aspects
– $('X')[0].nextSibling – gets the next
node (could be a text node)
Bryan Basham – Web Development using jQuery Slide 23
24. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Up/Down Traversal
● Up traversal:
– $('X').parent() – gets parent for each
– $('X').parents() – gets all ancestors
– $('X').parentsUntil('form') – gets a
subset of ancestors up to but not including the
parent that matches the selector
● Down traversal:
– $('X').children() – gets all direct children
– $('X').find('.myClass') – finds all
descendants that match the selector
Bryan Basham – Web Development using jQuery Slide 24
25. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Sibling Traversal
● All siblings:
– $('X').siblings() – gets all siblings
– $('X').siblings('.myClass') – gets all
matching siblings
● Next and Previous (not shown):
– $('X').next() – gets immediate next element
– $('X').nextAll() – gets all next elements
– $('X').nextUntil('.myClass') – get next
elements up to but not including the sibling
matched by the selector
Bryan Basham – Web Development using jQuery Slide 25
26. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Selector Array Manipulation
● You can also manipulate the array returned by
the $ function:
– Remove items: filter and not
– Add items: add and andSelf
– Selecting items: first, last, slice, eq
● Chaining:
$('ol#section_list > li').eq(3).nextAll().andSelf().filter('.myClass');
$('ol#section_list').addClass('sectionListStyle') // one <ol> element
.children('li').removeClass('highlighted') // list of <li> children
.addClass('sectionItemStyle'); // same list of items
Bryan Basham – Web Development using jQuery Slide 26
27. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Event Model
Low-level
Wars frameworks High-level
& Warts frameworks
JavaScript Standard APIs
Frameworks
jQuery Selectors
Using DEMO #1 Querying
Std Traversal
Plugins the DOM
jQuery Traversal
Traditional Model(s)
jQuery
Event Event Std Model
Queue Model
jQuery Event
Registration
Manipulating
Ajax
the DOM
Bryan Basham – Web Development using jQuery Slide 27
28. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
The Event Model(s)
● Traditional (AKA Level 0)
– Event handlers as tag attributes (eg, onclick)
– Event handlers set as Element properties
● Standard event model in DOM Level 2
– Event listeners are registered with the element
● jQuery provides easy API and advanced
(composite) events
Bryan Basham – Web Development using jQuery Slide 28
29. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Event Types
● Mouse:
– click, dblclick, mousedown, mouseup,
mouseover, mousemove, mouseout
● Keyboard:
– keypress, keydown, keyup
● Window:
– load, unload, resize, scroll, abort, error
● Form:
– focus, blur, select, change, reset, submit
Bryan Basham – Web Development using jQuery Slide 29
30. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Event Propagation
Netscape Model Microsoft Model
Element1 Element1
Element2 Element2
Event Bubbling Event Capturing
Bryan Basham – Web Development using jQuery Slide 30
31. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Traditional Event Handlers
● Assign handler on tag attribute
<a href="#" onclick="return LoginScreen.validateForm();">go</a>
● Assign handler with Element property
var goButton = document.getElementById("goButton");
goButton.onclick = function(event) { return Screen.validateForm(); };
● CONS:
– Limited to only one handler per element and
event type
– Poor separation of concerns: behavior mixed in
with structure
– Inconsistent event propagation
Bryan Basham – Web Development using jQuery Slide 31
32. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
DOM Level 2 Event Handlers
● HTML Elements are event targets:
«CORBA Interface» 0..* «CORBA Interface»
EventTarget EventListener
addEventListener(listener) handleEvent(event)
removeEventListener(listener)
dispatchEvent(event)
«CORBA Interface»
Event EventPhaseEnum
type : DOMString CAPTURING_PHASE = 1
target : EventTarget {an element} AT_TARGET = 2
currentTarget : EventTarget BUBBLING_PHASE = 3
eventPhase : EventPhaseEnum
timeStamp : DOMTimeStamp
stopPropagation() : void
preventDefault() : void
Bryan Basham – Web Development using jQuery Slide 32
33. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Standard Event Propagation
● The standard propagation model is a
combination of the proprietary models:
CAPTURE_PHASE
BUBBLING_PHASE
Element1
Element2
AT_TARGET
Bryan Basham – Web Development using jQuery Slide 33
34. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Event Registration (HTML)
<body onload="EventsLevel2.registerHandlers(false);">
<h1>Event Model: Level 2 w/ No Capturing</h1>
<div id="outerBox">
Element1
<div id="innerBox">
Element2
</div>
</div>
</body>
Bryan Basham – Web Development using jQuery Slide 34
35. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Event Registration (JS)
// Create the EventsLevel2 namespace
var EventsLevel2 = {
registerHandlers: function(capture) {
var outerBox = document.getElementById('outerBox');
var innerBox = document.getElementById('innerBox');
outerBox.addEventListener("click", EventsLevel2, capture);
innerBox.addEventListener("click", EventsLevel2, capture);
},
handleEvent : function(event) {
var div = event.currentTarget;
console.info("Current target: " + div.id
+ " had event: " + event
+ " in phase: " + event.eventPhase);
var propagate = confirm("Click OK to propagate the event.");
if ( ! propagate ) event.stopPropagation();
}
} // END of EventsLevel2 namespace definition
Bryan Basham – Web Development using jQuery Slide 35
36. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
jQuery Event Registration
● Methods on the jQuery object named after the
specific DOM event
$('a#collapse_all_sections').click(function(event) {
$('ol#section_list li ol').slideUp('slow');
event.preventDefault();
});
● Implicit iteration allows easy handler
registration across range of elements
$('ol#section_list > li').dblclick(function(event) {
var $objectivesList = $(this).find('ol');
if ($objectivesList.is(':visible')) {
$objectivesList.fadeOut(2000);
} else {
$objectivesList.fadeIn(2000);
}
});
Bryan Basham – Web Development using jQuery Slide 36
37. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
jQuery Events
● Native Browser events:
– Mouse,
– Click,
– Keyboard, ...
● Compound events:
– hover is a combination of mouseover and
mouseout
– toggle is a sequence of click handlers
● at least two
● more than two switches in order, around robin
Bryan Basham – Web Development using jQuery Slide 37
38. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
jQuery Examples (sketch)
● When hovering over a Section heading:
$('div.section_head').hover(function(event) {
// find the section_text DIV element
// and position it near the mouse
// and fade it in
},
function(event) {
// and fade it out
});
● When you click on the Control Panel to hide it:
$('#control_panel h3').toggle(function(event) {
// slide the panel contents away
// and move the panel to the top of the screen
},
function(event) {
// move the panel back to position
// and slide the contents back into place
});
Bryan Basham – Web Development using jQuery Slide 38
39. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Manipulating the DOM
Low-level
Wars frameworks High-level
& Warts frameworks
JavaScript Standard APIs
Frameworks
jQuery Selectors
Using DEMO #1 Querying
Std Traversal
Plugins the DOM
jQuery Traversal
Traditional Model(s)
jQuery
Event Event Std Model
Queue Model
jQuery Event
Std APIs Registration
Manipulating Setting
Ajax
the DOM Attributes
Effects
Setting CSS
Creating Elements
Bryan Basham – Web Development using jQuery Slide 39
40. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
DOM Manipulation
Node
insertBefore
replaceChild
removeChild
appendChild
1
Document Element
documentElement
{AKA: the root node} tagName : DOMString
createElement(tagName) : Element
hasAttribute(attrName) : boolean
createTextNode(data) : Text
getAttribute(attrName) : DOMString
createCDATASection(data) : CDATASection
setAttribute(attrName, attrValue)
removeAttribute(attrName)
Bryan Basham – Web Development using jQuery Slide 40
41. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Manipulation Example
● From the Ajax example: start with empty <dl>
<dl id="definitions"></dl>
● Ajax callback fills in the list
var defList = document.getElementById('definitions');
each(definitions, function (def) {
var dt = document.createElement('dt');
dt.innerHTML = def.name;
defList.appendChild(dt);
var dd = document.createElement('dd');
dd.innerHTML = def.definition;
defList.appendChild(dd);
});
● The new DOM content:
<dl id="definitions">
<dt>Ajax</dt> <dd>Asynchronous JavaScript and XML</dd>
<dt>JavaScript</dt><dd>The standard browser scripting language</dd>
<dt>Grails</dt> <dd>The hippest server-side scripting language</dd>
</dl>
Bryan Basham – Web Development using jQuery Slide 41
42. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
jQuery DOM Manipulation
● The standard DOM manipulation APIs are fairly
primitive
● jQuery (like other frameworks) provides a
richer, cross-browser API.
– Accessing element attributes
– Accessing CSS attributes
– Creating, placing and removing elements
– Graphical effects: hide, fade, slide
Bryan Basham – Web Development using jQuery Slide 42
43. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Element Attributes
● Get attributes with the attr(name) method
<h4><abbr title='Objective'>O.</abbr>1.3</h4>
$('abbr').attr('title') ==> 'Objective'
● Set attributes with attr(name, value)
<h4><abbr title='Objective'>O.</abbr>1.3</h4>
$('abbr').attr('title', 'Exam Objective')
==> becomes
<h4><abbr title='Exam Objective'>O.</abbr>1.3</h4>
Bryan Basham – Web Development using jQuery Slide 43
44. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Element Classes
● The HTML attribute class is special because it
actually may hold a space-delimited list:
<h2 id='bryan_actions' class='action_list'>Bryan Basham</h2>
● Add a class:
$('#bryan_actions').addClass('open');
<h2 id='bryan_actions' class='action_list open'>Bryan Basham</h2>
● Remove a class:
$('#bryan_actions').removeClass('open').addClass('closed');
// OR: $('#bryan_actions').toggleClass('open closed');
<h2 id='bryan_actions' class='action_list closed'>Bryan Basham</h2>
● Testing the existence of a class:
$('#bryan_actions').hasClass('open') ==> false
$('#bryan_actions').hasClass('action_list') ==> true
Bryan Basham – Web Development using jQuery Slide 44
45. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
CSS Style Properties
● While it is best to assign CSS style by applying
the class property, you can also adjust styles
directly on the DOM elements.
● Get style property (on first element in match):
$('X').css('background-color'); ==> (eg) '#FFFFFF' (maybe) 'transparent'
// OR use camelcase: $('X').css('backgroundColor');
● Set style properties (on all elements in match):
$('X').css('background-color', 'red');
● To set multiple values use a map (object):
$('X').css({'background-color': 'red', 'font-style': 'italic'});
Bryan Basham – Web Development using jQuery Slide 45
46. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
DOM Creation
● Inject HTML directly into an element:
<div class="demo-container">
<div class="demo-box">Demonstration Box</div>
</div>
$('demo-container').html('<p>New HTML</p>');
==> becomes:
<div class="demo-container">
<p>New HTML</p>
</div>
● Create detached HTML:
var $newPara = $('<p><em>New</em> Paragraph</p>');
Bryan Basham – Web Development using jQuery Slide 46
47. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
DOM Insertion
● Append new DOM elements within:
<div class="demo-container">
<div class="demo-box">Demonstration Box</div>
</div>
$('demo-container').append('<p>After</p>');
<div class="demo-container">
<div class="demo-box">Demonstration Box</div>
<p>After</p>
</div>
● Prepend:
$('demo-container').prepend('<p>Before</p>');
<div class="demo-container">
<p>Before</p>
<div class="demo-box">Demonstration Box</div>
<p>After</p>
</div>
Bryan Basham – Web Development using jQuery Slide 47
48. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
DOM Removal
● Removing a DOM element:
var $sectionLI = $('#' + Screen.sectionName(sectionIdx));
$sectionLI.remove();
● Detaching a DOM element
var $sectionLI = $('#' + Screen.sectionName(sectionIdx));
$sectionLI.detach();
– Detached elements can be reattached without
loss of registered event handlers
$('X').append($sectionLI);
Bryan Basham – Web Development using jQuery Slide 48
49. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Dynamic GUI Effects
● RIAs use simple graphical UI effects to help
focus the user on relevant widgets or activities.
● jQuery provides a few simple effects:
– show/hide – shows (or hides) whole DOM
elements and all children
– fadeIn/fadeOut – a show/hide feature with fading
animation; the element fades out of existence
– slideDown/slideUp – another show/hide feature
with animation that slides the content up and
out of sight
Bryan Basham – Web Development using jQuery Slide 49
50. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Demo Handlers with Effects
● Section head click handler:
// The “collapse all” button
$('a#collapse_all_sections').click(function(event) {
// slide closed the objectives lists of each section
$('ol#section_list li ol').slideUp('slow');
event.preventDefault();
});
● Section head double-click handler:
$('ol#section_list li').dblclick(function(event) {
var $objectivesList = $(this).find('ol');
// if the objectives list is visible
if ($objectivesList.is(':visible')) {
// then fade it out (snapping it out at the end)
$objectivesList.fadeOut(2000);
} else {
// otherwise fade the list back onto the screen
$objectivesList.fadeIn(2000);
}
});
Bryan Basham – Web Development using jQuery Slide 50
51. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Hover Example
● When hovering over a Section heading:
$('div.section_head').hover(function(event) {
// find the section_text DIV element
$(event.target).find('div.section_text')
// and position it near the mouse
.css('left', event.pageX + 'px')
.css('top', (event.pageY - $(window).scrollTop()) + 'px')
// and fade it in
.fadeIn('slow');
},
// hover out handler
function(event) {
// and fade it out
$(event.target).find('div.section_text').fadeOut('slow');
});
● This implementation has a usability problem
we will resolve later.
Bryan Basham – Web Development using jQuery Slide 51
52. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Ajax using jQuery
Low-level
Wars frameworks High-level
& Warts frameworks
JavaScript Standard APIs
Frameworks
jQuery Selectors
Using DEMO #1 Querying
Std Traversal
Plugins the DOM
jQuery Traversal
Traditional Model(s)
jQuery
Event Event Std Model
Queue Model
jQuery Event
Std APIs Registration
DEMO #2
Manipulating Setting
Ajax
the DOM Attributes
Effects
jQuery Review Setting CSS
Support Creating Elements
Bryan Basham – Web Development using jQuery Slide 52
53. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Demo #2: Multi-User Interactions
● The Exam editor page:
– In-place text editing
– Periodically: users actions change the page
– These actions are displayed in a side panel
Bryan Basham – Web Development using jQuery Slide 53
54. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Ajax Review
● Ajax provides a means to send requests to the
server without refreshing the page.
● Ajax request: Server
Page request
– URL Page response
Ajax request Page requests
REST verbs
●
– Ajax response (XML) ● Ajax requests
User
– callback Ajax request
Ajax response (JSON)
● Ajax response:
– Four phases but COMPLETE is all you need
– Access to response status and text
Bryan Basham – Web Development using jQuery Slide 54
55. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Issuing Commands using Ajax
● Part of what a page may do is issue
commands to the server:
EditExam request Server
EditExam page CertExam
addSection
{sectionIndex:7} Command Section
CertDev Servlet
modifySection('title','...')
{success:true}
Objective
Bryan Basham – Web Development using jQuery Slide 55
56. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Ajax Code to Send a Command
● The “Add Section” button sends a command to
the server to create a new Section object
// attach the “Add Section” button's click handler
$actionLink.click(function() {
var command = Screen.makeCommand('addSection', { URL
'examCode' : Screen.EXAM_CODE,
HTTP Method
});
$.ajax('/SurveyTool/CommandProcessor', { Request Parameters
type: 'POST',
data: { 'command': JSON.stringify(command) }, Successful response
success: function(respJSON) {
Screen.insertSectionDOM(respJSON.sectionIdx);
},
failure: function(errMsg) {
console.error("errMsg %o", errMsg);
}
});
});
Bryan Basham – Web Development using jQuery Slide 56
57. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
jQuery Ajax Support
● The ajax method is the core API.
● Specialized methods:
– get – GET request (needs configuration)
– load – GET requests for HTML chunks
– getJSON – GET request for JSON response
– post – POST request
Bryan Basham – Web Development using jQuery Slide 57
58. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Event Queue
Low-level
Wars frameworks High-level
& Warts frameworks
JavaScript Standard APIs
Frameworks
jQuery Selectors
Using DEMO #1 Querying
Std Traversal
Plugins the DOM
jQuery Traversal
DEMO #3
Traditional Model(s)
Deferred jQuery
Events
Event Event Std Model
Queue Model
jQuery Event
Periodic Std APIs Registration
Events Event Types DEMO #2
Manipulating Setting
Ajax
the DOM Attributes
Effects
jQuery Review Setting CSS
Support Creating Elements
Bryan Basham – Web Development using jQuery Slide 58
59. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Event Queue
● All events that have an handler get added to a
queue that is sorted by the time of the event.
● Each script is executed sequentially in the
order the events happened.
● If any given script takes a long time then it can
delay the execution of other event handlers.
● SO... make your event handler scripts as
efficient as possible.
Bryan Basham – Web Development using jQuery Slide 59
60. button / MouseOver
RJUG: 10-April-2012
1331413671600
Screen.buttonMouseOver
4ms
1331413671604
Bryan Basham – Web Development using jQuery
391ms
button / Click
1331413671995
30ms
Screen.buttonClick
Queue Example
1331413672005
20ms
Ajax request / state=COMPLETE
1331413672025
Screen.populateDefinitions
7ms
1331413672032
Slide 60
© Copyright 2012, Software Alchemy
61. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Types of Events
● User events are the majority
– Clicking on buttons and links
– Entering text
– Submitting forms
● Ajax callbacks are handled as events
● Timed events
– Periodic events (do over and over)
– Deferred events (do once after a delay)
● jQuery effects, such as fadeOut, slideDown
Bryan Basham – Web Development using jQuery Slide 61
62. ●
periodic event
RJUG: 10-April-2012
1331596413012
Clock.displayTime
5ms
1331596413017
Bryan Basham – Web Development using jQuery
1000ms
periodic event
1331596414012
Clock.displayTime
4ms
1331596414016
possible on the queue:
1000ms
Periodic Events
periodic event
1331596415022
Clock.displayTime
4ms
1331596415026
1000ms
periodic event
1331596416019
Periodic Events are placed as evenly as
Clock.displayTime
4ms
1331596416023
Slide 62
© Copyright 2012, Software Alchemy
63. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Multi-User Event Polling
Edit
Exa
add m
Sec
ad tion
Bryan getC dSecti
u on
getC rrentE Server
urre vents
add ntEven CertExam
getC Secti ts
urre on
n tE
ven
ts
Command EditExam Section
Servlet CommandHandler
am
EditEx
n
ctio Objective
addSe vents
ntE
urre ction
getC fySe
i e
mod bjectiv s
O nt
add ntEve
urre
getC
Rob
Bryan Basham – Web Development using jQuery Slide 63
64. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Multi-User Event Polling (code)
● The Screen initializer starts the periodic poller:
// start the action poller
setInterval(Screen.multiUserEventPoller, Screen.POLL_EVENTS_INTERVAL);
● Each period an Ajax request is sent:
multiUserEventPoller : function() {
var command = Screen.makeCommand('getCurrentEvents', {
'examCode': Screen.EXAM_CODE,
});
$.ajax('/SurveyTool/CommandProcessor', {
type: 'POST',
data: { 'command': JSON.stringify(command) },
success: Screen.eventPollerSuccessCallback,
failure: Screen.genericFailureCallback
})
},
eventPollerSuccessCallback: function(respJSON) {
$.each(respJSON.events, Screen.processUserEvent);
},
Bryan Basham – Web Development using jQuery Slide 64
65. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Multi-User Event Poller (code2)
● The event process changes the page:
processUserEvent: function(idx, actionEvent) {
// process the action in the main content
var eventName = actionEvent.eventName;
switch (eventName) {
case 'joinSession':
Screen.addUserRegion(actionEvent.username, actionEvent.data);
break;
case 'addSection':
Screen.insertSectionDOM(actionEvent.sectionIdx);
break;
// many more cases
};
// add the action to the user's action history list
Screen.addUserAction(actionEvent);
},
● User event logging sketch:
addUserAction: function(actionEvent) {
// Create action name cell
// Create action details cell
// Add a row to that user's event display grid
},
Bryan Basham – Web Development using jQuery Slide 65
66. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Deferred Events
● Some times responses to user actions need to
be delayed (deferred)
– Example: the Section description hover effects;
responds to fast when mousing across sections
– Solution: provide a script to be run after a small,
but noticeable delay (just a sketch)
$('div.section_head').hover(function(event) {
Screen._deferredEvent = event;
Screen._deferredTimerId = setTimeout(showSectionText, 500);
}, function() {
if (Screen._deferredTimerId != null) {
clearTimeout(Screen._deferredTimerId);
} else {
// fade out the Section text pop-up
$(this).find('div.section_text').fadeOut('slow');
}
});
Bryan Basham – Web Development using jQuery Slide 66
67. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Hover Lasts past Delay
● This timing chart shows how the delay works:
showSectionText()
Section heading / Hover In
Deferred Event invoked
Start hover
500ms
Bryan Basham – Web Development using jQuery Slide 67
68. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Hover Out before the Delay
● This timing chart shows deferred cancelation:
Cancel deferred timer
showSectionText()
Section heading / Hover Out
Section heading / Hover In
Deferred Event invoked
Start hover
500ms
Bryan Basham – Web Development using jQuery Slide 68
69. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Using jQuery Plugins
Low-level
Wars frameworks High-level
& Warts frameworks
Data Tables JavaScript Standard APIs
Frameworks
jQuery Selectors
JQ UI
& TabPanel Using DEMO #1 Querying
Std Traversal
Plugins the DOM
In-place jQuery Traversal
Editor DEMO #3
Traditional Model(s)
Deferred jQuery
Events
Event Event Std Model
Queue Model
jQuery Event
Periodic Std APIs Registration
Events Event Types DEMO #2
Manipulating Setting
Ajax
the DOM Attributes
Effects
jQuery Review Setting CSS
Support Creating Elements
Bryan Basham – Web Development using jQuery Slide 69
70. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
jQuery Plugins
● jQuery (like many JS frameworks) supports
custom plugins
● jQuery UI library (site, API)
● Large community building plugins:
– Functional augmentation
● Selectors
● Utilities (eg, cookie management)
– GUI widgets
● Grids, Editors, Layouts, Sliders, and so on...
Bryan Basham – Web Development using jQuery Slide 70
71. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
In-place Editor
● DEMO: Section title and text editors
Click title to enable
in-place editor.
assignSectionEditor: function($attrHTML, attribute, sectionIdx) {
$attrHTML.data('currentText', $attrHTML.text());
// attach jEditable to this GUI widget
$attrHTML.editable(function(value, setting) {
var currentText = $attrHTML.data('currentText');
if (value != currentText) {
$attrHTML.data('currentText', value);
Screen.sendSectionChange($attrHTML, attribute, value,
sectionIdx);
$attrHTML.addClass('pending');
return "Sending to server...";
}
return value;
},
// options to the plugin (next slide)
Screen.makeEditableOptions(attribute));
},
Bryan Basham – Web Development using jQuery Slide 71
72. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
jEditable Options
● Plugin Options pattern
makeEditableOptions: function(attribute) {
var options = {
onblur: 'ignore',
tooltip: 'Click to edit...',
placeholder: "ENTER THE " + attribute.toUpperCase()
};
if (attribute == 'title') {
// textfield objects
options.type = 'text';
options.width = 500;
} else {
// textarea objects
options.type = 'textarea';
options.cols = 75;
options.rows = 8;
options.submit = 'OK';
options.cancel = 'Cancel';
}
return options;
},
Bryan Basham – Web Development using jQuery Slide 72
73. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
jQuery UI Library
● GUI tools library from the jQuery team
– Interactions:
● Draggable, Droppable, Resizeable...
– Widgets:
● Tabs, Autocomplete, Datepicker, Button...
– Effects
● More than just fade and slide: puff, bounce, drop...
– Utilities
● Position: framework to position widgets relatively
● Widget: custom widget framework
Bryan Basham – Web Development using jQuery Slide 73
74. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Example: Tab Panel
● DEMO: separate Exam grid by state
● Uses the following plugins:
– jQuery UI
– cookies
– jqGrid
Bryan Basham – Web Development using jQuery Slide 74
75. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Tab Panel HTML
● HTML Structure of Tab Panel:
<div id="certExamStateTabs">
<ul>
<li><a href="#newExams"><span>New</span></a></li>
<li><a href="#inDevelopmentExams"><span>In Development</span></a></li>
<li><a href="#inEvaluationExams"><span>In Evaluation</span></a></li>
<li><a href="#releasedExams"><span>Released</span></a></li>
<li><a href="#retiredExams"><span>Retired</span></a></li>
</ul>
<!-- Each DIV becomes on Tab panel for each Tab header defined above -->
<div id='newExams'>
<table id='newExamsGrid'></table>
<div id='newExamsPager'></div>
</div>
<div id='inDevelopmentExams'>
<table id='inDevelopmentExamsGrid'></table>
<div id='inDevelopmentExamsPager'></div>
</div>
...
</div>
Bryan Basham – Web Development using jQuery Slide 75
76. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Tab Panel JavaScript
● JavaScript for the Tab Panel:
$('#certExamStateTabs').tabs({// options object
cookie: { expires: 30 }, // saves selected tab in cookie state
show: function(event, ui) {
Screen._showTab($(ui.panel));
}
});
_showTab: function($tabPanel) {
var tabPanelId = $tabPanel.attr('id');
// select and/or create the grid
var $grid = Screen._attachGridToTab(tabPanelId);
// resize the Grid after a delay (allowing the tab panel to be
displayed)
var thisScreen = this;
setTimeout(function() {
Screen._resizeGrid($tabPanel, $grid);
},100);
},
Bryan Basham – Web Development using jQuery Slide 76
77. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Exam Grids
● Server-side paging, sorted data grid:
<div id='newExams'>
<table id='newExamsGrid'></table>
<div id='newExamsPager'></div>
</div>
Bryan Basham – Web Development using jQuery Slide 77
78. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Grid JavaScript
_createGrid: function(tabPanelId) {
var stateCode = Screen.stateCodeByTabPanelId[tabPanelId];
var stateDesc = tabPanelId.split('Exams')[0];
return $('#' + tabPanelId + 'Grid').jqGrid({
url: 'QueryProcessor?queryName=examByState&state=' + stateCode,
datatype: 'json',
mtype: 'GET',
colNames:['Id', 'Title', 'Category', 'State', 'Version'],
colModel:[ {name:'id', index:'id', hidden:true}
,{name:'title', index:'title', width:100}
,{name:'category', index:'category', width:50}
,{name:'state', index:'state', width:50}
,{name:'version', index:'version', width:25} ],
pager: '#' + tabPanelId + 'Pager',
sortname: 'title', sortorder: 'asc',
rowNum: 10, rowList: [10, 25, 50],
viewrecords: true,
emptyrecords: 'No ' + stateDesc + ' Exams found.',
loadtext: 'Loading ' + stateDesc + ' Exams; please wait...',
height: 300, width: 500
});
}
Bryan Basham – Web Development using jQuery Slide 78
79. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Q&A
Low-level
Wars frameworks High-level
& Warts frameworks
Data Tables JavaScript Standard APIs
Frameworks
jQuery Selectors
JQ UI
& TabPanel Using DEMO #1 Querying
Std Traversal
Plugins the DOM
In-place jQuery Traversal
Editor DEMO #3
Traditional Model(s)
Deferred jQuery
Events
Event Event Std Model
Queue Model
jQuery Event
Periodic Std APIs Registration
Events Event Types DEMO #2
Manipulating Setting
Ajax
the DOM Attributes
Effects
jQuery Review Setting CSS
Support Creating Elements
Bryan Basham – Web Development using jQuery Slide 79
80. RJUG: 10-April-2012 © Copyright 2012, Software Alchemy
Resources
● Books:
– jQuery Reference Guide (PACKT)
– Learning jQuery (PACKT)
– DOM Scripting (friends of ed)
– designing with web standards, 2nd ed. (New Riders)
● Web resources:
– jQuery: site and API
– Douglas Crawford's site and lectures
– JSON
– Other Frameworks: Prototype, script.aculo.us, ExtJS, YUI, GWT,
Dojo, and so many more
Bryan Basham – Web Development using jQuery Slide 80