Class: Tabulatr

Inherits:
Object show all
Includes:
ActionView::Helpers::FormOptionsHelper, ActionView::Helpers::FormTagHelper, ActionView::Helpers::RecordTagHelper, ActionView::Helpers::TagHelper, ActionView::Helpers::TranslationHelper
Defined in:
lib/tabulatr/tabulatr.rb,
lib/tabulatr/version.rb,
lib/tabulatr/tabulatr/settings.rb,
lib/tabulatr/tabulatr/data_cell.rb,
lib/tabulatr/tabulatr/paginator.rb,
lib/tabulatr/tabulatr/filter_cell.rb,
lib/tabulatr/tabulatr/header_cell.rb,
lib/tabulatr/tabulatr/row_builder.rb,
lib/tabulatr/tabulatr/batch_actions.rb,
lib/tabulatr/tabulatr/check_controls.rb,
lib/generators/tabulatr/install_generator.rb

Overview

– Copyright © 2010-2011 Peter Horn, Provideal GmbH

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++

Defined Under Namespace

Modules: Finder, Formattr, Generators Classes: Adapter, Engine

Constant Summary collapse

VERSION =
"0.4.0"
TABLE_OPTIONS =

Hash keeping the defaults for the table options, may be overriden in the table_for call

WhinyHash.new({ # WhinyHash.new({
  :remote => false,                               # add data-remote="true" to form

  :form_class => 'tabulatr_form',                 # class of the overall form
  :table_class => 'tabulatr_table',               # class for the actual data table
  :sortable_class => 'sortable',                  # class for the header of a sortable column
  :sorting_asc_class => 'sorting-asc',            # class for the currently asc sorting column
  :sorting_desc_class => 'sorting-desc',          # class for the currently desc sorting column
  :page_left_class => 'page-left',                # class for the page left button
  :page_right_class => 'page-right',              # class for the page right button
  :page_no_class => 'page-no',                    # class for the page no <input>
  :reset_class => 'reset',                        # class for the reset button
  :control_div_class_before => 'table-controls',  # class of the upper div containing the paging and batch action controls
  :control_div_class_after => 'table-controls',   # class of the lower div containing the paging and batch action controls
  :paginator_div_class => 'paginator',            # class of the div containing the paging controls
  :batch_actions_div_class => 'batch-actions',    # class of the div containing the batch action controls
  :select_controls_div_class => 'check-controls',  # class of the div containing the check controls
  :submit_class => 'submit-table',                # class of submit button
  :pagesize_select_class => 'pagesize_select',    # class of the pagesize select element
  :select_all_class => 'select-btn',              # class of the select all button
  :select_none_class => 'select-btn',             # class of the select none button
  :select_visible_class => 'select-btn',          # class of the select visible button
  :unselect_visible_class => 'select-btn',        # class of the unselect visible button
  :select_filtered_class => 'select-btn',         # class of the select filtered button
  :unselect_filtered_class => 'select-btn',       # class of the unselect filteredbutton
  :info_text_class => 'info-text',                # class of the info text div

  :batch_actions_label => 'Batch Actions: ',      # Text to show in front of the batch action select
  :batch_actions_type => :select,                 # :select or :button depending on the kind of input you want
  :batch_actions_class => 'batch-action-inputs',  # class to apply on the batch action input elements
  :submit_label => 'Apply',                       # Text on the submit button
  :select_all_label => 'Select All',              # Text on the select all button
  :select_none_label => 'Select None',            # Text on the select none button
  :select_visible_label => 'Select visible',      # Text on the select visible button
  :unselect_visible_label => 'Unselect visible',  # Text on the unselect visible button
  :select_filtered_label => 'Select filtered',    # Text on the select filtered button
  :unselect_filtered_label => 'Unselect filtered',# Text on the unselect filtered button
  :reset_label => 'Reset',                        # Text on the reset button
  :info_text => "Showing %1$d, total %2$d, selected %3$d, matching %4$d",

  # which controls to be rendered above and below the tabel and in which order
  :before_table_controls => [:submit, :reset, :paginator, :batch_actions, :select_controls, :info_text],
  :after_table_controls => [],

  # whih selecting controls to render in which order
  :select_controls => [:select_all, :select_none, :select_visible, :unselect_visible,
                    :select_filtered, :unselect_filtered],

  :image_path_prefix => (Rails::version.to_f >= 3.1 ? 'tabulatr/' : '/images/tabulatr/'),
  :pager_left_button => 'pager_arrow_left.gif',
  :pager_left_button_inactive => 'pager_arrow_left_off.gif',
  :pager_right_button => 'pager_arrow_right.gif',
  :pager_right_button_inactive => 'pager_arrow_right_off.gif',
  :sort_up_button => 'sort_arrow_up.gif',
  :sort_up_button_inactive => 'sort_arrow_up_off.gif',
  :sort_down_button => 'sort_arrow_down.gif',
  :sort_down_button_inactive => 'sort_arrow_down_off.gif',

  :make_form => true,                # whether or not to wrap the whole table (incl. controls) in a form
  :table_html => false,              # a hash with html attributes for the table
  :row_html => false,                # a hash with html attributes for the normal trs
  :header_html => false,             # a hash with html attributes for the header trs
  :filter_html => false,             # a hash with html attributes for the filter trs
  :filter => true,                   # false for no filter row at all
  :paginate => true,                 # true to show paginator
  :sortable => true,                 # true to allow sorting (can be specified for every sortable column)
  :selectable => true,               # true to render "select all", "select none" and the like
  :reset => false,                   # true to render a reset button. Only reasonable in 'stateful' case
  :action => nil,                    # target action of the wrapping form if applicable
  :batch_actions => false,           # :name => value hash of batch action stuff
  :translate => false,               # call t() for all 'labels' and stuff, possible values are true/:translate or :localize
  :row_classes => ['odd', 'even'],   # class for the trs
  :footer_content => false           # if given, add a <%= content_for <footer_content> %> before the </table>
})
TABLE_FORM_OPTIONS =

