Padawan seeks advice from jedi masters to create toggle box via ajax/rjs before slitting wrists wit

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 <div id=<%= ‘"’
+
order.id + ‘"’ + ‘>’ %>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.idas 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| %>

<%= order.whatever%> <%= link_to_remote image_tag("path_to_image"), url_to_toggle_method(:id => order.id) %> <% 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:

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

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