HowTo update multiple DOM elements (update_element_function)

Hi!
The problem to update multiple DOMs has struggled me for a while, and
others too I realized when browsing the web for find a solutions for my
problems. Ok, since it easy that one seldom gives something back when a
solution is found I’ll post this example here. If you want to give
response, please dont forget:

  • Was this useful for you?
  • Is this the rails way to do it?
  • Are there better solutions?
  • What ever you want to say about it!

I’m no way an experienced ‘railer’, but intrested in it!

Problem:
When something happends e.g a dropdown box changes one might want to
make a AJAX call and update some (that is, multiple) DOM elements.

Solution: Use update_element_function (people complain about the
documentation of this function (and others) including my self.)

Example:
This is a really easy example and it is complete!

search_test_controller.rb:

class SearchTestController < ApplicationController
layout “default-layout”
include ActionView::Helpers::JavaScriptHelper
include ActionView::Helpers::TagHelper

def initialize
    @s_start ="DOM3"
end

def index

end

def update
  text = ""

  text += javascript_tag(update_element_function("dom-1",
        :content => "<p style='color: red;'>Updating this 

sucker!

",
:position => :bottom))
  text += javascript_tag(update_element_function("dom-2",
        :content => "<p style='color: red;'>Updating this sucker, 

too!

",
:position => :bottom))
  text += link_to_remote("Clean up", :update => "dom-3", :url => 

{:action => “clean_up”})

  render_text "This is the part that should update dom-1 and dom-2 <br 

/>"+text
end

def clean_up
	render_text @s_start
end

end

index.rhtml:

Test

Multi DOM Update Test

Below are som data we want to update. There are two DOMs (div-tags), dom-1 and dom-2 defined here. We want to update both with one click!

<%= link_to_remote “Update DOM-1 and DOM-2”, :update => “dom-3”, :url =>
{:action => “update”} %>

This is "dom-1"
This is "dom-2"
<%= @s_start %>
------------------------------------------------------------

Hope this helps! In this way it is possible to update dynamically named
DOM-IDs, since the update_element_function is generated in the
controller (in this simple example it is static though)

With the latest Rails Edge version, you can do all that with
Sam S.'s .rjs templates, which are sort of a wrapper
around the functionality you describe.

Learn more here:
http://www.codyfauser.com/articles/2005/11/20/rails-rjs-templates

Cheers,
Thomas

Am 29.11.2005 um 11:39 schrieb rickthemick:

Hi,

although it’s common practice in the RoR scene to generate HTML via
Ajax, I have always felt a bit dirty when doing it :wink:
I have just updated my small “XML-RPC encoding for AJAX responses”
tutorial:

http://www.cip.ifi.lmu.de/~schoefma/howto/ajax_responses_with_xmlrpc

As an example, it would be possible to return a hash, like
{ :div1_text => “Hi, I’m DIV1”, :div2_text => “Hi DIV1, i’m DIV2” }
and then do something like
$(‘div1’).innerHTML = ajax_data.div1_text;
$(‘div2’).innerHTML = ajax_data.div2_text
on the client side.

I normally use this for returning ActiveRecord objects to the client and
then doing some JavaScript-DOM-magic to display them.

Rgds,
Max

Heya,

I’d say let the server do what’s it good at: generate HTML.
Let the client do, what’s it good at: display it!

I think there’s no need (except for special cases) to add the burden
of XML generating and parsing it again on the server.
Some sites like flickr share their public APIs for their own Ajax use,
so this is a case where I can see why using XML for data transfer
would be ok (also, remember that HTML really is XML…).

For more complicated functionality I’ve found .rjs templates and
the predecessor update_element_function to be indispensible and
saving hours of work and tons of code.

Thomas

Am 29.11.2005 um 15:07 schrieb Maximilian Schöfmann:

On Tue, 2005-11-29 at 12:18 +0100, Thomas F. wrote:

With the latest Rails Edge version, you can do all that with
Sam S.'s .rjs templates, which are sort of a wrapper
around the functionality you describe.

is there a way to do a render_partial on an rjs? i’d like to have part
of the page updated from an ordinary rhtml file and part from an rjs (to
change various divs).

is this possible or am i getting something entirely wrong?

Yes, the bottom of this post
(http://www.codyfauser.com/articles/2005/11/20/rails-rjs-templates)
mentions it is possible by using:

page.replace_html ‘header’, :partial => ‘my_partial’

thanks for pointing out the obvious, i actually read that article, but
seemingly, i need more C8H10N4O2 … :slight_smile:

Hi!

Indeed, using another XML encoding for plain HTML is tautologous (my
example was bad).
But I found quite some opportunities, where I wanted to do more with the
result of an Ajax call, than just updating a part of the page.
As an example, a Javascript-representation of a newly created
ActiveRecord object can be very useful - especially in more complex web
applications whose user interfaces relie a lot on Javascript and Ajax.
Or being able to throw (js-)exceptions on the client (DB-save went
wrong, validation failed etc.) enables a well-structured, client-side
mechanism for error handling and reporting.

Of course, as always with XML - there is the “XML”-overhead :slight_smile: and I’m
looking forward to check out where RJS can do a better job for me.
RJS is a really cool thing and will in fact make many things possible,
that required unlovely workarounds in the past!

Btw, I don’t think that performance is a big problem in my case: As Ajax
uses the “XmlHttpObject”, the returned content is parsed anyway (as you
mentioned: HTML is XML), doesn’t it? So the DOM representation of the
data is “for free”. And rendering a Builder template shouldn’t be any
slower than rendering a RHTML partial.

Cheers!

Max

Hi Tobias,

On 11/29/05, Tobias W. [email protected] wrote:

On Tue, 2005-11-29 at 12:18 +0100, Thomas F. wrote:

With the latest Rails Edge version, you can do all that with
Sam S.'s .rjs templates, which are sort of a wrapper
around the functionality you describe.

is there a way to do a render_partial on an rjs? i’d like to have part
of the page updated from an ordinary rhtml file and part from an rjs (to
change various divs).

is this possible or am i getting something entirely wrong?

That’s exactly what RJS is for. The insert_html and replace_html
methods let you insert or replace HTML using the same options you’d
use for render:

page.replace_html ‘sidebar’, :partial => ‘sidebar’
page.replace_html ‘comments’, :partial => ‘comment’, :collection =>
@comments

Or you can just specify an HTML string:

page.replace_html ‘status’, ‘Logged in’

Rick O. has a nice example at:

http://rails.techno-weenie.net/tip/2005/11/29/ajaxed_forms_with_rjs_templates


sam

is there a way to do a render_partial on an rjs? i’d like to have part
of the page updated from an ordinary rhtml file and part from an rjs (to
change various divs).

Yes, the bottom of this post
(http://www.codyfauser.com/articles/2005/11/20/rails-rjs-templates)
mentions it is possible by using:

page.replace_html ‘header’, :partial => ‘my_partial’