Alex Marchant
Alex Marchant

Reputation: 2510

Rendering a partial from javascript, Issue with passing class variables

I'm trying to set up a view with infinite scroll. I'm doing that by having javascript load a partial, but the problem is I need to pass in the variable @row (see the partial below) to calculate which objects to load.

The @row variable doesn't load when the partial is inserted via the js below.

Am I approaching this problem wrong (is there an easier way to insert rails objects), or is there a way to pass the @row variable into the partial from js.

Controller:

respond_to do |format|
  format.html
  format.js
end

The js loaded from the controller response above:

$(' #{render "shared/browse_row" ).insertAfter( $('.row') );

View:

-(1..6).each do
    = render "shared/browse_row"

browse_row partial:

.row{'data-row'=> "#{@row}"}
-@row += 1
%ul
    -@i = 0
    -project_row( @row ).each do |project|
        -@i += 1
        -@i == 4 ? right = "right" : right = ""
        %li{:class => right}
            = image_tag( project.display_pic.url(:medium) )
            .filler{'data-link' => '/projects/'+project.id.to_s }
                .filler-text
                    .p-name
                        = project.name
                        .p-creator= "by " + project.creator.name
                    .p-price= "$" + number_with_precision(project.price, :precision => 2).to_s
                    .p-days
                        - if days_left( project ) > 0
                            ="Expires in " + pluralize( days_left( project ), " Day")
                        - else
                            ="Expires Today"
                    .p-percent
                        - percent_funded(project).gsub("%","").to_i > 100 ? percent = "100%" : percent = percent_funded(project)
                        .p-percent-bar{:style => "width:#{ percent };"}

Upvotes: 1

Views: 1269

Answers (1)

iwasrobbed
iwasrobbed

Reputation: 46713

You should pass the @row instance variable into the partial when you render it using this syntax:

render :partial => "shared/browse_row", :locals => { :row => @row }

It will then be available in the browse_row partial file as a variable named row

So then you'd just change it to this:

.row{'data-row'=> "#{row}"}

In the future, you may want to do something more like this...

In the link to load more projects:

<a href="path_to/more_projects" class="get-new-projects" data-remote="true" data-method="GET">Load more projects</a>

In your controller file:

def show
  row = params[:row]
  @projects = Project.where('id > ?', row)  

  render :json => { :projects => render_to_string( :partial => 'shared/browse_row.html',
                                                   :locals => { :row => row }) }, 
         :status => :ok
end

Then in your ajax success callback:

$('.get-new-projects').live('ajax:success', function(data, json, response) {
  // insert the rendered HTML that we passed in as a JSON string
  $('.row').after(json.projects);
});

This way, you keep everything nice and organized. Your backend renders the code, your front end places the rendered code where it needs to be on the page... everyone is happy.

Upvotes: 3

Related Questions