.rjs and link_to_function 3
A neat little trick is that .rjs templates can be used to generate local javascript functions and be invoked without doing a server roundtrip.
playground_controller.rbclass PlaygroundController < ApplicationController
def rjs
response.headers['content-type'] = 'text/html'
end
end<html>
<head>
<%= javascript_include_tag :defaults %>
</head>
<body>
<h1 id='header'>Javascript function test</h1>
<%= link_to_function('Add', 'add_item()' ) -%> |
<%= link_to_function('Clear', 'clear_list()') %>
<ul id='list' />
<script type='text/javascript'>
<%= render :partial => 'functions', :type => 'rjs' %>
</script>
<script type='text/javascript'>
<%= # Note: following javascript is run when the page is loaded.
update_page do |page|
3.times { page.call 'add_item' }
end
%>
</script>
</body>
</html>The rjs method in the PlaygroundController set’s the content-type as we perform a render of an rjs from within a .rhtml and this seems to change the content-type, so we need to reset it.
_function.rjspage << 'function add_item() {'
page.insert_html :bottom, 'list', content_tag('li', 'item', :id => 'list_item' )
page.visual_effect :highlight, 'list', :duration => 3
page << '}'
page << 'function clear_list() {'
page.replace_html :list, ""
page.visual_effect :highlight, 'list', :duration => 3
page << '}'In the partial _function.rjs we insert the function declaration before writing to the page object. This allows us to invoke the add_item _ and clear_list _ methods using the link_to_function _ from in the .rhtml file. Note also in the .rhtml file we invoke directly the update_page method to insert three calls to add_item().
The generated html files looks like this
<html>
<head>
<script src="/javascripts/prototype.js" type="text/javascript"></script>
<script src="/javascripts/effects.js" type="text/javascript"></script>
<script src="/javascripts/dragdrop.js" type="text/javascript"></script>
<script src="/javascripts/controls.js" type="text/javascript"></script>
</head>
<body>
<h1 id='header'>Javascript function test</h1>
<a href="#" onclick="add_item(); return false;">Add</a> |
<a href="#" onclick="clear_list(); return false;">Clear</a>
<ul id='list' />
<script type='text/javascript'>
function add_item() {
new Insertion.Bottom("list", "<li id=\"list_item\">item</li>");
new Effect.Highlight('list',{duration:3});
}
function clear_list() {
Element.update("list", "");
new Effect.Highlight('list',{duration:3});
}
</script>
<script type='text/javascript'>
add_item();
add_item();
add_item();
</script>
</body>
</html>

DONT USE BLACK BACKGROUNDS! Making things difficult to read is not useful!