these settings are considered constant for the whole application, can not be overridden on a per-table basis. That’s necessary to allow find_for_table to work properly

WhinyHash.new({
  :batch_action_name => 'batch_action',       # name of the batch action param
  :sort_by_key => 'sort_by_key',              # name of key which to search, format is 'id asc'
  :pagination_postfix => '_pagination',       # name of the param w/ the pagination infos
  :filter_postfix => '_filter',               # postfix for name of the filter in the params :hash => xxx_filter
  :sort_postfix => '_sort',                   # postfix for name of the filter in the params :hash => xxx_filter
  :checked_postfix => '_checked',             # postfix for name of the checked in the params :hash => xxx_filter
  :associations_filter => '__association',    # name of the associations in the filter hash
  :method => 'post',                          # http method for that form if applicable
  :batch_postfix => '_batch',                 # postfix for name of the batch action select
  :state_session_postfix => '_table_state',   # postfix for the state hash in the sessions
  :reset_state_postfix => '_reset_state',     # postfix for the name of the input to reset state
  :checked_separator => ','                   # symbol to separate the checked ids
})
PAGINATE_OPTIONS =

these settings are considered constant for the whole application, can not be overridden on a per-table basis. That’s necessary to allow find_for_table to work properly

ActiveSupport::HashWithIndifferentAccess.new({
  :page => 1,
  :pagesize => 10,
  :pagesizes => [10, 20, 50]
})
COLUMN_OPTIONS =

Hash keeping the defaults for the column options

ActiveSupport::HashWithIndifferentAccess.new({
  :header => false,                   # a string to write into the header cell
  :width => false,                    # the width of the cell
  :align => false,                    # horizontal alignment
  :valign => false,                   # vertical alignment
  :wrap => true,                      # wraps
  :type => :string,                   # :integer, :date
  :td_html => false,                  # a hash with html attributes for the cells
  :th_html => false,                  # a hash with html attributes for the header cell
  :filter_html => false,              # a hash with html attributes for the filter cell
  :filter => true,                    # false for no filter field,
                                   # container for options_for_select
                                   # String from options_from_collection_for_select or the like
                                   # :range for range spec
                                   # :checkbox for a 0/1 valued checkbox
  :checkbox_value => '1',             # value if checkbox is checked
  :checkbox_label => '',              # text behind the checkbox
  :filter_width => '97%',             # width of the filter <input>
  :range_filter_symbol => '&ndash;',  # put between the <inputs> of the range filter
  :format => false,                   # a sprintf-string or a proc to do special formatting
  :method => false,                   # if you want to get the column by a different method than its name
  :link => false,                     # proc or symbol to make the content a link
  :join_symbol => ', ',               # symbol used to join the elements of 'many' associations
  :map => true,                       # whether to map the call on individual records (true) or call on the list (false)
  :sort_by => false,                  # sort the elements of an association
  :sortable => true                   # if set, sorting-stuff is added to the header cell
})
FINDER_OPTIONS =

