sorting_table_for 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,8 +6,7 @@ module SortingTableFor
6
6
 
7
7
  class TableBuilder
8
8
 
9
- include ::ActionView::Helpers::TagHelper
10
- include ::ActionView::Helpers::NumberHelper
9
+ include ::ActionView::Helpers
11
10
 
12
11
  class_inheritable_accessor :reserved_columns, :currency_columns,
13
12
  :default_boolean, :show_total_entries,
@@ -31,7 +30,7 @@ module SortingTableFor
31
30
  def initialize(collection, object_or_array, template, options, params)
32
31
  @collection, @@object_or_array, @@template, @@options, @@params = collection, object_or_array, template, options, params
33
32
  set_default_global_options
34
- I18n.set_options(params, model_name(@collection.first), object_or_array.first, @@options[:i18n])
33
+ I18n.set_options(params, model_name(@collection.first), @@options[:i18n])
35
34
  @lines = []
36
35
  end
37
36
 
@@ -135,7 +134,7 @@ module SortingTableFor
135
134
  column_options, html_options = get_column_and_html_options( args.extract_options! )
136
135
  if block_given?
137
136
  @header_line = FormatLine.new(args, column_options, html_options, nil, :thead)
138
- @@template.capture(&block)
137
+ capture(&block)
139
138
  else
140
139
  @header_line = FormatLine.new(args, column_options, html_options, @collection.first, :thead)
141
140
  end
@@ -184,7 +183,7 @@ module SortingTableFor
184
183
  #
185
184
  def header(*args, &block)
186
185
  if block_given?
187
- block = @@template.capture(&block)
186
+ block = capture(&block)
188
187
  @header_line.add_cell(@collection.first, args, nil, block)
189
188
  else
190
189
  @header_line.add_cell(@collection.first, args)
@@ -392,7 +391,7 @@ module SortingTableFor
392
391
  #
393
392
  def column(*args, &block)
394
393
  if block_given?
395
- block = @@template.capture(&block)
394
+ block = capture(&block)
396
395
  @lines.last.add_cell(@current_object, args, nil, block)
397
396
  else
398
397
  @lines.last.add_cell(@current_object, args)
@@ -451,7 +450,7 @@ module SortingTableFor
451
450
  column_options, html_options = get_column_and_html_options( args.extract_options! )
452
451
  if block_given?
453
452
  @footer_line = FormatLine.new(args, column_options, html_options, nil, :tfoot)
454
- @@template.capture(&block)
453
+ capture(&block)
455
454
  else
456
455
  @footer_line = FormatLine.new(args, column_options, html_options, @collection.first, :tfoot) if !args.empty?
457
456
  end
@@ -506,7 +505,7 @@ module SortingTableFor
506
505
  #
507
506
  def footer(*args, &block)
508
507
  if block_given?
509
- block = @@template.capture(&block)
508
+ block = capture(&block)
510
509
  @footer_line.add_cell(@collection.first, args, nil, block)
511
510
  else
512
511
  @footer_line.add_cell(@collection.first, args)
@@ -557,7 +556,7 @@ module SortingTableFor
557
556
  def caption(*args, &block)
558
557
  @caption[:option], @caption[:html] = get_column_and_html_options( args.extract_options! )
559
558
  if block_given?
560
- @caption[:value] = @@template.capture(&block)
559
+ @caption[:value] = capture(&block)
561
560
  else
562
561
  @caption[:value] = (args.empty?) ? I18n.t(:table_caption) : args.first;
563
562
  end
@@ -571,6 +570,11 @@ module SortingTableFor
571
570
  object.present? ? object.class.name : object.to_s.classify
572
571
  end
573
572
 
573
+ # Send method to ActionView
574
+ def method_missing(name, *args, &block)
575
+ @@template.send(name, *args, &block)
576
+ end
577
+
574
578
  private
575
579
 
576
580
  def render_caption
