Permalink
Browse files

Merge branch 'session-3'

  • Loading branch information...
2 parents e7eebe2 + 4d1affa commit 32949f735e92ee53ad6110f6bc90897634e7208e Tero Parviainen committed Mar 14, 2012
View
@@ -12,6 +12,7 @@ gem 'heroku'
gem 'execjs'
gem 'therubyracer'
gem 'jquery-rails'
+gem 'pjax_rails', :git => 'git://github.com/rails/pjax_rails.git'
gem 'twitter-bootstrap-rails', :git => 'git://github.com/seyhunak/twitter-bootstrap-rails.git', :branch => 'static'
gem 'json'
gem 'isbn_validator', :git => 'git://github.com/Eficode/isbn_validator.git'
@@ -40,3 +41,7 @@ group :test do
gem 'shoulda'
end
+group :development, :test do
+ gem 'jasminerice'
+end
+
View
@@ -7,6 +7,13 @@ GIT
activemodel (>= 3.0)
GIT
+ remote: git://github.com/rails/pjax_rails.git
+ revision: 2e024b24de958c85ae45aa9cd79870f998a8eccb
+ specs:
+ pjax_rails (0.1.7)
+ jquery-rails
+
+GIT
remote: git://github.com/seyhunak/twitter-bootstrap-rails.git
revision: 2b119e7a83f34202b6ea7f61cd3da59b170ebdd8
branch: static
@@ -72,13 +79,16 @@ GEM
guard-test (0.4.3)
guard (>= 0.4)
test-unit (~> 2.2)
+ haml (3.1.4)
heroku (2.14.0)
launchy (>= 0.3.2)
rest-client (~> 1.6.1)
rubyzip
term-ansicolor (~> 1.0.5)
hike (1.2.1)
i18n (0.6.0)
+ jasminerice (0.0.8)
+ haml
jquery-rails (1.0.17)
railties (~> 3.0)
thor (~> 0.14)
@@ -166,9 +176,11 @@ DEPENDENCIES
guard-test
heroku
isbn_validator!
+ jasminerice
jquery-rails
json
pg
+ pjax_rails!
rails (= 3.1.1)
sass-rails (~> 3.1.4)
shoulda
@@ -6,4 +6,5 @@
//
//= require jquery
//= require jquery_ujs
+//= require pjax
//= require_tree .
@@ -0,0 +1,16 @@
+$(function() {
+
+ $(document).on('click', '.query-by', function() {
+ var value = $(this).val();
+ var searchField = $('#query');
+ searchField.attr('placeholder', 'Search by '+value);
+ if (searchField.val() !== '') {
+ $('#search-form').submit();
+ }
+ });
+
+ $(document).on('ajax:success', '#search-form', function(evt, data, status, xhr) {
+ $('#book-list').html(data);
+ });
+
+});
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
@@ -0,0 +1,9 @@
+$(function() {
+
+ $(document).on('ajax:success', '.reserve-link', function(evt, data, status, xhr) {
+ $('#reservation-form').hide();
+ $('#reservation-status').html('<span class="label important">Reserved by '+data.user.email+'</span>');
+ $('#reservation-links').html('<a href="/books/'+data.book_id+'/reservations/'+data.id+'/free" class="btn" data-method="put">Free</a>');
+ });
+
+});
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
@@ -3,6 +3,12 @@ class ApplicationController < ActionController::Base
before_filter :authorize
+ protected
+
+ def pjax_layout
+ 'pjax'
+ end
+
private
def current_user
@@ -16,7 +16,11 @@ def search
when 'authors' then Book.search_by_authors(params[:query])
else Book.search_by_title(params[:query])
end
- render action: :index
+ if request.xhr?
+ render partial: 'list'
+ else
+ render action: :index
+ end
end
def show
@@ -7,7 +7,7 @@ def create
flash[:notice] = "Book reserved"
respond_to do |format|
format.html { redirect_to book_path(@book) }
- format.js
+ format.json { render json: @reservation.to_json(include: :user) }
end
else
render :new
@@ -4,7 +4,7 @@ def query_by_radio_tag(field)
checked = params[:by].blank? ?
field.to_s == 'title' : params[:by] == field.to_s
output = ""
- output << (radio_button_tag :by, field, checked)
+ output << (radio_button_tag :by, field, checked, class: 'query-by')
output << field.to_s.titleize
content_tag(:span, raw(output))
end
@@ -0,0 +1,5 @@
+<% flash.each do |name,msg| %>
+ <div class="<%= flash_class(name)%>">
+ <%= msg %>
+ </div>
+<% end %>
@@ -0,0 +1,26 @@
+<div class="navbar">
+ <div class="navbar-inner">
+ <div class="container">
+ <%= link_to root_path, class: 'brand' do %>
+ <%= image_tag "books.png", width: '20px' %>
+ Library
+ <% end %>
+ <span class="pull-right">
+ <ul class="nav">
+ <% if current_user %>
+ <li>
+ <%= link_to "Log out", session_path, method: :delete %>
+ </li>
+ <% else %>
+ <li>
+ <%= link_to "Log in", new_session_path %>
+ </li>
+ <li>
+ <%= link_to "Sign up", new_user_path %>
+ </li>
+ <% end %>
+ </ul>
+ </span>
+ </div>
+ </div>
+</div>
@@ -0,0 +1,10 @@
+<% if @books.size > 0 %>
+ <dl>
+ <% @books.each do |book| %>
+ <dt><%= link_to book.title, book_path(book) %></dt>
+ <dd><%= book.authors %></dd>
+ <% end %>
+ </dl>
+<% else %>
+ <h2>Sorry, we haven't found any books!</h2>
+<% end %>
@@ -3,5 +3,5 @@
<%= link_to "Free", free_book_reservation_path(book, reservation), method: :put, class: 'btn' %>
<% end %>
<% else %>
- <%= link_to "Reserve", book_reservations_path(book), class: 'btn', remote: true, method: :post %>
+ <%= link_to "Reserve", book_reservations_path(book), class: 'btn reserve-link', remote: true, data: {type: :json}, method: :post %>
<% end %>
@@ -1,5 +1,5 @@
-<%= form_tag search_books_path, method: :get do %>
- <%= text_field_tag :query, params[:query] || 'Search by title' %>
+<%= form_tag search_books_path, method: :get, id: 'search-form', remote: true, data: {type: :html} do %>
+ <%= search_field_tag :query, params[:query], placeholder: 'Search by title' %>
<%= submit_tag 'Search', class: 'btn-primary' %>
<div>
<%= query_by_radio_tag :title %>
@@ -12,13 +12,6 @@
<%= link_to "Add a book", new_book_path, class: 'btn' %>
</p>
-<% if @books.size > 0 %>
- <dl>
- <% @books.each do |book| %>
- <dt><%= link_to book.title, book_path(book) %></dt>
- <dd><%= book.authors %></dd>
- <% end %>
- </dl>
-<% else %>
- <h2>Sorry, we haven't found any books!</h2>
-<% end %>
+<div id="book-list">
+ <%= render 'list' %>
+</div>
@@ -22,7 +22,7 @@
<%= render partial: "reservation_links", locals: {book: @book, reservation: @book_reservation} %>
</span>
-<%= link_to "Delete", book_path, method: :delete, class: 'btn btn-danger' %>
+<%= link_to "Delete", book_path, method: :delete, class: 'btn btn-danger', confirm: 'Are you sure?' %>
<p>
<%= link_to "Back to list", books_path %>
@@ -10,40 +10,12 @@
<div class="container main">
- <div class="navbar">
- <div class="navbar-inner">
- <div class="container">
- <%= link_to root_path, class: 'brand' do %>
- <%= image_tag "books.png", width: '20px' %>
- Library
- <% end %>
- <span class="pull-right">
- <ul class="nav">
- <% if current_user %>
- <li>
- <%= link_to "Log out", session_path, method: :delete %>
- </li>
- <% else %>
- <li>
- <%= link_to "Log in", new_session_path %>
- </li>
- <li>
- <%= link_to "Sign up", new_user_path %>
- </li>
- <% end %>
- </ul>
- </span>
- </div>
- </div>
+ <div data-pjax-container>
+ <%= render partial: 'navbar' %>
+ <%= render partial: 'flash', locals: {flash: flash} %>
+ <%= yield %>
</div>
-
- <% flash.each do |name,msg| %>
- <div class="<%= flash_class(name)%>">
- <%= msg %>
- </div>
- <% end %>
- <%= yield %>
-
+
</div>
</body>
@@ -0,0 +1,3 @@
+<%= render partial: 'navbar' %>
+<%= render partial: 'flash', locals: {flash: flash} %>
+<%= yield %>
@@ -1,3 +0,0 @@
-$('#reservation-form').hide();
-$('#reservation-status').html("<%=j render partial: "books/reservation_status", locals: {reservation: @reservation} %>");
-$('#reservation-links').html('<%=j render partial: "books/reservation_links", locals: {book: @book, reservation: @reservation} %>');
@@ -0,0 +1,43 @@
+//= require books
+
+describe("books.js", function() {
+
+ beforeEach(function() {
+ loadFixtures("book_search");
+ });
+
+ it("should set the search field placeholder to match the value of a clicked radio", function() {
+ $('#query-by-isbn').click();
+
+ expect($('#query').attr('placeholder')).toEqual("Search by isbn");
+ });
+
+ it("should submit the search form when a radio is clicked, if the search field is not empty", function() {
+ var submitSpy = jasmine.createSpy().andReturn(false);
+ $('#search-form').on('submit', submitSpy);
+
+ $('#query').val('my search term');
+ $('#query-by-isbn').click();
+
+ expect(submitSpy).toHaveBeenCalled();
+ });
+
+ it("should not submit the search form when a radio is clicked, if the search field is empty", function() {
+ var submitSpy = jasmine.createSpy().andReturn(false);
+ $('#search-form').on('submit', submitSpy);
+
+ $('#query').val('');
+ $('#query-by-isbn').click();
+
+ expect(submitSpy).not.toHaveBeenCalled();
+ });
+
+ it("should replace the contents of the book list when the search form gets a response", function() {
+ var newHtml = "<h2>New contents</h2>";
+
+ $('#search-form').trigger('ajax:success', newHtml);
+
+ expect($('#book-list').html()).toEqual(newHtml);
+ });
+
+});
@@ -0,0 +1,10 @@
+<form id="search-form">
+ <input id="query" type="search" placeholder="Initial">
+
+ <input id="query-by-title" class="query-by" type="radio" value="title" checked>
+ <input id="query-by-isbn" class="query-by" type="radio" value="isbn">
+
+</form>
+
+<div id="book-list">
+</div>
@@ -0,0 +1,3 @@
+//= require jquery
+//= require jquery_ujs
+//= require_tree ./

0 comments on commit 32949f7

Please sign in to comment.