defaults for the find_for_table

WhinyHash.new({
  :default_order => false,
  :default_pagesize => false,
  :precondition => false,
  :store_data => false,
  :stateful => false,
  :name_mapping => nil
})
SQL_OPTIONS =

Stupid hack

WhinyHash.new({
  :like => nil
})

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(records, view = nil, toptions = {}) ⇒ Tabulatr

Constructor of Tabulatr

Parameters:

records

the ‘row’ data of the table

view

the current instance of ActionView

opts

a hash of options specific for this table



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/tabulatr/tabulatr.rb', line 54

def initialize(records, view=nil, toptions={})
  @records = records
  @view = view
  @table_options = TABLE_OPTIONS.merge(toptions)
  @table_form_options = TABLE_FORM_OPTIONS
  @val = []
  @record = nil
  @row_mode = false
  if @records.respond_to? :__classinfo
    @klaz, @classname, @id, @id_type = @records.__classinfo
    @pagination = @records.__pagination
    @filters = @records.__filters
    @sorting = @records.__sorting
    @checked = @records.__checked
    @store_data = @records.__store_data
    @stateful = @records.__stateful
    @should_translate = @table_options[:translate]
  else
    @classname, @id, @id_type = nil
    @klaz = @records.first.class
    @pagination = { :page => 1, :pagesize => records.count, :count => records.count, :pages => 1,
      :pagesizes => records.count, :total => records.count }
    @table_options.merge!(
      :paginate => false,                 # true to show paginator
      :sortable => false,                 # true to allow sorting (can be specified for every sortable column)
      :selectable => false,               # true to render "select all", "select none" and the like
      :info_text => nil,
      :filter => false
    )
    @store_data = []
    @should_translate = @table_options[:translate]
  end
end

Class Method Details

.column_options(n = nil) ⇒ Object



181
182
183
184
# File 'lib/tabulatr/tabulatr/settings.rb', line 181

def self.column_options(n=nil)
  COLUMN_OPTIONS.merge!(n) if n
  COLUMN_OPTIONS
end

.finder_options(n = nil) ⇒ Object



176
177
178
179
# File 'lib/tabulatr/tabulatr/settings.rb', line 176

def self.finder_options(n=nil)
  FINDER_OPTIONS.merge!(n) if n
  FINDER_OPTIONS
end

.paginate_options(n = nil) ⇒ Object



191
192
193
194
# File 'lib/tabulatr/tabulatr/settings.rb', line 191

def self.paginate_options(n=nil)
  PAGINATE_OPTIONS.merge!(n) if n
  PAGINATE_OPTIONS
end

.sql_options(n = nil) ⇒ Object



206
207
208
209
# File 'lib/tabulatr/tabulatr/settings.rb', line 206

def self.sql_options(n=nil)
  SQL_OPTIONS.merge!(n) if n
  SQL_OPTIONS
end

.table_design_options(n = nil) ⇒ Object



201
202
203
# File 'lib/tabulatr/tabulatr/settings.rb', line 201

def self.table_design_options(n=nil)
  raise("table_design_options stopped existing. Use table_options instead.")
end

.table_form_options(n = nil) ⇒ Object



196
197
198
199
# File 'lib/tabulatr/tabulatr/settings.rb', line 196

def self.table_form_options(n=nil)
  TABLE_FORM_OPTIONS.merge!(n) if n
  TABLE_FORM_OPTIONS
end

.table_options(n = nil) ⇒ Object



186
187
188
189
# File 'lib/tabulatr/tabulatr/settings.rb', line 186

def self.table_options(n=nil)
  TABLE_OPTIONS.merge!(n) if n
  TABLE_OPTIONS
