Forum: Ruby on Rails Losing my mind with Ajax link_to_remote

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
A71cea5002d1563a78a6319f1daa33d5?d=identicon&s=25 Si Wi (swill)
on 2005-12-30 03:09
I'm playing around with Rails, and I can't get this to work.  I just
can't seem to wrap my brain around it.  I'm having some trouble doing an
Ajax navigation column.  Here's what I have:

view layout:
<div id="navigation">
   <%= render(:partial => "navigation", :collection => @categories) %>
</div>

My _navigation.rhtml partial looks like:
<% if @params[:id].to_i == navigation.parentid.to_i %>
  <%= link_to_remote navigation.name, :url => {:controller => "listing",
  :action => "browse", :id => navigation.id, :update => "navigation"} %>
  <br/>
<% end %>

And my browse method is:
    def browse
        if @params[:id]
            @item_pages, @items = paginate(:items, :per_page => 10,
              :conditions => ["category_id = ?", params[:id].to_i])
        else
            @item_pages, @items = paginate(:items, :per_page => 10)
        end
    end


Now, the basic premise is that the page should first look something
like:
[Main page]
cat1
cat2       stuff_from_all_categories
cat3

[After clicking on cat1]
cat1a
cat1b      stuff_from_cat1_only
cat1c
cat1d

What do I need to do to get from main page to the cat1 page using Ajax
to update that category list?  If I change the link_to_remote in my
partial to link_to I get my categories listed properly.  However, I'm
changing pages each time and I'd love to not...

Thanks!
8aa68df8d14eff5681c8e87a073e8cca?d=identicon&s=25 Gitte Wange (Guest)
on 2005-12-30 03:41
(Received via mailing list)
Si Wi wrote:
> <% if @params[:id].to_i == navigation.parentid.to_i %>
>   <%= link_to_remote navigation.name, :url => {:controller => "listing",
>   :action => "browse", :id => navigation.id, :update => "navigation"} %>
>   <br/>
> <% end %>


Maybe it's just me, but isn't you missing the navigation element?
AFAIK the :update parameter points to e.g. a div with id "navigation".

[SNIP]

Greetings,
Gitte Wange
B554bcde846e4497eeffffc1399d3b09?d=identicon&s=25 Benjamin Stiglitz (Guest)
on 2005-12-30 03:44
(Received via mailing list)
> What do I need to do to get from main page to the cat1 page using Ajax
> to update that category list?  If I change the link_to_remote in my
> partial to link_to I get my categories listed properly.  However, I'm
> changing pages each time and I'd love to not...

Is your browse method rendering a partial without a layout to display
the content on the side? Are you sure it's not returning an error?

-Ben
A71cea5002d1563a78a6319f1daa33d5?d=identicon&s=25 Si Wi (swill)
on 2005-12-30 04:41
Benjamin Stiglitz wrote:
>> What do I need to do to get from main page to the cat1 page using Ajax
>> to update that category list?  If I change the link_to_remote in my
>> partial to link_to I get my categories listed properly.  However, I'm
>> changing pages each time and I'd love to not...
>
> Is your browse method rendering a partial without a layout to display
> the content on the side? Are you sure it's not returning an error?
>
> -Ben

