Browse files

Begin sortable presenter.

  • Loading branch information...
1 parent bc6c2c6 commit 55a1cc79499045686bd090a989ca5b2d5b59a3ce @bobbytables committed Jan 10, 2013
Showing with 117 additions and 6 deletions.
  1. +1 −0 lib/table_cloth.rb
  2. +12 −6 lib/table_cloth/presenter.rb
  3. +49 −0 lib/table_cloth/presenters/sortable.rb
  4. +55 −0 spec/lib/presenters/sortable_spec.rb
View
1 lib/table_cloth.rb
@@ -14,6 +14,7 @@ module TableCloth
module Presenters
autoload :Default, "table_cloth/presenters/default"
+ autoload :Sortable, "table_cloth/presenters/sortable"
end
module Extensions
View
18 lib/table_cloth/presenter.rb
@@ -10,10 +10,6 @@ def initialize(objects, table, view)
@table = table_definition.new(objects, view)
end
- def v
- view_context
- end
-
def render_table
raise NoMethodError, "You must override the .render method"
end
@@ -70,10 +66,20 @@ def wrapper_tag(type, value=nil, options={}, &block)
def tag_options(type, options={})
options = options.dup
- options.merge!(table.config.config_for(type))
- options.merge!(TableCloth.config.config_for(type))
+ if TableCloth.config.respond_to?(type)
+ options.merge!(table.config.config_for(type))
+ options.merge!(TableCloth.config.config_for(type))
+ end
options
end
+
+ def v
+ view_context
+ end
+
+ def params
+ v.params
+ end
end
end
View
49 lib/table_cloth/presenters/sortable.rb
@@ -0,0 +1,49 @@
+module TableCloth
+ module Presenters
+ class Sortable < Default
+ def render_header
+ wrapper_tag :thead do
+ wrapper_tag :tr, v.raw(row_headers.join("\n"))
+ end
+ end
+
+ def render_sortable(column)
+ query_string = sort_query(sort_params_for(column))
+ wrapper_tag(:a, column.human_name, href: "?#{query_string}")
+ end
+
+ def row_headers
+ columns.map do |column|
+ if !!column.options[:sortable]
+ wrapper_tag :th, render_sortable(column), class: "sortable-column"
+ else
+ column.human_name
+ end
+ end
+ end
+
+ private
+
+ def sort_params_for(column)
+ direction = params[:direction]
+ new_direction = (direction == "asc") ? "desc" : "asc"
+
+ params.update({sort_by: column.name.to_s, direction: new_direction})
+ end
+
+ def sort_query(params)
+ params.stringify_keys.map{|k,v| "#{CGI.escape(k)}=#{CGI.escape(v)}" }.join("&")
+ end
+
+ def header_values
+ columns.map do |column|
+ if !!column.options[:sortable]
+ render_sortable(column)
+ else
+ column.human_name
+ end
+ end
+ end
+ end
+ end
+end
View
55 spec/lib/presenters/sortable_spec.rb
@@ -0,0 +1,55 @@
+require "spec_helper"
+
+describe TableCloth::Presenters::Sortable do
+ let(:dummy_table) { FactoryGirl.build(:dummy_table, name: {sortable: true} ) }
+ let(:dummy_model) { FactoryGirl.build(:dummy_model) }
+ let(:objects) { FactoryGirl.build_list(:dummy_model, 3) }
+ let(:view_context) { ActionView::Base.new }
+ subject { TableCloth::Presenters::Sortable.new(objects, dummy_table, view_context) }
+ let(:params) { {sort_by: "", direction: "asc"} }
+ let(:column) { subject.columns.first }
+
+ before do
+ dummy_table.presenter(described_class)
+ subject.stub params: params
+ column.options[:sortable] = true
+ end
+
+ it "inherits from default" do
+ expect(described_class).to be < TableCloth::Presenters::Default
+ end
+
+ context ".render_sortable" do
+ before do
+ column.stub human_name: "Header"
+ end
+
+ it "renders an a tag" do
+ element = to_element(subject.render_sortable(column), "a")
+ expect(element.node_name).to eq("a")
+ end
+
+ it "renders an a tag with href direction keys" do
+ params[:direction] = "desc"
+ element = to_element(subject.render_sortable(column), "a")
+ query_string = element[:href]
+
+ expect(query_string).to include "direction=asc"
+ end
+
+ it "renders an a tag with href sort by keys" do
+ params[:sort_by] = "desc"
+ element = to_element(subject.render_sortable(column), "a")
+ query_string = element[:href]
+
+ expect(query_string).to include "sort_by=#{column.name}"
+ end
+ end
+
+ context "thead" do
+ it "includes a css class for a sortable column" do
+ header = to_element(subject.render_header, "thead")
+ expect(header.at_css("th.sortable-column")).to be_present
+ end
+ end
+end

0 comments on commit 55a1cc7

Please sign in to comment.