@@ -595,6 +599,7 @@ module SortingTableFor
595
599
  def render_tbody
596
600
  if @lines and @lines.size > 0
597
601
  return Tools::html_safe(content_tag(:tbody, render_total_entries + Tools::html_safe(@lines.collect { |line| line.render_line }.join)))
602
+ return Tools::html_safe(content_tag(:tr, content_tag(:td, I18n.t(:total_entries, :scope => :sorting_table_for, :value => total_entries), {:colspan => max_cells}), { :class => 'total-entries' }))
598
603
  end
599
604
  ''
600
605
  end
@@ -624,7 +629,7 @@ module SortingTableFor
624
629
  total_entries = @collection.total_entries rescue @collection.size
625
630
  header_total_cells = @header_line ? @header_line.total_cells : 0
626
631
  max_cells = (@lines.first.total_cells > header_total_cells) ? @lines.first.total_cells : header_total_cells
627
- return Tools::html_safe(content_tag(:tr, content_tag(:td, I18n.t(:total_entries, :scope => :sorting_table_for, :value => total_entries), {:colspan => max_cells}), { :class => 'total-entries' }))
632
+ return Tools::html_safe(content_tag(:tr, content_tag(:td, I18n.t(:total_entries, :value => total_entries), {:colspan => max_cells}), { :class => 'total-entries' }))
628
633
  end
629
634
  ''
630
635
  end
@@ -635,300 +640,4 @@ module SortingTableFor
635
640
  end
636
641
 
637
642
  end