end

Instance Method Details

#action(opts = {}, &block) ⇒ Object



65
66
67
68
69
70
71
72
73
# File 'lib/tabulatr/tabulatr/row_builder.rb', line 65

def action(opts={}, &block)
  #puts "column: '#{name}'"
  case @row_mode
  when :data   then data_action(opts, &block)
  when :header then header_action(opts, &block)
  when :filter then filter_action(opts, &block)
  else raise "Wrong row mode '#{@row_mode}'"
  end # case
end

#association(relation, name, opts = {}, &block) ⇒ Object

called inside the build_table block, branches into data, header, or filter building methods depending on the current mode



43
44
45
46
47
48
49
50
51
# File 'lib/tabulatr/tabulatr/row_builder.rb', line 43

def association(relation, name, opts={}, &block)
  #puts "assoc: '#{relation}.#{name}'"
  case @row_mode
  when :data   then data_association(relation, name, opts, &block)
  when :header then header_association(relation, name, opts, &block)
  when :filter then filter_association(relation, name, opts, &block)
  else raise "Wrong row mode '#{@row_mode}'"
  end # case
end

#build_table(&block) ⇒ Object

the actual table definition method. It takes an Array of records, a hash of options and a block with the actual column calls.

The following options are evaluated here:

:table_html

a hash with html-attributes added to the <table> created

:header_html

a hash with html-attributes added to the <tr> created for the header row

:filter_html

a hash with html-attributes added to the <tr> created for the filter row

:row_html

a hash with html-attributes added to the <tr>s created for the data rows

:filter

if set to false, no filter row is output



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/tabulatr/tabulatr.rb', line 100

def build_table(&block)
  @val = []
  make_tag(@table_options[:make_form] ? :form : nil,
      :method => :get,
      :class => @table_options[:form_class],
      'data-remote' => (@table_options[:remote] ? "true" : nil)) do
    # TODO: make_tag(:input, :type => 'submit', :style => 'display:inline; width:1px; height:1px', :value => '__submit')
    make_tag(:div,  :class => @table_options[:control_div_class_before]) do
      @table_options[:before_table_controls].each do |element|
        render_element(element)
      end
    end if @table_options[:before_table_controls].present? # </div>

    @store_data.each do |k,v|
      make_tag(:input, :type => :hidden, :name => k, :value => h(v))
    end

    render_element(:table, &block)

    make_tag(:div,  :class => @table_options[:control_div_class_after]) do
      @table_options[:after_table_controls].each do |element|
        render_element(element)
      end
    end if @table_options[:after_table_controls].present? # </div>

  end # </form>
  @val.join("").html_safe
end

#checkbox(opts = {}, &block) ⇒ Object

called inside the build_table block, branches into data, header, or filter building methods depending on the current mode



55
56
57
58
59
60
61
62
63
# File 'lib/tabulatr/tabulatr/row_builder.rb', line 55

def checkbox(opts={}, &block)
  #puts "column: '#{name}'"
  case @row_mode
  when :data   then data_checkbox(opts, &block)
  when :header then header_checkbox(opts, &block)
  when :filter then filter_checkbox(opts, &block)
  else raise "Wrong row mode '#{@row_mode}'"
  end # case
end

#column(name, opts = {}, &block) ⇒ Object

called inside the build_table block, branches into data, header, or filter building methods depending on the current mode



31
32
33
34
35
36
37
38
39
# File 'lib/tabulatr/tabulatr/row_builder.rb', line 31

def column(name, opts={}, &block)
  #puts "column: '#{name}'"
  case @row_mode
  when :data   then data_column(name, opts, &block)
  when :header then header_column(name, opts, &block)
  when :filter then filter_column(name, opts, &block)
  else raise "Wrong row mode '#{@row_mode}'"
  end # case
end

#data_action(opts = {}, &block) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
# File 'lib/tabulatr/tabulatr/data_cell.rb', line 120

def data_action(opts={}, &block)
  raise "Not in data mode!" if @row_mode != :data
  opts = normalize_column_options opts
  make_tag(:td, opts[:td_html]) do
    if block_given?
      concat(yield(@record))
    else
      raise "Always give a block ino action columns"
    end # block_given?
  end # </td>
end

