2

I have three links in my Rails 3 app that load information in the container beneath them using UJS. To complete the experience I want to display a bit of 'Loading...' text while the information loads. So I used some jQuery from Simone Carletti's post to try to accomplish it. Depending on the jQuery, though, two different things happen when the first link is clicked. (In both scenarios, nothing happens when the other two are clicked.)

  • Given the code below I get TypeError: 'undefined' is not a function (evaluating '$("#tabs-1").js(data)')

So to fix that I change my jQuery to $("#tabs-1").html(data);. Then:

  • TypeError goes away
  • 'Loading...' doesn't show
  • Clicking my first link renders all sorts of unformatted, extraneous code like:
    • $( "#tabs-1" ).html( " \n Text:</h4>\n \n text.</li>\n </div>\n</div>\n

The HTML generated:

<div id="tabs">
  <ul id="infoContainer">
    <li><a href="/profiles/1/profile_reviews" class="active" data-remote="true" id="profile_loader">Cred</a></li>
    <li><a href="/profiles/1/profile_about" class="inactive" data-remote="true" id="profile_loader">About</a></li>
    <li><a href="/profiles/1/profile_credits" class="inactive" data-remote="true" id="profile_loader">Credits</a></li>
    <span id="loading">Loading...</span>
  </ul>
  <div id="tabs-1">
    # load info here
  </div>
</div>

An example of my profiles_controller.rb action that loads information:

def profile_about
  @profile = Profile.find(params[:id])
  respond_to do |format|
    format.js { render :layout => nil }
  end
end

My profile_about.js.erb:

$( "#tabs-1" ).html( "<%= escape_javascript( render (:partial => "profile_about" ) ) %>" );

My application.js:

$(function() {
  var toggleLoading = function() { $("span#loading").toggle() };
  $("#profile_loader")
    .bind("ajax:loading",  toggleLoading)
    .bind("ajax:complete", toggleLoading)
    .bind("ajax:success", function(event, data, status, xhr) {
      $("#tabs-1").js(data);
    });
});

In my CSS:

span#loading {
    float:right;
    padding:10px 5px;
    color:#666666;
}

In my <head>:

<script src="/javascripts/jquery.js?1316133561" type="text/javascript"></script>
<script src="/javascripts/jquery-ui.js?1316133957" type="text/javascript"></script>
<script src="/javascripts/jquery-ujs.js?1316133561" type="text/javascript"></script>
<script src="/javascripts/application.js?1317960952" type="text/javascript"></script>
<meta name="csrf-param" content="authenticity-token"/>
<meta name="csrf-token" content="k1RB3GSMFweZ&#47;ty9haXTCWxYTOZB4DxQ90uEGTIhNo8="/>

UPDATE:

If I remove the respond_to format.js and format.xml and keep only format.html, remove the profile_about.js.erb, and keep the binding as .html(data), the console says:

ActionView:MissingTemplate (Missing template profiles/profile_about with {:handlers=>[:rxml, :builder, :rjs, :erb, :rhtml], :locale=>[:en, :en], :formats=>[:html] in view paths "/Users/me/Desktop/app/views", "/Users/me/Desktop/app/vendor/plugins/paperclip/app/views"): 
app/controllers/profiles_controller.rb:87:in 'profile_about' #format.html
app/controllers/profiles_controller.rb:86:in 'profile_about' #the respond_to to |format|

Rendered /Library/Ruby/Gems/1.8/gems/actionpack-3.0.5/lib/action_dispatch/middleware/templates/rescues/missing_template.erb within rescues/layout
Simone Carletti
  • 164,184
  • 42
  • 341
  • 356
tvalent2
  • 4,879
  • 9
  • 42
  • 83

2 Answers2

2

I got it working by replacing the jQuery I was using (above) with jQuery found in this question. It is much simpler than the jQuery I was working off of.

$(function() {
    $('#loading')
        .hide() // hide initially
        .ajaxStart(function(){
            $(this).show();
        })
        .ajaxStop(function(){
            $(this).hide();
        })
});

I also made a few minor changes to the code in my question above to make it work. In particular I removed: display:none in my css, and format.html and format.xml in my controller action.

Community
  • 1
  • 1
tvalent2
  • 4,879
  • 9
  • 42
  • 83
0

You currently have three links with the same ID; this is invalid HTML and will cause problems.

Not sure what you were trying with the .js thing; I don't even think that's a jQuery method.

You can do this either with JS, or with HTML, but I wouldn't recommend both--remove the xml and js respond_to, leave only the html. Remove the JS erb file.

In the "ajax:success" binding, keep it as .html(data).

That should be all you need to do, assuming everything else is set up correctly.

Which version of Rails are you using?

Dave Newton
  • 152,765
  • 23
  • 240
  • 286
  • Well, looks like I don't have everything set up correctly. Removing the `respond_to` format.js (and the js.erb files) no longer renders the partials after clicking the links. – tvalent2 Oct 31 '11 at 19:09
  • @tvalent2 Anything in the console? What version of Rails? My test also renders a partial, although I don't *think* that would matter. And you're definitely using jQuery (not Prototype)? – Dave Newton Oct 31 '11 at 19:20
  • @tvalent Rake routes shows what you expect? Template in the right place? – Dave Newton Oct 31 '11 at 20:33
  • @tvalent2 Put it on github; I'll take a look--it's all working fine for me. It's also best if you answer all the questions I ask instead of just one or two, 'cuz then I have to ask again, and that's boring. – Dave Newton Oct 31 '11 at 21:04