I have an issue with the way replace_html works in an RJS template.
This is a copy of a post on my blog (http://blog.craz8.com
<http://blog.craz8.com/> ) that describes the problem and my working
solution to the problem.
If I have a collection of things that are output like this:
<div id="things">
<% @things.each do |thing| %>
<%= render :partial => ''thing'' %>
<% end %>
</div>
Or
<div id="things">
<%= render :partial => ''thing'', :collection =>
@things %>
</div>
I can use AJAX to insert a new ''thing'' by implementing an RJS
template
that does this, reusing the same partial layout:
page.insert_html :bottom, :partial => ''thing''
but I can''t then replace the inserted thing by doing this, as this is
implemented as element.innerHTML:
page.replace_html "thing-id", :partial =>
''thing''
There are ways around this, but they involve moving the outer element of
the thing out of the partial code, splitting the HTML across two files,
or removing and re-adding the element:
page.remove "thing-id"
page.insert_html :bottom, :partial => ''thing''
I don''t like either of these ideas, so I came up with an improvement
that replaces the entire element in the DOM, similar to IE''s
element.outerHTML:
page.replace_html_element "thing-id", :partial =>
''thing''
So, I''ve written an implementation of replace_html_element that comes
in
two parts:
* The addition to the JavaScriptGenerator class to add a
replace_html_element method
* An update to the Prototype Element implementation to perform the
client side update.
Add this code to the Application.rb (or in a separate file required by
Application.rb):
# Update the JavaScriptGenerator to add our own functionality
module ActionView
module Helpers
module PrototypeHelper
class JavaScriptGenerator
def replace_html_element(id, *options_for_render)
html = render(*options_for_render)
record "Element.replace(#{id.inspect}, #{html.inspect})"
end
end
end
end
end
Add this code to your application javascript file:
// Extend the object for our RJS extension to work
Object.extend(Element, {
replace: function(element, html) {
var el = $(element);
if (el.outerHTML) { // IE
el.outerHTML = html.stripScripts();
} else { // Mozilla
var range = el.ownerDocument.createRange();
range.selectNodeContents(el);
el.parentNode.replaceChild(range.createContextualFragment(html.stripScri
pts()), el);
}
setTimeout(function() {html.evalScripts()}, 10);
}
}
);
_______________________________________________
Rails mailing list
Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
http://lists.rubyonrails.org/mailman/listinfo/rails