#data_association(relation, name, opts = {}, &block) ⇒ Object

the method used to actually define the data cells of the columns, taking the name of the attribute and a hash of options.

The following options are evaluated here:

:td_html

a hash with html-attributes added to the <ts>s created

:method

the actual method invoked on the record to retrieve the value for the column, or false if name is to be used.

:format

either a String by which the value is sprinfed, a proc/lambda to which the value is passed or false if no specific formatting is desired.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/tabulatr/tabulatr/data_cell.rb', line 74

def data_association(relation, name, opts={}, &block)
  raise "Not in data mode!" if @row_mode != :data
  opts = normalize_column_options opts
  if block_given?
    return yield(@record)
  end
  assoc = @record.class.reflect_on_association(relation)
  make_tag(:td, opts[:td_html]) do
    format = opts[:format]
    ass = @record.send(relation.to_sym)
    if opts[:sort_by]
      # TODO: SORTING specified by opts[:sort_by]
    end
    concat(if (ass.is_a?(Array) || ass.respond_to?(:to_ary)) && opts[:map]
      ass.map do |r|
        val = h(r.send(opts[:method] || name))
        if format.is_a?(Proc) then format.call(val)
        elsif format.is_a?(String) then h(format % val)
        elsif format.is_a?(Symbol) then Tabulatr::Formattr.format(format, val)
        else h(val.to_s)
        end
      end.join(opts[:join_symbol])
    else
      return '' unless ass
      #puts ass.to_s
      val = h(ass.send(opts[:method] || name))
      val = if format.is_a?(Proc) then format.call(val)
      elsif format.is_a?(String) then h(format % val)
      elsif format.is_a?(Symbol) then Tabulatr::Formattr.format(format, val)
      else h(val.to_s)
      end
    end)
  end # </td>
end

#data_checkbox(opts = {}, &block) ⇒ Object



109
110
111
112
113
114
115
116
117
118
# File 'lib/tabulatr/tabulatr/data_cell.rb', line 109

def data_checkbox(opts={}, &block)
  raise "Whatever that's for!" if block_given?
  iname = "#{@classname}#{@table_form_options[:checked_postfix]}[current_page][]"
  make_tag(:td, opts[:td_html]) do
    checked = @checked[:selected].member?(@record.send(@id)) ? :checked : nil
    make_tag(:input, :type => 'checkbox', :name => iname,
      :id => "#{@classname}#{@table_form_options[:checked_postfix]}_#{@record.send(@id).to_s}",
      :value => @record.send(@id), :checked => checked)
  end
end

#data_column(name, opts = {}, &block) ⇒ Object

the method used to actually define the data cells of the columns, taking the name of the attribute and a hash of options.

The following options are evaluated here:

:td_html

a hash with html-attributes added to the <ts>s created

:method

the actual method invoked on the record to retrieve the value for the column, or false if name is to be used.

:fromat

either a String by which the value is sprinfed, a proc/lambda to which the value is passed or false if no specific formatting is desired.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/tabulatr/tabulatr/data_cell.rb', line 36

def data_column(name, opts={}, &block)
  raise "Not in data mode!" if @row_mode != :data
  opts = normalize_column_options opts
  make_tag(:td, opts[:td_html]) do
    href = if opts[:link].class == Symbol || opts[:link].class == String
        @view.send(opts[:link], @record)
      elsif opts[:link].respond_to?(:call)
        opts[:link].call(@record)
      else
        nil
      end
    make_tag((href ? :a : nil), :href => href) do
      if block_given?
        concat(yield(@record))
      else
        val = @record.send(opts[:method] || name)
        format = opts[:format]
        concat(
          if format.is_a?(Proc) then format.call(val)
          elsif format.is_a?(String) then h(format % val)
          elsif format.is_a?(Symbol) then Tabulatr::Formattr.format(format, val)
          else h(val.to_s)
        end)
      end # block_given?
    end # </a>
  end # </td>
end

#filter_action(opts = {}, &block) ⇒ Object



84
85
86
87
88
89
90
# File 'lib/tabulatr/tabulatr/filter_cell.rb', line 84

