March 31st, 2009 by Andrea Franz
The stable version of prototype is 1.6.0.3. I just fiddled around with the edge version (1.6.1_rc2) and I found 2 new features I really like. The first one is the Element#clone method. At last I can easily clone an element, or make a deep clone of it passing true as first argument:
<div id="genres">
<div class="genre">
<select name="genre[]">
<option>Your favorite genre...</option>
<option>Death Metal</option>
<option>Black Metal</option>
<option>Speed Metal</option>
</select>
</div>
</div>
<a id="add-genre" href="#">Add</a>
document.observe("dom:loaded", function() {
$("add-genre").observe("click", function(event) {
event.stop();
var genres = $("genres");
genres.insert(genres.down(".genre").clone(true));
});
});
Just click the Add link to add a new the select tag.
Another cool new feature is the Element Storage. You can store any kind of data inside a element, and retrieve it when you need it.
Here an example:
<div id="items">
<div class="item" id="item-1">
<h1>Item 1</h1>
<a href="#" class="save">Save</a>
</div>
<div class="item" id="item-2">
<h1>Item 2</h1>
<a href="#" class="save">Save</a>
</div>
</div>
document.observe("dom:loaded", function() {
var item = $("item-1");
var data = item.retrieve("data", {});
data.url = "http://cowboys.from.hell/items/1";
$("items").select("a.save").invoke("observe", "click", function(event) {
alert(event.target.up(".item").retrieve("data").url);
});
});
Just click the first save link and an alert will display the url I previously stored inside the first item element.
Given what I’m seeing I’m pretty excited about the upcoming version of prototype.
March 25th, 2008 by Andrea Franz
Every day I use will_paginate plugin to paginate list of records. Today I need to paginate with ajax, and googling I only found a patch for the plugin that adds some code inside the generated links. Thus I decided to write a few lines of javascript to generate the same behaviour:
var Pagination = {
initLinks: function() {
$('container').select('div.pagination a').invoke('observe', 'click', Pagination.linkHandler);
},
linkHandler: function(event) {
event.stop();
new Ajax.Updater('container', event.element().getAttribute('href'),{
method: 'get',
onComplete: Pagination.initLinks
});
}
}
document.observe('dom:loaded', Pagination.initLinks);
Obviously the code it’s not optimized, it’s just an example, but it works. You only need create a list of records inside a div caled ‘container’, and that div will be update with the content loaded by the ajax request.
[UPDATE] I like the prototype OO way to write js. So I wote the same thing with a class:
var Pagination = Class.create({
initialize: function() {
this.options = Object.extend({
container: 'container'
}, arguments[0] || {});
this.initLinks();
},
initLinks: function() {
$(this.options.container).select('div.pagination a').invoke('observe', 'click', this.linkHandler.bind(this));
},
linkHandler: function(event) {
event.stop();
new Ajax.Updater('container', event.element().getAttribute('href'),{
method: 'get',
onComplete: this.initLinks.bind(this)
});
}
});
document.observe('dom:loaded', function() {
new Pagination();
});
The latest version is more customizable because the constructor could receive a list of options. For now it’s only one, you can specify the container that will be updated, but you could add more options like the name of the spinner to show during requests and so on.