Rendering an html partial from the js block in action.respond_to--possible?

3 views
Skip to first unread message

Roy Pardee

unread,
Apr 24, 2008, 8:24:09 PM4/24/08
to Ruby on Rails: Talk
Hey All,

I'm trying to get an ajax search feature together for one of my
views. When my user types a name fragment into a text input box, the
browser makes an ajax call, passing search parameters, and dumps the
results into a <div>. I've got it basically working with render :text
in the respond_to block, but I need to send an html table w/the
results in it & so that's not going to work w/out doing serious
violence to separation of concerns. The obvious choice would seem to
be an html partial, but it looks like rails is expecting a js partial
in that branch of respond_to. Is there a graceful way of telling
rails that I really want the results from my html partial?

Here's some code to make it concrete. Here's the relevant part of the
view:

<%= text_field_tag 'name_search' %>
<%= observe_field('name_search',
:url => { :controller => "project_people", :action => "search" },
:update => "search-results",
:frequency => 1,
:with => "'q=' + encodeURIComponent($F('name_search'))+'&p=' +
$F('project_id')") -%>
<div id="search-results"></div>

And here's my controller:

def search
respond_to do |format|
@project_people =
ProjectPerson.find_person_by_name_fragment(params[:q], params[:p])
format.js {render(:partial => 'project_people', :locals => {:pp =>
@project_people })}
# format.js {render :text => "frag is '#{params[:q]}' and project
is '#{params[:p]}'" }
# format.js {render :text => debug(params) }
end
end

As is, that gets me "ActionView::ActionViewError in Project
peopleController#search"
Couldn't find template file for project_people/_project_people in
["C:/railsapps/collabtrac/app/views"]

I do indeed have a file called C:/railsapps/collabtrac/app/views/
project_people/_project_people.html.erb. If I deviously rename that
to ..._people.js.erb, then it seems to work (suprising--I would have
thought erb would have been screwed up by the disinformation in the
extension).

Sooo... I suspect I'm pretty far off the intended track here--this
seems kludgy at best. Who's got a clue for me?

Many thanks!

-Roy

Alan Smith

unread,
Apr 24, 2008, 9:07:22 PM4/24/08
to rubyonra...@googlegroups.com
Yes, you can do this in your .rjs.js file
page.replace_html('id_to_replace', :partial => "task_node", :object => @task)

I hope this helps

Frederick Cheung

unread,
Apr 25, 2008, 3:39:55 AM4/25/08
to rubyonra...@googlegroups.com

On 25 Apr 2008, at 02:07, Alan Smith wrote:

>
> Yes, you can do this in your .rjs.js file
> page.replace_html('id_to_replace', :partial => "task_node", :object
> => @task)
>
> I hope this helps
>

The disadvantage being of course that a large blob of html is encoded
as js and then decoded on the other side.
Why not just scrap the respond_to stuff and have your action be

def search
@project_people
=ProjectPerson.find_person_by_name_fragment(params[:q], params[:p])


render(:partial => 'project_people', :locals => {:pp
=>@project_people })

end
which has worked fine for me in the past.

Fred

AndyV

unread,
Apr 25, 2008, 9:06:49 AM4/25/08
to Ruby on Rails: Talk
@Roy: It's not confused by the naming at all. The naming convention
is basically allowing you to render something for the 'js' format
request using the 'erb' rendering strategy. It's your
render :partial=>'blah' that helps it determine that the erb makes
sense, and the format.js that guides it to the 'js' format.

Also, you can simplify your observe_field by using the :submit
option. Submit allows you to provide a dom id that contains some
input fields and it's elements will be serialized and encoded in a
similar manner. The chief advantage will be maintenance:

<div id="search">
<%= hidden_field :project, :id %>
<%= text_field_tag 'name_search' %>
</div>
<%= observe_field('name_search',
:url => { :controller => "project_people", :action =>
"search" },
:update => "search-results",
:frequency => 1,
:submit => 'search' -%>
<div id="search-results"></div>

@Fred: I've done both rendering the partial for a 'replace_html' and
rendered the html and used the :update parameter on the client side.
There does not seem to be much difference in performance. The :update
approach, though, probably makes more sense if you are updating only
one region of the page (as here).

On Apr 25, 3:39 am, Frederick Cheung <frederick.che...@gmail.com>
wrote:

Frederick Cheung

unread,
Apr 25, 2008, 10:12:56 AM4/25/08
to rubyonra...@googlegroups.com

On 25 Apr 2008, at 14:06, AndyV wrote:

>
> @Fred: I've done both rendering the partial for a 'replace_html' and
> rendered the html and used the :update parameter on the client side.
> There does not seem to be much difference in performance. The :update
> approach, though, probably makes more sense if you are updating only
> one region of the page (as here).
>

I've done both too. It's really only for large amounts of html that it
makes a difference (and it's not something I'd worry about unless it
became a problem). The performance problems were actually mostly
serverside, doing all the escaping on a very long javascript string.

Fred

Roy Pardee

unread,
Apr 27, 2008, 12:31:22 AM4/27/08
to Ruby on Rails: Talk
Kick-ass. That :submit thing rocks. And thanks for the re-
interpretation of the js thing.

Thanks everybody!

-Roy
Reply all
Reply to author
Forward
0 new messages