def filter_action(opts={}, &block)
  raise "Not in filter mode!" if @row_mode != :filter
  opts = normalize_column_options(opts)
  make_tag(:td, opts[:filter_html]) do
    concat(t(opts[:filter])) unless [true, false, nil].member?(opts[:filter])
  end # </td>
end

#filter_association(relation, name, opts = {}, &block) ⇒ Object

the method used to actually define the filters of the columns, taking the name of the attribute and a hash of options.

The following options are evaluated here:

:filter_html

a hash with html-attributes added to the <ts>s created

:filter

may take different values:

false

no filter is output for this column

a Hash

the keys of the hash are used to define a select where the values are the value of the options.

an Array

the elements of that array are used to define a select

a subclass of ActiveRecord::Base

a select is created with all instances



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/tabulatr/tabulatr/filter_cell.rb', line 63

def filter_association(relation, name, opts={}, &block)
  raise "Not in filter mode!" if @row_mode != :filter
  opts = normalize_column_options(opts)
  filters = (@filters[@table_form_options[:associations_filter]] || {})
  value = filters["#{relation}.#{name}"]
  make_tag(:td, opts[:filter_html]) do
    of = opts[:filter]
    iname = "#{@classname}#{@table_form_options[:filter_postfix]}[#{@table_form_options[:associations_filter]}][#{relation}.#{name}]"
    filter_tag(of, iname, value, opts)
  end # </td>
end

#filter_checkbox(opts = {}, &block) ⇒ Object



75
76
77
78
79
80
81
82
# File 'lib/tabulatr/tabulatr/filter_cell.rb', line 75

def filter_checkbox(opts={}, &block)
  raise "Whatever that's for!" if block_given?
  make_tag(:td, opts[:filter_html]) do
    iname = "#{@classname}#{@table_form_options[:checked_postfix]}"
    make_tag(:input, :type => 'hidden', :name => "#{iname}[checked_ids]", :value => @checked[:checked_ids])
    make_tag(:input, :type => 'hidden', :name => "#{iname}[visible]", :value => @checked[:visible])
  end
end

#filter_column(name, opts = {}, &block) ⇒ Object

the method used to actually define the filters of the columns, taking the name of the attribute and a hash of options.

The following options are evaluated here:

:filter_html

a hash with html-attributes added to the <ts>s created

:filter

may take different values:

false

no filter is output for this column

a container

the keys of the hash are used to define a select

where the values are the <tt>value</tt> of the <tt>options</tt>.
an Array

the elements of that array are used to define a select

a String

a select is created with that String as options you can use ActionView#collection_select and the like



39
40
41
42
43
44
45
46
47
48
# File 'lib/tabulatr/tabulatr/filter_cell.rb', line 39

def filter_column(name, opts={}, &block)
  raise "Not in filter mode!" if @row_mode != :filter
  opts = normalize_column_options(opts)
  value = @filters[name]
  make_tag(:td, opts[:filter_html]) do
    of = opts[:filter]
    iname = "#{@classname}#{@table_form_options[:filter_postfix]}[#{name}]"
    filter_tag(of, iname, value, opts)
  end # </td>
end

#header_action(opts = {}, &block) ⇒ Object



85
86
87
88
89
90
# File 'lib/tabulatr/tabulatr/header_cell.rb', line 85

def header_action(opts={}, &block)
  opts = normalize_column_options opts
  make_tag(:th, opts[:th_html]) do
    concat(t(opts[:header] || ""), :escape_html)
  end
end

#header_association(relation, name, opts = {}, &block) ⇒ Object

the method used to actually define the headers of the columns, taking the name of the attribute and a hash of options.

The following options are evaluated here:

:th_html

a hash with html-attributes added to the <th>s created

:header

if present, the value will be output in the header cell, otherwise, the capitalized name is used



67
68
69
70
71
72
73
74
75
76
# File 'lib/tabulatr/tabulatr/header_cell.rb', line 67

def header_association(relation, name, opts={}, &block)
  raise "Not in header mode!" if @row_mode != :header
  opts = normalize_column_options opts
  if opts[:sortable] and @table_options[:sortable]
    # change classes accordingly
  end
  make_tag(:th, opts[:th_html]) do
    concat(t(opts[:header] || "#{relation.to_s.humanize.titlecase} #{name.to_s.humanize.titlecase}"), :escape_html)
  end # </th>