638
-
639
- class FormatLine < TableBuilder
640
-
641
- def initialize(args, column_options = {}, html_options = {}, object = nil, type = nil)
642
- @args, @column_options, @html_options, @object, @type = args, column_options, html_options, object, type
643
- @cells = []
644
- if object
645
- @attributes = (args.empty?) ? (get_columns - TableBuilder.reserved_columns) : @args
646
- create_cells
647
- end
648
- end
649
-
650
- # Create a new cell with the class FormatCell
651
- # Add the object in @cells
652
- def add_cell(object, args, type = nil, block = nil)
653
- @cells << FormatCell.new(object, args, type, block)
654
- end
655
-
656
- # Return a tr line based on the type (:thead, :tbody or :tfoot)
657
- def render_line
658
- if @type == :thead
659
- return content_tag(:tr, Tools::html_safe(@cells.collect { |cell| cell.render_cell_thead }.join), @html_options)
660
- elsif @type == :tfoot
661
- return content_tag(:tr, Tools::html_safe(@cells.collect { |cell| cell.render_cell_tfoot }.join), @html_options)
662
- else
663
- content_tag(:tr, Tools::html_safe(@cells.collect { |cell| cell.render_cell_tbody }.join), @html_options.merge(:class => "#{@html_options[:class]} #{@@template.cycle(:odd, :even)}".strip))
664
- end
665
- end
666
-
667
- # Return the number of cells in line
668
- def total_cells
669
- @cells.size
670
- end
671
-
672
- protected
673
-
674
- # Return each column in the model's database table
675
- def content_columns
676
- model_name(@object).constantize.content_columns.collect { |c| c.name.to_sym }.compact rescue []
677
- end
678
-
679
- # Return true if the column is in the model's database table
680
- def model_have_column?(column)
681
- model_name(@object).constantize.content_columns.each do |model_column|
682
- return true if model_column.name == column.to_s
683
- end
684
- false
685
- end
686
-
687
- # Return true if the column is in the model's database table
688
- def can_sort_column?(column)
689
- model_have_column?(column)
690
- end
691
-
692
- # Options only for cells
693
- def only_cell_option?(key)
694
- [:colspan].include? key
695
- end
696
-
697
- # Format ask to send options to cell
698
- def format_options_to_cell(ask, options = @column_options)
699
- options.each do |key, value|
700
- if only_cell_option?(key)
701
- if ask.is_a? Hash
702
- ask.merge!(key => value)
703
- else
704
- ask = [ask] unless ask.is_a? Array
705
- (ask.last.is_a? Hash and ask.last.has_key? :html) ? ask.last[:html].merge!(key => value) : ask << { :html => { key => value }}
706
- end
707
- end
708
- end
709
- ask
710
- end
711
-
712
- private
713
-
714
- # Call after headers or columns with no attributes (table.headers)
715
- # Create all the cells based on each column in the model's database table
716
- # Create cell's actions based on option default_actions or on actions given (:actions => [:edit])
717
- def create_cells
718
- @attributes.each { |ask| add_cell(@object, format_options_to_cell(ask)) }
719
- if @args.empty?
720
- TableBuilder.default_actions.each { |action| add_cell(@object, action, :action) }
721
- else
722
- get_column_actions.each { |action| add_cell(@object, action, :action) }
723
- end
724
- end
725
-
726
- # Return an Array of all actions given to headers or columns (:actions => [:edit, :delete])
727
- def get_column_actions
728
- if @column_options.has_key? :actions
729
- if @column_options[:actions].is_a?(Array)
730
- return @column_options[:actions]
731
- else
732
- return [ @column_options[:actions] ]
733
- end
734
- end
735
- []
736
- end
737
-
738
- # Return an Array of the columns based on options :only or :except
739
- def get_columns
740
- if @column_options.has_key? :only
741
- return @column_options[:only] if @column_options[:only].is_a?(Array)
742
- [ @column_options[:only] ]
743
- elsif @column_options.has_key? :except
744
- return content_columns - @column_options[:except] if @column_options[:except].is_a?(Array)
745
- content_columns - [ @column_options[:except] ]
746
- else
747
- content_columns
748
- end
749
- end
750
-
751
- end
752
-
753
- class FormatCell < FormatLine
754
-
755
- def initialize(object, args, type = nil, block = nil)
756
- @object, @type, @block = object, type, block
757
- if args.is_a? Array
758
- @options, @html_options = get_cell_and_html_options( args.extract_options! )
759
- @ask = args.first
760
- if @ask.nil? and @options.has_key?(:action)
761
- @type = :action
762
- @ask = @options[:action]
763
- end
764
- else
765
- @ask = args
766
- end
767
- set_default_options
768
- @can_sort = true if @options and @options[:sort] and can_sort_column?(@ask)
769
- end
770
-
771
- # Return a td with the formated value or action for columns
772
- def render_cell_tbody
773
- if @type == :action
774
- cell_value = action_link_to(@ask)
775
- elsif @ask
776
- cell_value = (@ask.is_a?(Symbol)) ? format_cell_value(@object[@ask], @ask) : format_cell_value(@ask)
777
- else
778
- cell_value = @block
779
- end
780
- cell_value = action_link_to(@options[:action], cell_value) if @type != :action and @options.has_key?(:action)
781
- content_tag(:td, cell_value, @html_options)
782
- end
783
-
784
- # Return a td with the formated value or action for headers
785
- def render_cell_thead
786
- if @ask
787
- cell_value = (@ask.is_a?(Symbol)) ? I18n.t(@ask, {}, :header) : @ask
788
- else
789
- cell_value = @block
790
- end
791
- if @can_sort and @options[:sort]
792
- @html_options.merge!(:class => "#{@html_options[:class]} #{sorting_html_class}".strip)
793
- content_tag(:th, sort_link_to(cell_value), @html_options)
794
- else
795
- content_tag(:th, cell_value, @html_options)
796
- end
797
- end
798
-
799
- def render_cell_tfoot
800
- if @ask
801
- cell_value = (@ask.is_a?(Symbol)) ? I18n.t(@ask, {}, :footer) : @ask
802
- else
803
- cell_value = @block
804
- end
805
- cell_value = action_link_to(@options[:action], cell_value) if @type != :action and @options.has_key?(:action)
806
- content_tag(:td, cell_value, @html_options)
807
- end
808
-
809
- private
810
-
811
- # Return options and html options for a cell
812
- def get_cell_and_html_options(options)
813
- return options, options.delete(:html) || {}
814
- end
815
-
816
- # Set default options for cell
817
- # Set an empty hash if no html options
818
- # Set an empty hash if no options
819
- # Set sort to true if no options sort
820
- def set_default_options
821
- @html_options = {} unless defined? @html_options
822
- @options = {} unless defined? @options
823
- @html_options = format_options_to_cell(@html_options, @options)
824
- @options[:sort] = @@options[:sort] if !@options.has_key? :sort
825
- end
826
-
827
- # Create the link for actions
828
- # Set the I18n translation or the given block for the link's name
829
- def action_link_to(action, block = nil)
830
- object_or_array = @@object_or_array.clone
831
- object_or_array.push @object
832
- return case action.to_sym
833
- when :delete
834
- create_link_to(block || I18n.t(:delete), object_or_array, @@options[:link_remote], :delete, I18n.t(:confirm_delete))
835
- when :show
836
- create_link_to(block || I18n.t(:show), object_or_array, @@options[:link_remote])
837
- else
838
- object_or_array.insert(0, action)
839
- create_link_to(block || I18n.t(@ask), object_or_array, @@options[:link_remote])
840
- end
841
- end
842
-
843
- # Create sorting link
844
- def sort_link_to(name)
845
- create_link_to(name, sort_url, @@options[:sort_remote])
846
- end
847
-
848
- # Create the link based on object
849
- # Set an ajax link if option link_remote is set to true
850
- # Compatible with rails 2 and 3.
851
- def create_link_to(block, url, remote, method = nil, confirm = nil)
852
- if remote and Tools::rails3?
853
- return @@template.link_to(block, url, :method => method, :confirm => confirm, :remote => true)
854
- elsif remote
855
- method = :get if method.nil?
856
- return @@template.link_to_remote(block, { :url => url, :method => method, :confirm => confirm })
857
- end
858
- @@template.link_to(block, url, :method => method, :confirm => confirm)
859
- end
860
-
861
- # Return a string with html class of sorting for headers
862
- # The html class is based on option: SortingTableFor::TableBuilder.html_sorting_class
863
- def sorting_html_class
864
- return TableBuilder.html_sorting_class.first if current_sorting.nil?
865
- return TableBuilder.html_sorting_class.second if current_sorting == :asc
866
- TableBuilder.html_sorting_class.third
867
- end
868
-
869
- # Return an url for sorting
870
- # Add the param sorting_table[name]=direction to the url
871
- # Add the default direction: :asc
872
- def sort_url
873
- url_params = @@params.clone
874
- if url_params.has_key? TableBuilder.params_sort_table
875
- if url_params[TableBuilder.params_sort_table].has_key? @ask
876
- url_params[TableBuilder.params_sort_table][@ask] = inverse_sorting
877
- return @@template.url_for(url_params)
878
- end
879
- url_params[TableBuilder.params_sort_table].delete @ask
880
- end
881
- url_params[TableBuilder.params_sort_table] = { @ask => :asc }
882
- @@template.url_for(url_params)
883
- end
884
-
885
- # Return a symbol of the current sorting (:asc, :desc, nil)
886
- def current_sorting
887
- if @@params.has_key? TableBuilder.params_sort_table and @@params[TableBuilder.params_sort_table].has_key? @ask
888
- return @@params[TableBuilder.params_sort_table][@ask].to_sym
889
- end
890
- nil
891
- end
892
-
893
- # Return a symbol, the inverse of the current sorting
894
- def inverse_sorting
895
- return :asc if current_sorting.nil?
896
- return :desc if current_sorting == :asc
897
- :asc
898
- end
899
-
900
- # Return the formated cell's value
901
- def format_cell_value(value, attribute = nil)
902
- unless (ret_value = format_cell_value_as_ask(value)).nil?
903
- return ret_value
904
- end
905
- format_cell_value_as_type(value, attribute)
906
- end
907
-
908
- # Format the value if option :as is set
909
- def format_cell_value_as_ask(value)
910
- return nil if !@options or @options.empty? or !@options.has_key?(:as)
911
- return case @options[:as]
912
- when :date then ::I18n.l(value.to_date, :format => @options[:format] || TableBuilder.i18n_default_format_date)
913
- when :time then ::I18n.l(value.to_datetime, :format => @options[:format] || TableBuilder.i18n_default_format_date)
914
- when :currency then number_to_currency(value)
915
- else nil
916
- end
917
- end
918
-
919
- # Format the value based on value's type
920
- def format_cell_value_as_type(value, attribute)
921
- if value.is_a?(Time) or value.is_a?(Date)
922
- return ::I18n.l(value, :format => @options[:format] || TableBuilder.i18n_default_format_date)
923
- elsif TableBuilder.currency_columns.include?(attribute)
924
- return number_to_currency(value)
925
- elsif value.is_a?(TrueClass)
926
- return TableBuilder.default_boolean.first
927
- elsif value.is_a?(FalseClass)
928
- return TableBuilder.default_boolean.second
929
- end
930
- value
931
- end
932
-
933
- end
934
643
  end
