Ruben Catchme Obregon
Ruben Catchme Obregon

Reputation: 569

How should I properly refresh a partial that renders a partial (refreshing via js results in page in a page)

Update 2 - marzapower's came through again.. the success section in the ajax was causing the problem - the explanation below..

UPDATE:

marzapower's answer works well (see it below) but I needed this on a timer.

Works on the first time, but on reload it displays html markup instead of just the content.. I tried html_safe int refreshnews.js.erb file but it still doesn't work.

If I use single quotes before <% %> it bombs because 'news/newsfeed' has them too - kept single quotes and changes the partial name to double quotes.. still doesn't work right..

refreshnews.js.erb:

$("#refreshscribbles").html("<%= j(render(:partial=> 'news/newsfeed', :locals=>{:news=>@news}).html_safe) %>");

I've tried all kinds of changes - single quotes, .html_safe on the outer right parenthesis, etc.. but this is what i get instead of clean content.

RETURNED CONTENT:

sample output

news.js
$(document).ready(function() 
{

  setInterval(

     function() {

        $.ajax({
            url: '/refreshnews.js',
            type: 'GET',
            dataType: 'script',
            success: function(result) 
            {
              $('#refreshscribbles').html(result)
            }
        });
    }
  , 500);
});

Otherwise, the solution is perfect - any ideas why html_safe isn't working? Should I do something in the format.js ?


I have a news feed that I'm working on (think facebook news feed). I need to update the feed without reloading the entire page again. (The entire feed loads at once - it is not a bunch of small loads.. Rather one big load.. like returning data from a sql select)

I'm dynamically rendering a partial which renders another partial based upon values in the data..

I stole a javascript solution, and worked it into my form, but the minute it reloads the div section it uses the application layout. I've tried layout=>false etc to no avail. I've tried in the format.js respond_to section, setting layout for the controller (with except also), just about everything published out there to no avail.

What I'd really like to do is simply refresh the div with a partial without having the app layout being included. (Rails 3.2, Ruby 1.92)

news controller:

index.html.erb

<div class="actions" id="refreshscribbles">
  <%=render :partial=> 'news/newsfeed', :locals=>{:news=>@news}%>
</div>

_newsfeed.html.erb:

<% news.each do |act| %>
  <%=render :partial=> act["object_type"], :locals=>{:activity=>act}%>
  <br><%= act["object_type"]%>
  <hr>
<%end %>

news.js (note, I've tried refreshnews in the url, etc, but it all just pulls back a page within a page at best).

$(document).ready(function(){
  var timelyrefreshScribbleFeeds = function(){
    url = '/news'
    $.get(url,function(data,status){
      $('#refreshscribbles').html(data)
      return false
    });
  };
  setInterval(timelyrefreshScribbleFeeds,600);
});

news controller:

def refreshnews
  @news=News.get_newsstream(viewer_id,  @per_page, @current_page)
  respond_to do |format|
    format.html   #tried :layout => false, etc, to no avail
    format.json { render  json: @news }
  end
end

refreshnews.html.erb (empty - used to simply ignore no method error)

routes.rb

get  "refreshnews"  => "news#refreshnews", :as => "refreshnews"

How would I refresh this div via ajax/jquery? I've seen multiple solutions but not one for rendering partials that render partials etc. What is wrong with the code / solution above?

Upvotes: 2

Views: 1883

Answers (1)

marzapower
marzapower

Reputation: 5611

I would call the refreshnews using the JS format:

def refreshnews
  @news=News.get_newsstream(viewer_id,  @per_page, @current_page)
  respond_to do |format|
    format.js
  end
end

using url = '/refreshnews.js' in the javascript $.get calls:

$.ajax({
  url: '/refreshnews.js',
  type: 'GET',
  dataType: 'script'
});

You'll need a corresponding template file:

refreshnews.js.erb

$("#refreshscribbles").html("<%= j(render :partial=> 'news/newsfeed', :locals=>{:news=>@news}) %>");

Once all this is done, you should see that the app calls the refreshnews action and gets a js script that will update the main div with all the updated data you need.

Upvotes: 2

Related Questions