end

#header_checkbox(opts = {}, &block) ⇒ Object



78
79
80
81
82
83
# File 'lib/tabulatr/tabulatr/header_cell.rb', line 78

def header_checkbox(opts={}, &block)
  raise "Whatever that's for!" if block_given?
  make_tag(:th, opts[:th_html]) do
    concat(t(opts[:header] || ""), :escape_html)
  end
end

#header_column(name, opts = {}, &block) ⇒ Object

the method used to actually define the headers of the columns, taking the name of the attribute and a hash of options.

The following options are evaluated here:

:th_html

a hash with html-attributes added to the <th>s created

:header

if present, the value will be output in the header cell, otherwise, the capitalized name is used



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/tabulatr/tabulatr/header_cell.rb', line 34

def header_column(name, opts={}, &block)
  raise "Not in header mode!" if @row_mode != :header
  sortparam = "#{@classname}#{@table_form_options[:sort_postfix]}"
  bid = "#{@classname}#{@table_form_options[:sort_postfix]}"
  opts = normalize_column_options opts
  make_tag(:th, opts[:th_html]) do
    concat(t(opts[:header] || @klaz.human_attribute_name(name).titlecase), :escape_html)
    if opts[:sortable] and @table_options[:sortable]
      if @sorting and @sorting[:by].to_s == name.to_s
        pname = "#{sortparam}[_resort][#{name}][#{@sorting[:direction] == 'asc' ? 'desc' : 'asc'}]"
        bid = "#{bid}_#{name}_#{@sorting[:direction] == 'asc' ? 'desc' : 'asc'}"
        psrc = @table_options[@sorting[:direction] == 'desc' ?
          :sort_down_button : :sort_up_button]
        make_tag(:input, :type => :hidden,
          :name => "#{sortparam}[#{name}][#{@sorting[:direction]}]",
          :value => "#{@sorting[:direction]}")
      else
        pname = "#{sortparam}[_resort][#{name}][desc]"
        bid = "#{bid}_#{name}_desc"
        psrc = @table_options[:sort_down_button_inactive]
      end
      make_image_button(psrc, :id => bid, :name => pname)
    end
  end # </th>
end

#render_batch_actionsObject

render the select tag or the buttons for batch actions



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/tabulatr/tabulatr/batch_actions.rb', line 27

def render_batch_actions
  make_tag(:div, :class => @table_options[:batch_actions_div_class]) do
    concat(t(@table_options[:batch_actions_label])) if @table_options[:batch_actions_label]
    iname = "#{@classname}#{TABLE_FORM_OPTIONS[:batch_postfix]}"
    case @table_options[:batch_actions_type]
    when :select
      make_tag(:select, :name => iname, :class => @table_options[:batch_actions_class]) do
        concat("<option></option>")
        @table_options[:batch_actions].each do |n,v|
          make_tag(:option, :value => n) do
            concat(v)
          end # </option>
        end # each
      end # </select>
    when :buttons
      @table_options[:batch_actions].each do |n,v|
        make_tag(:input, :type => 'submit', :value => v, 
          :name => "#{iname}[#{n}]",
          :class => @table_options[:batch_actions_class])
      end # each
    else raise "Use either :select or :buttons for :batch_actions_type"
    end # case
  end # </div>
end

#render_element(element, &block) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/tabulatr/tabulatr.rb', line 129

def render_element(element, &block)
  case element
  when :paginator then render_paginator if @table_options[:paginate]
  when :hidden_submit then "IMPLEMENT ME!"
  when :submit then   make_tag(:input, :type => 'submit',
      :class => @table_options[:submit_class],
      :value => t(@table_options[:submit_label])) if @records.respond_to?(:__classinfo)
  when :reset then   make_tag(:input, :type => 'submit',
      :class => @table_options[:reset_class],
      :name => "#{@classname}#{TABLE_FORM_OPTIONS[:reset_state_postfix]}",
      :value => t(@table_options[:reset_label])) if @stateful
  when :batch_actions then render_batch_actions if @table_options[:batch_actions]
  when :select_controls then render_select_controls if @table_options[:selectable]
  when :info_text
    make_tag(:div, :class => @table_options[:info_text_class]) do
      concat(format(t(@table_options[:info_text]),
        @records.count, @pagination[:total], @checked[:selected].length, @pagination[:count]))
    end if @table_options[:info_text]
  when :table then render_table &block
  else
    if element.is_a?(String)
      concat(element)
    else
      raise "unknown element '#{element}'"
    end
  end
