javascript libraries overview
DESCRIPTION
Day 1 of 7-days "JavaScript and Rich User Interfaces" training for my colleagues. It covers Prototype, jQuery, Dojo and qooxdoo.TRANSCRIPT
JavaScript Libraries Overview
Siarhei [email protected]
Our roadmap
Libraries: What we will cover today...
5 great open source libraries for your project.
• prototype• jQuery• dojo• qooxdoo
Libraries: General picture
Global picture
Lightweight Widgets One-page Applications
Prototype
Prototype: Overviewhttp://prototypejs.org
Prototype: Focus
• DOM manipulation• Ajax transport• Utility methods for built-in objects• Class-based OOP
Prototype: DOM manipulation
Say goodbye to getElementById()
Say hello to $()
document.getElementById("id").innerHTML = "<li>node</li>";
$("id").innerHTML = "<li>node</li>";
$(element) extended DOM element
Prototype: DOM Element extension
* absolutize * addClassName * addMethods * adjacent * ancestors * childElements * classNames * cleanWhitespace * clonePosition * cumulativeOffset * cumulativeScrollOffset * descendantOf * descendants * down * empty
* makePositioned * match * next * nextSiblings * observe * positionedOffset * previous * previousSiblings * readAttribute * recursivelyCollect * relativize * remove * removeClassName * replace * scrollTo
* extend * fire * firstDescendant * getDimensions * getElementsByClassName * getElementsBySelector * getHeight * getOffsetParent * getStyle * getWidth * hasClassName * hide * identify * immediateDescendants * insert * inspect * makeClipping
* select * setOpacity * setStyle * show * siblings * stopObserving * toggle * toggleClassName * undoClipping * undoPositioned * up * update * viewportOffset * visible * wrap * writeAttribute
$('message').addClassName('read').update('I read this message!').setStyle({opacity: 0.5});
Prototype: Creating a DOM elementThe old way:
var a = document.createElement('a');a.setAttribute('class', 'foo');a.setAttribute('href', '/foo.html');a.appendChild(document.createTextNode("Next page"));
The new way:
var a = new Element('a', { 'class': 'foo', href: '/foo.html' }).update("Next page");
Prototype: Even more bucks
$((id | element)...) -> [HTMLElement...]
$$(cssRule...) -> [HTMLElement...]
$A(iterable) -> actualArray
$F(element) -> value
$H([obj]) -> Hash
$R(start, end[, exclusive = false]) -> ObjectRange
$w(String) -> Array
$('foo').observe('click', respondToClick);
function respondToClick(event) { var element = event.element(); element.addClassName('active');}
Prototype: Event handling
Prototype: Ajax transport
new Ajax.Request('/some_url',{ method:'get', onSuccess: function(transport){ var response = transport.responseText || "no response text"; alert("Success! \n\n" + response); }, onFailure: function(){ alert('Something went wrong...') } });
Also available are onXXX callbacks, where XXX is the HTTP response status like 200 or 404.
Prototype: Ajax transport
new Ajax.Request('/some_url', { method: 'get', parameters: {company: 'example', limit: 12} });
new Ajax.Request('/some_url', { parameters: $('id_of_form_element').serialize(true) });
form serialization
Prototype: Ajax magic
new Ajax.Updater( { success: 'products', failure: 'errors' }, '/some_url', { method: 'get', insertion: Insertion.Top } );
1
3.13.2
2
4
Prototype: Built-in object extensions * all * any * collect * detect * each * eachSlice * entries * find * findAll * grep * inGroupsOf * include * inject * invoke * map * max * member * min * partition * pluck * reject * select * size * sortBy * toArray * zip
var myObject = {};
['foo', 'bar', 'baz'].each(function(name, index) { this[name] = index; }, myObject); // we have specified the context myObject //-> { foo: 0, bar: 1, baz: 2}
Prototype: Built-in object extensions * blank * camelize * capitalize * dasherize * empty * endsWith * escapeHTML * evalJSON * evalScripts * extractScripts * gsub * include * inspect * interpolate * isJSON * parseQuery * scan * startsWith * strip * stripScripts * stripTags * sub * succ * times * toArray * toJSON * toQueryParams * truncate * underscore * unescapeHTML * unfilterJSON
"<h1>hello, i'm HTML</h1>".escapeHTML() //-> "<h1>hello, i'm HTML</h1>"
'background-color'.camelize(); // -> 'backgroundColor'
'Prototype framework'.include('frame'); //-> true'Prototype framework'.include('frameset');//-> false
"echo ".times(3); //-> "echo echo echo "
"#{animals} on a #{transport}".interpolate({ animals: "Pigs", transport: "Surfboard" });
//-> "Pigs on a Surfboard"
Prototype: Class-based OOPvar Person = Class.create({ initialize: function(name) { this.name = name; }, say: function(message) { return this.name + ': ' + message; }});
var Pirate = Class.create(Person, { // redefine the speak method say: function($super, message) { return $super(message) + ', yarr!'; }});
var john = new Pirate('Long John');john.say('ahoy matey');// -> "Long John: ahoy matey, yarr!"
Prototype: Real life examplehttp://gmx.com http://web.de http://gmx.de
Prototype: Conclusion
• lightweight• good for small projects• a lot of useful methods• transport support• effects with script.aculo.us• good documented• a lot of real project which use prototype
Questions?
jQuery
jQuery: Focus
Motto: Write less, do more.
• DOM manipulation• Ajax transport• Effects• Other functionality with plugins
jQuery: DOM manipulation
Very powerful selectors.
$("#myDiv").css("border","3px solid red");
$("div").css("border","3px solid red");
$(".myClass").css("border","3px solid red");
$("*").css("border","3px solid red");
$("div,span,p.myClass").css("border","3px solid red");
jQuery: DOM manipulationEven more powerful than you expect.
$('li:eq(0)')
$('li:even')
$('li:lt(3)')
$('li:not(.goofy)')
$('p a[href*=#]')
$('code, li.goofy')
$('ol .goofy > strong')
$('li + li > a[href$=pdf]')
$('span:hidden')
jQuery: DOM manipulation
Attributes:attr( name )attr( properties )attr( key, value )attr( key, value )removeAttr( name )
Classes:addClass( class )hasClass( class )removeClass( class )toggleClass( class )
Text:
HTML:
Value:
html( )html( val )
text( )text( val )
val( )val( val )
jQuery: DOM manipulation
append( content )appendTo( content )
prepend( content )prependTo( content )
after( content )before( content )
insertAfter( content )insertBefore( content )
wrap( html )
replaceWith( content )
clone( )
jQuery: Events
Very convenient event handling system.
bind( type, data, fn )
trigger( type, data )
unbind( type, data )
3 main methods:
jQuery: Binding event handlers
$("p").bind("click", function(e){ var str = "( " + e.pageX + ", " + e.pageY + " )"; $("span").text("Click happened! " + str);});
$("p").bind("dblclick", function(){ $("span").text("Double-click happened in " + this.tagName);});
$("p").bind("mouseenter mouseleave", function(e){ $(this).toggleClass("over");});
$("p").trigger("click");
jQuery: Binding event handlers
$("p").click(function(e){ var str = "( " + e.pageX + ", " + e.pageY + " )"; $("span").text("Click happened! " + str);});
$("p").dblclick(function(){ $("span").text("Double-click happened in " + this.tagName);});
$("p").click();
jQuery: Custom events
$("p").bind("myCustomEvent", function(e, myName, myValue){ $(this).text(myName + ", hi there!"); $("span").stop().css("opacity", 1) .text("myName = " + myName) .fadeIn(30).fadeOut(1000);});
$("button").click(function () { $("p").trigger("myCustomEvent", [ "John" ]);});
jQuery: onload event
$(document).ready(function () { $("p").text("The DOM is now loaded and can be manipulated.");});
jQuery: Ajax transport
$.ajax({ type: "POST", url: "some.php", data: "name=John&location=Boston", success: function(msg){ alert( "Data Saved: " + msg ); } });
$.ajax({ url: "test.html", cache: false, success: function(html){ $("#results").append(html); }});
jQuery: Ajax transport
$.ajax({ url:"http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json", dataType:"jsonp", jsonp:"jsoncallback", success: function(data){ //... }) }})
jQuery: Effects
show/hidetoggle
slideDown/slideUpslideToggle
fadeIn/fadeOutfadeTo
animate
jQuery: Conclusion
• lightweight• powerful CSS selectors• ‘less code’ way• built-in effects and animation• transport support (including cross-domain)• a lot of real-life examples
Questions?
Dojo
Dojo: Focus
• DOM manipulation• Animations• Ajax• Event and keyboard normalization • Internationalization (i18n)• Widgets
Dojo: Package system
Dojo has a package system built-in to load all the code you need, and is controlled by dojo.require().
This function allows us to pull in parts of the Dojo Toolkit not provided for in the Base dojo.js, such as Drag and Drop, additional animations, Dijit widgets, DojoX projects, or even your own code.
dojo.require("dijit.form.Button");dojo.require("dijit.TitlePane");
Dojo: Selectors
dojo.addOnLoad(function(){ // our dom is ready, get the node: dojo.query("#testHeading") // add "testClass" to its class="" attribute .addClass("testClass") // and fade it out after 500 ms .fadeOut({ delay:500 }).play();});
Dojo: Event handling
dojo.addOnLoad(function(){ var node = dojo.byId("testHeading"); dojo.connect(node,"onclick",function(){ node.innerHTML = "I've been clicked"; }); });
dojo.addOnLoad(function(){ dojo.query("#testHeading") .style("cursor","pointer") .connect("onclick",function(){ this.innerHTML = "I've been clicked"; }); });
Dojo: Ajax transportvar init = function(){ var contentNode = dojo.byId("content"); dojo.xhrGet({ url: "js/sample.txt", handleAs: "text", load: function(data,args){ // fade out the node we're modifying dojo.fadeOut({ node: contentNode, onEnd: function(){ // set the data, fade it back in contentNode.innerHTML = data; dojo.fadeIn({node: contentNode}).play(); } }).play(); }, // if any error occurs, it goes here: error: function(error,args){ console.warn("error!",error); } });}; dojo.addOnLoad(init);
// sumbit the form var formSubmit = function(e){ // prevent the form from actually submitting e.preventDefault(); // submit the form in the background dojo.xhrPost({ url: "alternate-submit.php", form: "mainForm", handleAs: "text", handle: function(data,args){ if(typeof data == "error"){ console.warn("error!",args); }else{ // show our response console.log(data); } } });};dojo.addOnLoad(function(){ var theForm = dojo.byId("mainForm"); // another dojo.connect syntax: call a function directly dojo.connect(theForm,"onsubmit",formSubmit);});
Dojo: Ajax transport
Dojo: WidgetsFirst Name:<input type="text" size="20" name="first" dojoType="dijit.form.TextBox" trim="true" propercase="true" />
Price: <input type="text" maxlength="12" class="fillwidth currency" id="grossincome" name="grossincome" value="0.00" dojoType="dijit.form.CurrencyTextBox" required="true" onChange="updateTotals()" currency="USD"/>
dojo.require("dijit.form.TextBox");dojo.require("dijit.form.CurrencyText");
Dojo: Dijit at a Glance
CheckBox
ComboBox CurrencyTextBox
DateTextBox
FilteringSelect InlineEditBox
NumberSpinner
NumberTextBoxSlider
Textarea
TimeTextBox
ValidationTextBox
AccordionContainerBorder ContainerContentPane
StackContainerTabContainer
Menu
Toolbar
DialogProgressBar Editor GridTree
Dojo: DojoX - Dojo eXtensions
CometdCharting
Collections
Cryptography
Data
Grid
I/OImage
Layout
Offline
String Utilities
Timing
UUIDValidate
Widgets
Wire
XML Utilities
FX
GFX
Dojo: Dojo custom build
1. groups together modules into layers2. interns external non-JavaScript files3. smooshes the layer down with ShrinkSafe4. copies all non-layered scripts to the appropriate places
Dojo: Conclusion
• not so lightweight as previous• tons of features• separate packages• custom build
Questions?
qooxdoo
qooxdoo: Focus
• One page Rich Internet Applications• A lot of ideas from Qt• OOP approach• No HTML and CSS programming
qooxdoo: The power is in OOP
The main actors of qooxdoo OO are:
• Classes• Interfaces• Mixins
qx.Class.define("qx.test.Cat", { construct : function() { ... }});
qx.Class.define("qx.test.Cat", { ... statics : { LEGS: 4, makeSound : function() { ... } }});
qx.Class.define("qx.test.Cat", { ... members: { name : "Kitty", getName: function() { return this.name } }});
qooxdoo: Classes
qx.Class.define("qx.test.Cat", { type : "static" ...});
qx.Class.define("qx.test.Cat", { type : "abstract" ...});
qx.Class.define("qx.test.Cat", { type : "singleton" ...});
qooxdoo: Special Types of Classes
qooxdoo: Inheritance
qx.Class.define("qx.test.Animal", { members: { makeSound : function(howManyTimes) { .... } }}); qx.Class.define("qx.test.Cat", { extend: qx.test.Animal, members: { makeSound : function() { this.debug("I'm a cat"); /* howManyTimes or any other parameter are passed. We don't need to know how many parameters are used. */ arguments.callee.base.apply(this, arguments); } }});
qooxdoo: Interfaces
qx.Interface.define("qx.test.ISample", { extend: [SuperInterfaces], properties: {"color": {}, "name": {} }, members: { meth1: function() { return true; }, meth2: function(a, b) { return arguments.length == 2; }, meth3: function(c) { return qx.Class.hasInterface(c.constructor, qx.some.IInterface); } }, statics: { PI : 3.14, staticMethod: function(z) { return typeof z == "string"; } }, });
Defining interface:
qooxdoo: Interfaces
qx.Class.define("qx.test.Sample", { implement: [qx.test.ISample], properties: { "color": { check: "color"}, "name": { check: "String"} }, members: { meth1: function() { return 42; }, meth2: function(a, b) { return a+b }, meth3: function(c) { c.foo() } }});
Implementing interface:
qooxdoo: Mixins
qx.Mixin.define("name",{ include: [SuperMixins], properties: { "tabIndex": {check: "Number", init: -1} }, members: { prop1: "foo", meth1: function() {}, meth2: function() {} }});
Defining mixin:
qooxdoo: Mixins
qx.Class.define("my.cool.Class", { include : [my.cool.MMixin, my.other.cool.MMixin] ...});
Attaching mixin:
qx.Class.include(qx.ui.core.Widget, qx.MWidgetExtensions);
...properties : { width : { check : "Number", apply : "applyWidth" }} members : { applyWidth : function(value) { this.setStyleProperty("width", value + "px"); }}...
qooxdoo: Properties
widget.addEventListener("changeWidth", function(e) { e.getValue().innerHTML = "Hello World";});
qooxdoo: GUI
qooxdoo: GUI and even more features
• Layouting• Widgets• Interaction• Selection Handling• Drag & Drop • Theming• Low-level Ajax Transport• RPC• Logging and Debugging• Unit testing
qooxdoo: Tooling
Generator:
• Optimization• Compressing• Internalization • API Documentation• More
XML description for UI - qxtransformer
http://qxtransformer.org
Questions?