padawan seeks advice from jedi masters to create toggle box via ajax/rjs before slitting wrists with ruby powered light-saber.

I AM TRYING TO MAKE A DAMN TOGGLE BOX, BUT USING MY OWN GRAPHIC AND HAVING THE MOUSECLICK TRIGGER BOTH SWITCHING THE GRAPHIC (via AJAX) AND SAVING THE STATE IN THE DATABASE.

I GOT IT ALL WORKING WITH NORMAL HTML GET CALLS TO THE SERVER, BUT I NEED IT TO BE AJAXIFIED SO THAT THE PAGE DOESN’T RELOAD.

AND TO COMPLICATE MATTERS, IT HAS TO WORK IN A TABLE WITH AN ARBITRARY NUMBER OF ENTRIES, AND MUST OF COURSE SPECIFICALLY UPDATE ITS OWN ROW ONLY.

So far:

I have an orders table. I want to have a graphic within

' %>IMAGE
, which when clicked calls the link_to_remote method with an :action => "toggle".

The toggle method then determines the current state of a BOOLEAN field in the database, switch that field, and then render with a call to the rjs file, which I want to update the image by replacing it with another image.

If this new image is clicked it would go through a similar process to get back to the original state.

But alas I cannot quite get there, because I can’t seem to figure out how to get rjs to take a variable so that it will update only the tag on the row where the graphic is found. I basically need to be able to pass in order.id as the name of the html id to rjs, which apparently can only take strings.

I wonder if a partial would solve this issue? Oh, will I ever be a jedi or must I always remain a padawan?

Tim

why don't you generate the complete image tag by :toggle and then
update the correpsonding div?
div.innerHtml = updatedImageTagStr;

this can be done without having to pass the current toggle status

the view
<% orders.each do |order| %>
<tr>
<td><%= order.whatever%></td>
<td id="#{order.id}"><%= link_to_remote image_tag("path_to_image"),
url_to_toggle_method(:id => order.id) %></td>
</tr>
<% end %>

the controller

def toggle
    @order = Order.find(params[:id])
    @order.toggle_the_boolean_attribute_based_on_its_current_value
    @order.save(false)
    render :update do |page|
        page.replace_html "#{@order.id}",
the_new_image_with_link_to_remote
    end
end

there are a few things missing and its untested but thats definitely
one way to go. look into render :update.

As I haven't used Ajax in rails so far (all customers wanted to stay
js-less) I can't/couldn't deliver any code :wink:

Regarding Rams suggestion:
looks like "render :update" is not propagated
--> http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/d5e7fb7347e641be

:slight_smile: you could just as well do the same in an rjs template..

Thats a valid point though, that using render :update breaks MVC.
Ive always wondered though whether breaking the pattern in such cases
is really gonna harm the application or is it just breaking a
principle.
if its really gonna harm the application, render :update probably
would not even exist right?

Got it!!! Here are the key steps:

The view should decide which image to present based on the info in the
order.placed_date column and link it remotely to the toggle action.
Don't mind the span tags, they are there just to hide some text which
can be used for sorting (can't really sort off an image, right?).

View:
<td id=<%= order.id %> colspan=1 align="center">
<% if order.placed_date == nil then %>
<span class="hidden">nil</span><div id="image"><%= link_to_remote
image_tag("unselected.png"), :url => { :controller =>
"orders", :action => "toggle", :id => order } %></div>
<% else %>
<span class="hidden">sel</span><div id="image"><%= link_to_remote
image_tag("selected.png"), :url => { :controller => "orders", :action
=> "toggle", :id => order } %></div>
<% end %></td>

The toggle method updates the database and toggles between rjs files
Order:
    def toggle
       @order = Order.find(params[:id])
       if @order.placed_date == nil
        @order.placed_date = Date.today

        respond_to do |format|
          format.js {render :action => "selectedGraphicClicked.rjs"}
        end
      else
        @order.placed_date = nil
        respond_to do |format|
          format.js {render :action => "unselectedGraphicClicked.rjs"}
        end
      end
        @order.save
      end
    end

The rjs file identifies the id to replace using the @order.id.to_s and
replaces the html with a new link_to_remote as shown below:
rjs file 1:
page[@order.id.to_s].replace_html link_to_remote(image_tag
("selected.png"), :url => { :controller => "orders", :action =>
"toggle", :id => @order })

rjs file2:
page[@order.id.to_s].replace_html link_to_remote(image_tag
("unselected.png"), :url => { :controller => "orders", :action =>
"toggle", :id => @order })

This code can likely be cleaned up quite a bit but I am going to enjoy
clicking the buttons and watching the server update the database, and
the javascript executing seamlessly for a while before I change
anything. Thanks for the responses.
Tim