Prototype 2
Prototype 2
Stuart Halloway
[email protected]
Prototype’s Role
What is Prototype?
provides core support for Ajax
hides browser oddities
powers other libraries (Scriptaculous, Rico)
keeps things simple
works with any server stack
integrates with Rails
Prototype’s Class:
OO for JavaScript
Ajax.Request = Class.create();
Ajax.Request.Events =
['Uninitialized', 'Loading', 'Loaded', 'Interactive',
'Complete'];
create a class
Ajax.Request = Class.create();
Ajax.Request.Events =
['Uninitialized', 'Loading', 'Loaded', 'Interactive',
'Complete'];
class-level properties
Ajax.Request = Class.create();
Ajax.Request.Events =
['Uninitialized', 'Loading', 'Loaded', 'Interactive',
'Complete'];
constructor
Ajax.Request = Class.create();
Ajax.Request.Events =
['Uninitialized', 'Loading', 'Loaded', 'Interactive',
'Complete'];
instance-level properties
Ajax.Request = Class.create();
Ajax.Request.Events =
['Uninitialized', 'Loading', 'Loaded', 'Interactive',
'Complete'];
Class.create
Object.extend = function(destination, source) {
for (var property in source) {
destination[property] = source[property];
}
return destination;
}
Object.extend
OO in Prototype
stripScripts: function() {
return this.replace(new RegExp(Prototype.ScriptFragment,
'img'), '');
},
// ... snip ...
}
augmenting String
$A(element.childNodes).each(function(node){
element.removeChild(node)
});
enumeration: each
toQueryString: function() {
return this.map(function(pair) {
return pair.map(encodeURIComponent).join('=');
}).join('&');
},
enumeration: map
compact: function() {
return this.select(function(value) {
return value != undefined || value != null;
});
},
enumeration: select
Augmenting Classes
URL to invoke
new Ajax.Request(this.validateAction, {
method: 'get',
parameters: e.name + "=" + e.value,
onSuccess: (function(req) {
this.reportValidation(e, req.responseText);
}).bind(this),
onFailure: function(req) {alert(req.responseText)},
onException: function(t,e) {alert(e);}
});
HTTP verb
new Ajax.Request(this.validateAction, {
method: 'get',
parameters: e.name + "=" + e.value,
onSuccess: (function(req) {
this.reportValidation(e, req.responseText);
}).bind(this),
onFailure: function(req) {alert(req.responseText)},
onException: function(t,e) {alert(e);}
});
query string
new Ajax.Request(this.validateAction, {
method: 'get',
parameters: e.name + "=" + e.value,
onSuccess: (function(req) {
this.reportValidation(e, req.responseText);
}).bind(this),
onFailure: function(req) {alert(req.responseText)},
onException: function(t,e) {alert(e);}
});
success callback
new Ajax.Request(this.validateAction, {
method: 'get',
parameters: e.name + "=" + e.value,
onSuccess: (function(req) {
this.reportValidation(e, req.responseText);
}).bind(this),
onFailure: function(req) {alert(req.responseText)},
onException: function(t,e) {alert(e);}
});
failure callback
new Ajax.Request(this.validateAction, {
method: 'get',
parameters: e.name + "=" + e.value,
onSuccess: (function(req) {
this.reportValidation(e, req.responseText);
}).bind(this),
onFailure: function(req) {alert(req.responseText)},
onException: function(t,e) {alert(e);}
});
exception callback
Ajax.Request
call periodically
new PeriodicalExecuter(function() {
new Ajax.Updater('items',
'http://localhost:3000/retrieve_chats',
{evalScripts:true});
}, 10);
URL to invoke
new PeriodicalExecuter(function() {
new Ajax.Updater('items',
'http://localhost:3000/retrieve_chats',
{evalScripts:true});
}, 10);
interval (seconds)
xhr
$
function $() {
var results = [], element;
for (var i = 0; i < arguments.length; i++) {
element = arguments[i];
if (typeof element == 'string')
element = document.getElementById(element);
results.push(Element.extend(element));
}
return results.length < 2 ? results[0] : results;
}
$ implementation
$$("h1").each(function(e) {
Element.addClassName(e, "blueborder");
});
$$("li .showme").each(function(e) {
Effect.Pulsate(e);
});
$$
insertions
log: function(type, message) {
new Insertion.Bottom(this.element,
'<tr class="' + type + '"><td>' +
message.escapeHTML() + '</td></tr>');
Element.scrollTo(this.form);
},
insertion example
//from pragforms sample app
new Form.Element.Observer(
'search',
0.5,
function(element, value) {
Element.show('spinner');
new Ajax.Updater(
'ajaxWrapper',
'http://localhost:3000/user/search',
{ asynchronous:true,
evalScripts:true,
onComplete:function(request) {
Element.hide('spinner')
},
parameters:'search=' + encodeURIComponent(value)
}
)
}
)
observe an element
//from pragforms sample app
new Form.Element.Observer(
'search',
0.5,
function(element, value) {
Element.show('spinner');
new Ajax.Updater(
'ajaxWrapper',
'http://localhost:3000/user/search',
{ asynchronous:true,
evalScripts:true,
onComplete:function(request) {
Element.hide('spinner')
},
parameters:'search=' + encodeURIComponent(value)
}
)
}
)
interval (seconds)
//from pragforms sample app
new Form.Element.Observer(
'search',
0.5,
function(element, value) {
Element.show('spinner');
new Ajax.Updater(
'ajaxWrapper',
'http://localhost:3000/user/search',
{ asynchronous:true,
evalScripts:true,
onComplete:function(request) {
Element.hide('spinner')
},
parameters:'search=' + encodeURIComponent(value)
}
)
}
)
handler
<%= observe_field :search,
:frequency => 0.5,
:update => 'ajaxWrapper',
:complete=>"Element.hide('spinner')",
:before=>"Element.show('spinner')",
:with=>"'search=' + encodeURIComponent(value)",
:url=>{:action=>'search'} %>
Pragforms App:
www.relevancellc.com/code
Rails Samples:
www.pragmaticprogrammer.com/titles/fr_rails4java/