Reputation: 548
I have a simple application that is currently working, but I am trying to convert it to use ajax in order to improve the user experience so that full page reloads are not required every time a user clicks a link in the navigation. It uses a simple Header / Body / Footer approach with the nav bar included inside the header.
So currently, when I click on any of my nav items, it correctly changes the active-state CSS highlight properly, which I have done using Coffeescript.
As you will see in the code below, my 4th link in the navigation links to "new_movie_path". This page uses Nokogiri to crawl a web site (for example IMDB.com) and displays the current Box Office Top 10 movies, so it is something that can take a few moments to do and does not load instantly. This module individually is working just fine.
What I am trying to do is make it so that when I click on that link, it doesn't refresh the page, but instead, fetches the data using an ajax call and shows the result within the body of my current layout. I have added the remote: true element to the link but after much trial and error have failed to figure out the rest. Bonus: A spinner appears while the data is being loaded.
Snippets from my existing code:
/app/views/layout/application.erb.html
<body>
<%= render 'shared/header' %>
<div class="container first-contain" id="body-content">
<%= yield %>
</div>
</body>
/app/views/shared/_header.html.erb
<ul class="nav">
<li class="active"><%= link_to "Home", "#" %></li>
<li><%= link_to "About", "#" %></li>
<li><%= link_to "Contact", "#" %></li>
<li><%= link_to "New Movies", new_movie_path, remote: true %></li>
</ul>
/app/assets/javascripts/navigation.js.coffee
$ ->
changeTab = (e) ->
e.preventDefault()
$("ul.nav li.active").removeClass "active"
$(@).addClass("active")
$("ul.nav li").click changeTab
Any help in this matter is much appreciated.
Upvotes: 0
Views: 596
Reputation: 2938
You need another file to handle the AJAX request. Suppose that movies link takes you to the 'show' action, then you would have a movies/show.js.erb
view template file.
Let's say the action crawls IMDB and populates an array of names of movies in @movies
Your view file might then look like this:
<%
if @movies
out = ''
@movies.each do |m|
out += m + '\n'
end
%>
$("#body").html('<%= out %>');
<% end %>
This assumes you're using jquery ofcourse (and you should be). Essentially, you have to, one way or another, use javascript to replace the contents of your HTML body.
Upvotes: 1
Reputation: 29599
The ajax request should send you to MoviesController#new
which is already working as you've said. You need to add a new view called new.js.erb
under app/views/movies
which will contain the javascript that you want to run after the request finishes ie
# movies_controller.rb
def new
@movies = parse_movies_from_imdb
end
# new.js.erb
<% @movies.each do |movie| %>
console.log(movie);
<% end %>
Upvotes: 0