Kellogs
Kellogs

Reputation: 471

Rails: Rendering Partials through Ajax

I have a page with tabs and I want to just render different partials through ajax when the tabs are clicked upon. I have some code but I don't think it is the most efficient way. I was hoping if anyone can help me with my code that is already in place or if there is an easier method I would appreciate it a lot. Thank you!

HTML Tab

<li class='StreamTab StreamTabRecent active'>
<%= link_to 'Most Recent', mostrecent_schools_path, :remote => true, :class => 'TabText' %>
</li>


<div id='ContentBody'>
<div id='ajax'></div>
<%= render 'users/microposts', :microposts => @microposts %>
</div>

School Controller

class SchoolsController < ApplicationController  
  def mostrecent
    @school = School.find_by_slug(request.url.gsub('http://localhost:3000/','')).id
    @microposts = @user.microposts.order('created_at DESC').paginate(:per_page => 3, :page => params[:page])
     respond_to do |format|
      format.html
      format.js
     end
  end
end

Most Recent JS

$("#ContentBody").html('<%= escape_javascript(render :partial => "users/microposts" )%>');

Routes

  resources :schools do
    collection do
        get :mostrecent
    end
  end

Upvotes: 7

Views: 12875

Answers (3)

techbrownbags
techbrownbags

Reputation: 626

I'm using rails 4.2 and @prasvin answer pointed me in the right direction but when I used

format.json { render :json => {:success => true, :html => (render_to_string 'instruments')} }

I would get an error "Missing template ... instruments..."

After some reading i found this comment rails render_to_string giving errors with partial view. @marcel mentioned you need to specify the file is a partial, partial: 'instruments', as below:

format.json { render :json => {:success => true, :html => (render_to_string partial: 'instruments')} }

Upvotes: 0

Pete Campbell
Pete Campbell

Reputation: 91

Prasvin's answer is spot-on. Returning and executing JS may seem simple but it makes debugging much nastier - how do you set a breakpoint in JS that was returned via AJAX? Instead you should include all of your JS in the page and only send data back.

Upvotes: 2

prasvin
prasvin

Reputation: 3009

See my answer to a previous post. This will give you an idea AJAX in Rails: Show model#new form after completing a model#update

What you can do is render a json in the action and pass the partial as json.

def mostrecent
  @school = School.find_by_slug(request.url.gsub('http://localhost:3000/','')).id
  @microposts = @user.microposts.order('created_at DESC').paginate(:per_page => 3, :page => params[:page])
  respond_to do |format|
    format.json { render :json => {:success => true, :html => (render_to_string 'users/microposts')} }
    format.html { }
  end
end

You can access the json in your js (i.e. a javascript/coffeescript file such as mostrecent.js or mostrecent.js.coffee) and replace the current element.

$('.TabText').live 'ajax:success', (event,data) ->
  $('#ContentBody').html(data.html) if(data.success == true)

Upvotes: 10

Related Questions