views:

125

answers:

2

I have a div tag in the view that I'd like to update with a graph that I generate via Gruff.

I have the following controller action which does this at the end

send_data g.to_blob, :disposition=>'inline', :type=>'image/png', :filename=>'top_n.pdf'

Now if I directly invoke this action, I can see the graph. (More details here if reqd.)

If I add a link_to_remote_tag that calls the above action via AJAX passing in specific input, generates this graph and tries to update a placeholder div tag... I see gibberish.

I think I can write the graph to a png file with g.write(filename.png) how do I embed the graph within the div tag in the view at run-time?

+1  A: 

In your link_to_remote tag just set :complete to something like this:

:complete => "updateImg(id_of_div, request.responseText)"

And write a JS function:

function updateImg(id, img)
{
  $(id).innerHTML = '<img src="' + img + '" />';
}

Where id_of_div is the id of the div when you want to show de image.

The request.responseText var come from the request of the AJAX call, I mean, when your code writes the png file with the graph, finish the method returning the path to this new png (render :text => path_to_new_image ); then, use this request variable in the :complete.

ARemesal
Updated my blog post with the solution based on this post. Thanks ARemesal.
Gishu
You're welcome ;)
ARemesal
A: 

You could use a regular img tag to call a controller action wich returns a generated png. If you set up the controller to use respond_to something like this:

def graph
    # get the relevant data for 'g' here
    respond_to do |format|
        format.html #uses the default view if relevant (good for debugging)
        format.png do 
            send_data g.to_blob, 
                :disposition=>'inline', 
                :type=>'image/png', 
                :filename=>'top_n.pdf' 
        end
    end
end

You'll even have a normal looking url for the generator like this:

<img src="controller/graph.png" alt="Something"/>

If there's a chance the image generation can fail: you could store a fallback image on the server and read that file and return that.

If the generation is quite heavy and not very likely to change all the time you cold allso cache the resulting file and get that instead if you determine that the data has not changed. You could use the method ARemesal suggested to delay adding the image link until the image is generated and then link directly to the cached file. (It depends on your specific case what's best)

Stein G. Strindhaug
Maybe I'm too much of a noob to really appreciate this post.. maybe in a few years.. thanks anyway.
Gishu