end

#render_paginatorObject

render the paginator controls, inputs etc.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/tabulatr/tabulatr/paginator.rb', line 27

def render_paginator
  # get the current pagination state
  pagination_name = "#{@classname}#{TABLE_FORM_OPTIONS[:pagination_postfix]}"
  pparams = @records.__pagination
  page = pparams[:page].to_i
  pages = pparams[:pages].to_i
  pagesize = pparams[:pagesize].to_i
  pagesizes = pparams[:pagesizes].map &:to_i
  # render the 'wrapping' div
  make_tag(:div, :class => @table_options[:paginator_div_class]) do
    # << Page Left
    make_image_button(@table_options[page > 1 ? :pager_left_button : :pager_left_button_inactive],
      :class => @table_options[:page_left_class],
      :id => "#{pagination_name}_page_left",
      :name => "#{pagination_name}[page_left]",
      :inactive => (page <= 1))
    # current page number
    concat(make_tag(:input,
      :type => :hidden,
      :name => "#{pagination_name}[current_page]",
      :value => page))
    concat(make_tag(:input,
      :type => :text,
      :size => pages.to_s.length,
      :name => "#{pagination_name}[page]",
      :value => page))
    concat("/#{pages}")
    # >> Page Right
    make_image_button(@table_options[page < pages ? :pager_right_button : :pager_right_button_inactive],
      :class => @table_options[:page_right_class],
      :id => "#{pagination_name}_page_right",
      :name => "#{pagination_name}[page_right]",
      :inactive => (page >= pages))
    if pagesizes.length > 1
      make_tag(:select, :name => "#{pagination_name}[pagesize]", :class => @table_options[:pagesize_select_class]) do
        pagesizes.each do |n|
          make_tag(:option, (n.to_i==pagesize ? {:selected  => :selected} : {}).merge(:value => n)) do
            concat(n.to_s)
          end # </option>
        end # each
      end # </select>
    else # just one pagesize
      concat(make_tag(:input,
        :type => :hidden,
        :name => "#{pagination_name}[pagesize]",
        :value => pagesizes.first))
    end
  end # </div>
end

#render_select_controlsObject

render the buttons to (de-)select multiple rows



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/tabulatr/tabulatr/check_controls.rb', line 27

def render_select_controls
  make_tag(:div, :class => @table_options[:select_controls_div_class]) do
    iname = "#{@classname}#{TABLE_FORM_OPTIONS[:checked_postfix]}"
    @table_options[:select_controls].each do |name|
      raise "Invalid check control '#{name}' requested." unless [:select_all,
        :select_none, :select_visible, :unselect_visible,
        :select_filtered, :unselect_filtered].member?(name)
      topts = {
        :type => 'submit',
        :value => t(@table_options["#{name}_label"]),
        :name => "#{iname}[#{name}]" }
      topts[:class] = @table_options["#{name}_class"] if @table_options["#{name}_class"]
      make_tag(:input, topts)
    end
  end # </div>
end

#render_table(&block) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/tabulatr/tabulatr.rb', line 157

def render_table(&block)
  to = @table_options[:table_html]
  to = (to || {}).merge(:class => @table_options[:table_class]) if @table_options[:table_class]
  make_tag(:table, to) do
    make_tag(:thead) do
      render_table_header(&block)
      render_table_filters(&block) if @table_options[:filter]
    end # </thead>
    make_tag(:tbody) do
      render_table_rows(&block)
    end # </tbody>
    content_for(@table_options[:footer_content]) if @table_options[:footer_content]
  end # </table>
end

#sql_options(n = nil) ⇒ Object



210
# File 'lib/tabulatr/tabulatr/settings.rb', line 210

def sql_options(n=nil) self.class.sql_options(n) end

#table_design_options(n = nil) ⇒ Object



204
# File 'lib/tabulatr/tabulatr/settings.rb', line 204

def table_design_options(n=nil) self.class.table_design_options(n) end