JavaScript Library Prototype

JavaScript Libraries:
Prototype.js
Prototype.js
Get it at:
http://www.prototypejs.org/
Prototype.js
•
•
•
•
•
•
Ajax interface
Utility methods
Helper methods
Extending the DOM
Class Object
…and even more!
AJAX interface
• Three objects that give you the simplest
method for AJAXifying your applications:
– Ajax.PeriodicalUpdater
– Ajax.Updater
– Ajax.Request
• Also provides the ability to register global
listeners for each step of the AJAX
requests using Ajax.Responders
Ajax.PeriodicalUpdater
new Ajax.PeriodicalUpdater(container,
url[,options])
• Updates the container with the contents of the
response text
• Options:
– Frequency: number of seconds between calls (default
is 2)
– Decay: rate at which the request interval grows when
the response in unchanged (default is 1 – or no
decay)
Ajax.Updater
new Ajax.Updater(container, url[, options])
• Replaces innerHTML of container with
response text
Ajax.Request
• new Ajax.Request(url[, options])
• Callbacks allow you to build custom
functionality with the response text instead
of just replacing innerHTML of container
element.
Ajax.Responders
• Repository of global event listeners for
each step of the AJAX request.
• Use register() and unregister() methods
• Example:
Ajax.Responders.register({
onCreate: function() {
Ajax.activeRequestCount++;
toggleIndicator();
},
onComplete: function() {
Ajax.activeRequestCount--;
toggleIndicator();
}
});
Ajax Options
• Available options:
–
–
–
–
–
–
–
–
–
method,
parameters,
asynchronous,
postBody,
requestHeaders,
insertion,
evalScripts,
decay (periodicalUpdater),
frequency (periodicalUpdater)
Ajax Callbacks
• The following are commonly used
callbacks that receive the XHR object and
the result of evaluating the X_JSON
response header if applicable:
– onSuccess,
– onFailure,
– onException,
– onComplete
Ajax Callbacks example
var myObject = Class.create();
Object.extend(myObject.prototype, {
initialize: function(options){
this.setoptions(options)
},
setoptions: function(options) {
this.options = {
ajaxurl: 'ajaxcalls.cfm',
mydivid: 'mydiv'
}
Object.extend(this.options, options || {});
},
myAjaxCall: function(){
var pars = 'action=returntrue';
var myAjax = new Ajax.Request(this.options.ajaxurl, {method: 'post', parameters:
pars, onSuccess: this.processMyAjax.bindAsEventListener(this)});
},
processMyAjax: function(t){
if (t.responseText.strip() == 1)
$(this.options.mydivid).innerHTML = 'Hello, world!';
else
window.alert('There was an error');
}
});
Event.observe(window,'load',function(){myobj = new myObject();});
Utility Methods
•
•
•
•
•
•
•
•
•
$
$$
$A
$F
$H
$R
$w
try.these
document.getElementsByClassName
$() method
• document.getElementById() on steroids
• Pass in id or element
• Pass in multiple ids will return an Array
object of all elements
$() example
1. <html xmlns="http://www.w3.org/1999/xhtml">
2. <head>
3. <script language="javascript" type="text/javascript"
src="lib/prototype.js"></script>
4. <script language="javascript" type="text/javascript">
5.
function alertDivs(){
6.
var divNodes = $('div1','div2');
7.
divNodes.each(function(node){
8.
window.alert(node.innerHTML);
9.
});
10.
}
11. </script>
12. <title>Dollar Method</title>
13. </head>
14. <div id="div1">Hello,</div>
15. <div id="div2">World!</div>
16. <a href="javascript:void(0)" onclick="alertDivs();">Alert Divs</a>
17. <body>
18. </body>
19. </html>
$$() method
• Specify any CSS rule
–
–
–
–
–
Type selectors (div)
Descendent selector (space between selectors)
Attribute selectors ([attr],[attr=value],etc…)
Class selectors (.classname)
ID selectors (#div1)
• Returns a document-order Array of elements
that match the CSS rule
• All elements inherit Prototype’s DOM Extensions
$$() method
• When to NOT use:
– You want elements with a specified CSS class
name use:
document.getElementsByClassName()
– You want elements with a specified CSS class
name within a container element use:
Element.getElementsByClassName()
$$() example
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script language="javascript" type="text/javascript"
src="lib/prototype.js"></script>
<script language="javascript" type="text/javascript">
function alertDivs(){
var divNodes = $$('div.helloworld');
divNodes.each(function(node){
window.alert(node.innerHTML);
});
}
</script>
<title>Dollar Method</title>
</head>
<div id="div1" class="helloworld">Hello, World!</div>
<div id="div2">Not me?</div>
<a href="javascript:void(0)" onclick="alertDivs();">Alert Divs</a>
<body>
</body>
</html>
$A() method
• $A(iterable)
• Takes an “array-like collection” – that’s anything with an
numeric indices
• Often used for DOM functions that return the
HTMLCollection object (an abstract representation in the
W3C DOM of any collection of HTML element objects)
• Provides the ability to use Prototype’s extended Array
class with the Enumerable module
• i.e.
– document.images
– document.getElementByTagName()
– element.childNodes
$A() example
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script language="javascript" type="text/javascript"
src="lib/prototype.js"></script>
<script language="javascript" type="text/javascript">
function alertDivs(){
var divs = document.getElementsByTagName('div');
var divNodes = $A(divs);
divNodes.each(function(node){
window.alert(node.innerHTML);
});
}
</script>
<title>Dollar Method</title>
</head>
<div>Hello, World!</div>
<div>Here we go again!</div>
<a href="javascript:void(0)" onclick="alertDivs();">Alert Divs</a>
<body>
</body>
</html>
$F() method
• $F(element)
• Returns the current value of a form control
• The current value is a string for all controls
except multiple select boxes, which return
an array of values.
• As a side note: Really, this is just a global
shortcut method for
Form.Element.getValue(element)
$H() method
• $H([obj])
• Returns instance of a Hash object (instead
of regular JS object instantiation using the
new keyword, which returns a clone of the
hash – keeping the original intact).
What’s a Hash?
• Hashes are associative arrays
• In ColdFusion, we refer to these as Structs
• Prototype extends these as well (as we’ll
see later) with the Enumerable module
$H() example
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script language="javascript" type="text/javascript"
src="lib/prototype.js"></script>
<script language="javascript" type="text/javascript">
function alertDivs(){
var h = $H({name: 'value', myfunction: function(){
window.alert('This is my function!'); }});
h.myfunction();
}
</script>
<title>Hash Example</title>
</head>
<a href="javascript:void(0)" onclick="alertDivs();">Alert my function</a>
<body>
</body>
</html>
$R() method
• $R(start, end[, exclusive = false])
• Creates a new ObjectRange object
• Returned Array is extended with
Prototype’s Enumerable module
$R() examples
$R(0, 10).include(10)
// -> true
$A($R(0, 5)).join(', ')
// -> '0, 1, 2, 3, 4, 5'
$A($R('aa', 'ah')).join(', ')
// -> 'aa, ab, ac, ad, ae, af, ag, ah'
$R(0, 10, true).include(10)
// -> false
$R(0, 10, true).each(function(value) {
// invoked 10 times for value = 0 to 9
});
$w() method
• Splits a string into an Array, treating all
whitespace as delimiters
• Returned Array is extended with
Prototype’s Enumerable class
You keep saying:
‘The element is extended with Prototype’s
DOM extensions’
or
‘The returned Array is extended with
Prototype’s Enumerable module’
What the heck are you talking
about?
I’m talking about Helpers…
• Enumerables
– Arrays
– Hashes
– Ranges
•
•
•
•
•
•
•
Element.Methods
Event
Form
Function
Insertion
Class
Object
Enumerables
•
•
•
•
•
•
•
•
•
•
•
•
all
any
collect
detect
each
entries
find
findAll
grep
include
Inject
invoke
•
•
•
•
•
•
•
•
•
•
•
•
map
max
member
min
partition
pluck
reject
select
size
sortBy
toArray
zip
Array Helpers
• Array is extended with Enumerable module
• Array is also extended with the following methods:
–
–
–
–
–
–
–
–
–
–
–
clear()
clone()
compact()
each()
first() and last()
flatten()
from()
indexOf()
reverse()
uniq()
without()
Hash Helpers
• Hash is extended with Enumerable module
• Hash is also extended with the following
methods:
–
–
–
–
–
–
–
each()
inspect()
keys()
merge()
remove()
toQueryString()
values()
Element.Methods
• Prototype extends DOM elements
• Accessed via:
– $() utility method, i.e.:
$(‘mydiv’).addClassName(‘highlight’);
– Element object, i.e.:
Element.addClassName(‘mydiv’,’highlight’);
– Or directly as methods of an extended element using
Element.extend(), i.e.:
say we have an: onclick=“highlight(this)”
function highlight(elem){
Element.extend(elem);
elem.addClassName(‘highlight’);
}
Commonly used Element methods
•
•
•
•
•
•
•
•
•
addClassName() and removeClassName()
addMethods()
cleanWhitespace()
extend()
hide() and show()
getElementsByClassName()
setStyle()
scrollTo()
update()
and more…
Element.methods
• Most methods return the element, so you
can also chain these together, i.e.:
$(‘mydiv’).addClassName(‘highlight’).upda
te(‘Changes have been saved’).toggle();
Event
• Events management made easy!
• Commonly used methods:
– observe() and stopObserving()
– findElement()
Event example
Event.observe(‘mydiv’,’click’,myFunction);
Event.stopObserving(‘mydiv’,’click’,myFunction);
Now, lets say we are using the this reference within a function, such as:
var myObj = {
ajaxurl: 'ajaxcalls.cfm',
indicatorid: 'ajaxindicator',
toggleIndicator: function(){
$(this.indicatorid).toggle();
},
myFunction: function(){
new Ajax.Request(this.ajaxurl,{parameters: pars, onSuccess:
this.myFunctionHandler});
},
myFunctionHandler: function(t){
if (t.responseText.strip() == 1){
this.toggleIndicator;
}else{
window.alert('There was an error');
}
}
}
The problem with this
• When you pass the myFunctionHandler as a
function argument you lose what this means to
the original function
• When we call this.toggleIndicator() within the
myFunctionHandler() method without using
Prototype’s binding, toggleIndicator() will not be
called.
• Prototype solves this with bind() and
bindAsEventListener()
– The only difference is that bindAsEventListener()
ensures the first argument to the function is the event
object
Binding solved, thanks Prototype!
What does it do?
Pretty simple actually: Prototype wraps the function in another one, which locks the
execution scope to an object that is specified as the first argument
var myObj = {
ajaxurl: 'ajaxcalls.cfm',
indicatorid: 'ajaxindicator',
toggleIndicator: function(){
$(this.indicatorid).toggle();
},
myFunction: function(){
new Ajax.Request(this.ajaxurl,{parameters: pars, onSuccess:
this.myFunctionHandler.bindAsEventListener(this)});
},
myFunctionHandler: function(t){
if (t.responseText.strip() == 1){
this.toggleIndicator;
}else{
window.alert('There was an error');
}
}
}
Class Object
• Prototype extends the OO nature of JS
• Class.create() returns a function that acts
like a Ruby class, that when called will fire
its own initialize() method.
Class example
var Sports = Class.create();
Sports.prototype = {
initialize: function(name,action,point){
this.name = name;
this.action = action;
this.point = point;
},
score: function(){
window.alert('The '+this.name+' player '+this.action+' a '+this.point);
}
}
var rball = new Sports('racquetball','served','ace');
rball.score();
// -> alerts 'The racquetball player served a ace'
var bball = new Sports('baseball','hit','homerun');
bball.score();
// -> alerts 'The baseball player hit a homerun'
//lets extend the Sports class to create a Swimming class
var Swimming = Class.create();
Swimming.prototype = Object.extend(new Sports(), {
score: function(){
window.alert('The '+this.name+'\'s time was '+this.point);
}
});
var swimmer = new Swimming('swimmer','','1 minute and 2 seconds');
swimmer.score();
// -> alerts 'The swimmer's time was 1 minute and 2 seconds'