data/spec/db/schema.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  ActiveRecord::Schema.define(:version => 0) do
2
2
 
3
- create_table :users, :force => true do |t|
3
+ create_table :sorting_table_for_users, :force => true do |t|
4
4
 
5
5
  t.string :username
6
6
  t.string :firstname
@@ -1,4 +1,4 @@
1
- class User < ActiveRecord::Base
1
+ class SortingTableForUser < ActiveRecord::Base
2
2
  if ::SortingTableFor::Tools::rails3?
3
3
  scope :good_position, :conditions => 'position > 3'
4
4
  scope :set_limit, lambda { |limit| { :limit => limit } }
@@ -10,7 +10,7 @@ class User < ActiveRecord::Base
10
10
  end
11
11
 
12
12
  20.times do |n|
13
- User.create(
13
+ SortingTableForUser.create(
14
14
  :username => "my_usename_#{n}",
15
15
  :firstname => "my_firstname_#{n}",
16
16
  :lastname => "my_lastname_#{n}",
@@ -1,16 +1,19 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'spec_helper'
4
- require File.expand_path(File.dirname(__FILE__) + '/../fixtures/user')
4
+ require File.expand_path(File.dirname(__FILE__) + '/../fixtures/sorting_table_for_user')
5
5
 
6
6
  include SortingTableForSpecHelper
7
7
 
8
8
  describe SortingTableFor, :type => :helper do
9
9
 
10
+ before :all do
11
+ (SortingTableFor::Tools::rails3?) ? routes_rails3 : routes_rails2
12
+ end
13
+
10
14
  before :each do
11
- @users = User.all
12
- helper.stub!(:url_for).and_return('fake_link')
13
- helper.stub!(:params).and_return({ :controller => 'fakes', :action => 'index' })
15
+ @users = SortingTableForUser.all
16
+ helper.stub!(:params).and_return({ :controller => 'sorting_table_for_users', :action => 'index' })
14
17
  helper.output_buffer = ''
15
18
  end
16
19
 
@@ -42,7 +45,7 @@ describe SortingTableFor, :type => :helper do
42
45
  end
43
46
  end
44
47
 
45
- it "should no use i18n by default" do
48
+ it "should use i18n by default" do
46
49
  helper.sorting_table_for(@users) do |table|
47
50
  html = table.headers(:username)
48
51
  html.should have_comp_tag("th:nth-child(1)", :text => 'Usernames')