Rails Against The Machine

Just a mind dump. Why are you even reading this?

Saturday, 23 February 2008

 

Switching to jquery

Prototype is well integrated with rails and with scriptalicious has most of the helpers you are likely to need but when it doesn't you have to write javascript and quickly find that prototype has almost no documentation and generally sucks at being unobtrusive.

So since I want to write a 'local live search' to take some load off my sever I'm making the switch to Jquery.

Hello jquery

Download jquery from http://docs.jquery.com/Downloading_jQuery, rename the file from jquery-x.x.x.js to jquery.js and place it in public/javascripts
<head>
<%= javascript_include_tag "jquery.js" %>
</head>

<%= link_to 'my blog', "http://railsagainstthemachine.blogspot.com/", :class => 'hello-world' %>

<script>
$(document).ready(
function() {
$(".hello-world").click( function() {
alert("Hello world!");
});
return false;
});
</script>

Ok but what we really want is jquery replacements for unobtrusive the ajax. This doesn't require any special helpers and is detailed here:
http://mad.ly/2007/05/17/jquery-ajax-rails/
http://mad.ly/2007/05/21/integrating-jquery-and-rails-javascript-functions-not-view-helpers/

The only problem with this is that in his example Geoff hard codes the div which is updated on success:

        success: function(data) {
$("#post-detail").html(data);
}


It would be nice if you could define this on success target as a property of the link so lets just do that .
<%= link_to 'show post', {:action =>'get'}, {:class => 'ajax_replace', :on_success => "post-detail" } %>


this generates the following link with a custom DOM attribute called 'on_success'
<a href="/jquery_test/get" on_success="post-detail" class="post-detail">show post</a>


without java script this results in an ordinary link with the following jquery function it becomes a ajax link which updates the on success target.

// Add ajax behavior to all links which are 'ajax_replace' classes
// the function requests html asyncronsusly and updates the target div
// specified by the 'on_success' attribute of the link
$(function() {
$(".ajax_replace").click( function() {
var on_success = this.getAttribute("on_success");
$.ajax({
url: this.href,
dataType: "html",
beforeSend: function(xhr) {xhr.setRequestHeader("Accept", "text/html");},
success: function(data) {
$("#"+on_success).html(data);
}
});
return false;
});

// Add ajax behavior to all links which are 'ajax_form' classes
// the function requests html asyncronsusly and updates the target div
// specified by the 'on_success' attribute of the link if no success target is specified
// we assume that we send as javascript

$(".ajax_form").each(
//for each selected element run this code
function( intIndex ){
//Get the target for this element
var on_success = this.getAttribute("on_success");

//setup the parameter hash
var options=getFormOptions(on_success);
//Apply ajax form to this element
$( this ).ajaxForm(options);
});//end of code applied to each element

function getFormOptions(on_success)
{
var options = {
dataType: "html",
beforeSend: function(xhr) {xhr.setRequestHeader("Accept", "text/html");},
success: function(data) {
$("#"+on_success).html(data);
}
};
return options;
}

});
The problem with this is that jquery behaviours are only bound to dom items when the document ready event fires. So any new items added as a result of the ajax request will have the required behaviour. So we turn to the live query plugin


$(document).ready(function() {
$(".ajax_form").livequery(attach_ajax_form);
$(".ajax_replace").livequery(attach_ajax_link);
});//

// Add ajax behavior to all links which are 'ajax_replace' classes
// the function requests html asyncronsusly and updates the target div
// specified by the 'on_success' attribute of the link
function attach_ajax_link()
{
$(this).click( function() {
var on_success = this.getAttribute("on_success");
$.ajax({
url: this.href,
dataType: "html",
beforeSend: function(xhr) {xhr.setRequestHeader("Accept", "text/html");},
success: function(data) {
$("#"+on_success).html(data);
}
});
return false;
});
}


// Add ajax behavior to all links which are 'ajax_form' classes
// the function requests html asyncronsusly and updates the target div
// specified by the 'on_success' attribute of the link if no success target is specified
// we assume that we send as javascript
function attach_ajax_form()
{
$( this ).each(
//for each selected element run this code
function( intIndex ){
var on_success = this.getAttribute("on_success");//Get the target for this element
var options=getFormOptions(on_success);//setup the parameter hash
$( this ).ajaxForm(options); //Apply ajax form to this element
});//end of code applied to each element
}

//Builds the form options for ajax form
function getFormOptions(on_success)
{
var options = {
dataType: "html",
beforeSend: function(xhr) {xhr.setRequestHeader("Accept", "text/html");},
success: function(data) {
$("#"+on_success).html(data);
}
};
return options;
}



Comments: Post a Comment

Subscribe to Post Comments [Atom]





<< Home

Archives

July 2007   August 2007   September 2007   December 2007   January 2008   February 2008   March 2008   April 2008   June 2008   July 2008   August 2008   October 2008   November 2008   January 2009  

This page is powered by Blogger. Isn't yours?

Subscribe to Comments [Atom]