2

I would like to refresh a partial in Rails every time a link is clicked, but it doesn't seem to be doing anything.

Can someone spot the error?

index.html.erb

<% @users.each do |u| %>
   <% if !u.nil? and u.department_id == department.id %>
      <%= link_to "#{u.first_name} #{u.last_name}", professor_refresh_path(u.id), remote: true %>
   <% end %> 
<% end %>
<div id="profile"></div>

_profile.html.erb

Hello, <%= user %>

refresh.js.erb

$('#profile').html('<%=j render partial: "/professors/profile", locals: {user: @user} %> ');

professors_controller.rb

    def refresh
      @user = @user + 1
        respond_to do |format|
          format.html
          format.js
      end
    end

routes.rb

    resources :professors do
      get 'refresh'
    end
theoretisch
  • 1,718
  • 5
  • 24
  • 34
  • Is it not reloading or is it just [reloading the old value of the partial](http://stackoverflow.com/q/16970196/712765)? – Old Pro Jun 17 '13 at 15:59
  • @OldPro It's not reloading at all. : ( –  Jun 17 '13 at 16:03
  • what does it do then? – Nick Ginanto Jun 17 '13 at 16:05
  • @NickGinanto Well, it's not doing anything right now. What I want it to do is to add 1 to the user variable, and then refresh the partial with the new value. However, it's not loading at all, and nothing is showing up in the **index.html.erb** file where I want the partial to go. –  Jun 17 '13 at 16:07
  • see my answer, maybe it will help you a little (wait a minute, I need to write it first) – Nick Ginanto Jun 17 '13 at 16:09
  • Have you tried using a tool like firebug to make sure it isn't giving an error? – Travis Pessetto Jun 17 '13 at 16:37

4 Answers4

1

firstly, in ur refresh.js.erb u have specified profile as class. it should be an id. try using

$('#profile').replaceWith("#{escape_javascript(render partial: 'professors/profile', locals: { user: @user })}"); 

since @user is the only instance variable in the refresh method. Also, from ur code in the refresh method, it seems that u r just updating the count. hence my suggestion would be to update the value on the view with the new value rather than replacing the entire partial.

Prasad Surase
  • 6,486
  • 6
  • 39
  • 58
0
def refresh
    @user = @user + 1
    render :partial => "/professors/profile"
  end

As far as I know, @user will be undefined here, because it is simular to @user=nil+1

From controller you can not render partials. Controller can respond to view files.

def refresh
    @user=User.find(params[:id]) #you need to take data from database
    @user = @user + 1
   respond_to do |format|
   format.html
   end
  end

views/proffesors/refresh.html.erb

Hello "<%= @user %>"

P.S. Remove scripts from views and add them to proffesors.js in assets, it is good practice.

Rewrite you JS function. Remove it from html file, add class profile_links to these links, and in proffesors.js (in assets): $('.profile_links).click(function() {$("#profle").load('professors/refresh.html'}

P.P.S.

Also note, that you should add refresh to your routes

resourse :professors do
get 'refresh'
end
Joe Half Face
  • 2,303
  • 1
  • 17
  • 45
  • Thanks for your answer, but it still doesn't do anything when I click the link. –  Jun 17 '13 at 16:25
0

I'm not sure if this is what you want to be done, but using UJS is the rails way of doing partial loading

have

def refresh
    @user = @user + 1

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

have a refresh.js.erb and put it in app/views/professors and inside have

$('.profile').html('<%=j render partial: "/professors/profile", locals: {user: @user} %> ');

you don't have to provide locals, but its easier to maintain. in which case change your partial to be

Hello "<%= user %>"

since user is now a local variable in the partial which gets the value of @user

Then you can have your JS button to be with remote: true

<%= link_to "#{u.first_name} #{u.last_name}", professors_refresh_path(u), remote: true %>

just make sure the paths are allright and stuff

this will call refresh action with type js and fire the refresh.js.erb making the js there work.

for making it with timeout you need to use the jquery ajax get with javascript type by setting the accept header similiar to the answer here jQuery ajax request not triggering JS response from rails controller?

Community
  • 1
  • 1
Nick Ginanto
  • 31,090
  • 47
  • 134
  • 244
  • I'm getting an error **undefined method `professors_refresh_path' for #<#:0x00000004d7f330>**. I'm guessing it has something to do with the routes.rb file? How do I make a route to match this? –  Jun 17 '13 at 17:38
  • type rake routes in the console to see the route for refresh action. I think I had a typo it should be professor_refresh_path (singular professor not plural) – Nick Ginanto Jun 17 '13 at 18:33
  • also, as Joe's answer said, make sure to have routes for the refresh action – Nick Ginanto Jun 17 '13 at 18:37
  • It seems to be giving me another error now. It says **undefined local variable or method `user' for #<#:0x000000047e2760>**. –  Jun 18 '13 at 16:37
  • make sure to include the locals: {..} part. Also, I advise to use a debugger such as pry since I cannot debug your code error by error. Either that, or display your entire relevant code here so I can take a look – Nick Ginanto Jun 18 '13 at 16:40
  • as I wrote.. you didnt include the locals part.. see the difference between my refresh.js.erb and yours.. `$('.profile').html('<%=j render partial: "/professors/profile", locals: {user: @user} %> ');` – Nick Ginanto Jun 18 '13 at 16:59
  • So I added that to the **refresh.js.erb**, and I removed the <%= render 'profile' %> from the **index.html.erb** div#profile, and now I don't get an error, but now nothing happens when I click a link. –  Jun 18 '13 at 20:36
0

There's no great mystery here, you have a simple typo in your click handler, #profile instead of .profile.

Nowhere in your markup to you define an element with an id of "profile", which is what #profile would be matching. You only define a div with a class of "profile".

Your click handler reads:

$('#profile').load('/professors/refresh');

While your interval callback reads:

$('.profile').load('/professors/refresh');

One of these is never going to work, and based on your markup provided, it's the #profile one which runs on click.

user229044
  • 232,980
  • 40
  • 330
  • 338