tvalent2
tvalent2

Reputation: 5009

Exclude application layout in Rails 3 div

I'm loading a template profile_messages as part of jQuery UI Tabs with Ajax. However when it loads, profile_messages inherits my site's application layout (header, footer, everything). I tried doing it as a partial but then things didn't work. So I'm wondering if there was a way to do it.

The jQuery in my application.js:

$(function() {
    $( "#tabs" ).tabs({
        ajaxOptions: {
            error: function( xhr, status, index, anchor ) {
                $( anchor.hash ).html(
                    "There was an error loading this tab. Please try again." );
            }
        }
    });
});

Routes.rb:

resources :profiles do
  get :profile_messages, :on => :collection
end
match "/profiles/profile_messages" => "profiles#profile_messages"

My profiles#show.html.erb:

<div id="tabs">
  <ul id="infoContainer">
    <li><a href="#tabs-1">About</a></li>
    <li><%= link_to "Messages", '/profiles/profile_messages/', :id => 'qs', :remote => true %></li>
  </ul>
  <div id="tabs-1">
  </div>
</div>

My profile_messages template:

<div id="tabs-2">
<% for message in @user.messages %>
<% end %>
</div>

My profile_messages.js.erb:

$( "#tabs" ).html( "<%= escape_javascript( render(@profile.messages) ) %>" );

My profile_messages method in profiles_controller.rb:

def profile_messages
  @profile = User.find(user.id).profile #need to fix so @profile is defined for each profile, not just the current_user profile
  @messages = User.find(@profile.user_id).messages
  respond_to do |format|
    format.html # index.html.erb
    format.xml  { render :xml => @messages }
  end
end

So is there any way to work around the application layout?

UPDATE: I got the layout to disappear by inserting the following into my profile_messages

def profile_messages
  @profile = User.find(user.id).profile
  @messages = User.find(@profile.user_id).messages
  respond_to do |format|
    format.html { render :layout => nil }
    format.xml  { render :xml => @messages }
  end
end

UPDATE 2: I tried to render a partial but it didn't work. Here's what I changed in my profiles#show.html.erb:

<div id="tabs">
  <ul id="infoContainer">
    <li><a href="#tabs-1">About</a></li>
    <li><%= link_to render(:partial => 'profiles/profile_messages'), :id => 'qs', :remote => true do %>Messages<span>&nbsp;</span><% end %></li>
  </ul>
  <div>
  </div>
</div>

This however loads the partial in <ul id="infoContainer">

Upvotes: 0

Views: 1707

Answers (2)

mrbrdo
mrbrdo

Reputation: 8258

In the controller, add at the end of the "show" action:

render :layout => nil

Or if you render from somewhere else just add the :layout => nil option to render.

The better solution would be to make it a partial and call render :partial => "profile_messages/profile_message" (if you have the template in app/views/profile_messages/_profile_message.html.erb - note the _ in the filename!)

Also instead of using escape_javascript it's actually simpler to ditch the " quotes and use (render ...).to_json.

Upvotes: 4

Kristian PD
Kristian PD

Reputation: 2695

Do you have a response format of JS defined in your controller? It shouldn't render the layout if it renders a JS response properly. Do your logs show "responding with JS format"?

respond_to do |format|
  format.js
end

As mrbrdo mentioned, you can also do render :layout => false but it shouldn't be necessary if the JS response is being run properly.

Upvotes: 0

Related Questions