I'm not sure if I'm completely follow your question (I'm finding lately
that I'm pretty dense :O), but in my browse.rhtml I have
<div id="navigation">
   <%= render(:partial => "navigation", :collection => @categories) %>
</div>

and my _navigation.rhtml is listed in my first post.

If I change the link_to_remote action to something like
def printit
   p @params
end

I see the @params hash in my webrick output.  Even without changing
that, I can see the call to /listing/browse/4?update=navigation in my
webrick output.

It seems like the action is working, but I must be missing something in
how to update the display of the categories themselves...

Any general advice on how best to accomplish this would be appreciated
as well as any troubleshooting on my current instantiation...

Thanks!
B554bcde846e4497eeffffc1399d3b09?d=identicon&s=25 Benjamin Stiglitz (Guest)
on 2005-12-30 04:53
(Received via mailing list)
> My _navigation.rhtml partial looks like:
> <% if @params[:id].to_i == navigation.parentid.to_i %>
>   <%= link_to_remote navigation.name, :url => {:controller =>
> "listing",
>   :action => "browse", :id => navigation.id, :update =>
> "navigation"} %>
>   <br/>
> <% end %>

Oh! You have :update in the URL params. Use this:

   <%= link_to_remote navigation.name, :url => {:controller =>
"listing",
   :action => "browse", :id => navigation.id}, :update =>
"navigation" %>

-Ben
3f900b38ec3b2c45427c354722fa4ce3?d=identicon&s=25 Tom Fakes (tomfakes)
on 2005-12-30 05:36
(Received via mailing list)
Once you apply all the other changes suggested here, you will need to
also
fix your browse.rhtml to be this (a single line):

   <%= render(:partial => "navigation", :collection => @categories) %>

The Update function changes everything inside the 'navigation' tag, it
does
not replace the tag itself, so your response to the update can't include
the
<div id="navigation"></div> element.

As a debugging note, you can see the parameters passed to your Rails
app,
and the URL, in the development.log file, so you don't need to change
code
to see what is going on with your requests.  Weirdly, these two items
are at
different ends of the log entry (the parameters at the beginning and the
URL
at the end)
A71cea5002d1563a78a6319f1daa33d5?d=identicon&s=25 Swill (Guest)
on 2005-12-30 16:05
Tom Fakes wrote:
> Once you apply all the other changes suggested here, you will need to
> also
> fix your browse.rhtml to be this (a single line):
>
>    <%= render(:partial => "navigation", :collection => @categories) %>
>
> The Update function changes everything inside the 'navigation' tag, it
> does
> not replace the tag itself, so your response to the update can't include
> the
> <div id="navigation"></div> element.
>
> As a debugging note, you can see the parameters passed to your Rails
> app,
> and the URL, in the development.log file, so you don't need to change
> code
> to see what is going on with your requests.  Weirdly, these two items
> are at
> different ends of the log entry (the parameters at the beginning and the
> URL
> at the end)


Benjamin,
Thanks for catching that!  I can't try it out right now, but I'm sure
that must be it.


Tom,
So, really what I ultimately want to happen is for the navigation to be
updated with the subcategories, and *also* to have the contents of the
page change to reflect only items in the category that was clicked.  So,
if my browse.rhtml should only be that 1 line, how do I accomplish that?

Thanks a lot for all of your help.
A71cea5002d1563a78a6319f1daa33d5?d=identicon&s=25 Si Wi (swill)
on 2005-12-31 01:54
Tom Fakes wrote:
> Once you apply all the other changes suggested here, you will need to
> also
> fix your browse.rhtml to be this (a single line):
>
>    <%= render(:partial => "navigation", :collection => @categories) %>
>
> The Update function changes everything inside the 'navigation' tag, it
> does
> not replace the tag itself, so your response to the update can't include
> the
> <div id="navigation"></div> element.
>
> As a debugging note, you can see the parameters passed to your Rails
> app,
> and the URL, in the development.log file, so you don't need to change
> code
> to see what is going on with your requests.  Weirdly, these two items
> are at
> different ends of the log entry (the parameters at the beginning and the
> URL
> at the end)


Ok, so I'm getting a page within the page... even after trying the
browse.rhtml change.

Any thoughts?  I feel like part of my problem is that, when you click a
link in the navigation, I want the list of categories to change as well
as the page content, so I'm pretty confused about how to go about
achieving that.  Sorry for the dumb questions...
B554bcde846e4497eeffffc1399d3b09?d=identicon&s=25 Benjamin Stiglitz (Guest)
on 2005-12-31 04:11
(Received via mailing list)
> Ok, so I'm getting a page within the page... even after trying the
> browse.rhtml change.

Is the full-page URL browse? If it is, you need to split off this
method to not use a layout. You can use the :except directive to
layout; see "Conditional layouts" at http://api.rubyonrails.com/
classes/ActionController/Layout/ClassMethods.html.

> Any thoughts?  I feel like part of my problem is that, when you
> click a
> link in the navigation, I want the list of categories to change as
> well
> as the page content, so I'm pretty confused about how to go about
> achieving that.  Sorry for the dumb questions...

Do you mean you want to update two different parts of the page? If
you're willing to live on Edge Rails (or use the RJS plugin for Rails
1.0), you can use RJS templates to update multiple parts of a parts.
Alternatively, you can generate the JavaScript to update the proper
DOM nodes and build your own Ajax request that evaluates the returned
script; see update_element_function at http://api.rubyonrails.com/
classes/ActionView/Helpers/JavaScriptHelper.html#M000437.

