2
votes

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
2

2 Answers

2
votes

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.

0
votes

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?