-Ben
455ac2a64d06dc8461f4d258d7f7e980?d=identicon&s=25 Michael Trier (Guest)
on 2005-12-31 04:53
(Received via mailing list)
I believe you need to turn the layout off in the controller:

render( :layout => false )

I'm new to this stuff too, so that's just a best guess.

Michael Trier
A71cea5002d1563a78a6319f1daa33d5?d=identicon&s=25 Si Wi (swill)
on 2005-12-31 06:34
Benjamin Stiglitz wrote:
>> Ok, so I'm getting a page within the page... even after trying the
>> browse.rhtml change.
>
> Is the full-page URL browse? If it is, you need to split off this
> method to not use a layout. You can use the :except directive to
> layout; see "Conditional layouts" at http://api.rubyonrails.com/
> classes/ActionController/Layout/ClassMethods.html.
>
>> Any thoughts?  I feel like part of my problem is that, when you
>> click a
>> link in the navigation, I want the list of categories to change as
>> well
>> as the page content, so I'm pretty confused about how to go about
>> achieving that.  Sorry for the dumb questions...
>
> Do you mean you want to update two different parts of the page? If
> you're willing to live on Edge Rails (or use the RJS plugin for Rails
> 1.0), you can use RJS templates to update multiple parts of a parts.
> Alternatively, you can generate the JavaScript to update the proper
> DOM nodes and build your own Ajax request that evaluates the returned
> script; see update_element_function at http://api.rubyonrails.com/
> classes/ActionView/Helpers/JavaScriptHelper.html#M000437.
>
> -Ben



The :except symbol was exactly what I needed.  I actually managed to
find it just before reading this post while watching the Ajax movie
linked from the JavaScriptHelper API docs.  It works great now!

Incidentally, I just love watching those movies -- I learn *so much*.
Anyone have any links to some other really good ones?  I just pause the
thing and stare at all of the code (I assume that's David, so I trust
that it's good stuff :O)

Yes, I do want to update 2 different parts, the navigation menu and the
actual page content.  Thanks a bunch for the pointers, I'll take a good
look at those.

Thanks everyone for your help, I can go to sleep feeling like I've
accomplished something now!
3f900b38ec3b2c45427c354722fa4ce3?d=identicon&s=25 Tom Fakes (tomfakes)
on 2005-12-31 21:12
(Received via mailing list)
The standard Rails Ajax replace system doesn't work so well for updating
more than one thing on the page.

If you want to update two things on the page, the easiest way is with an
RJS
template to generate the Ajax response.  RJS templates are in Edge rails
and
there is a plugin for Rails 1.0 that provides the same functionality.

Your RJS template (browse.rjs) would look like this:

	# Update the Navigation
	page.replace_html 'navigation', render(:partial => "navigation",
:collection => @categories)
	# Update the Content Area
	page.replace_html 'content_area', render(:partial => "content", ...)


You would need to change the link_to_remote call to remove the :update
=>
'navigation' piece, as this is needed with this new code.
This topic is locked and can not be replied to.