lib/table_helper/header.rb in table_helper-0.0.3 vs lib/table_helper/header.rb in table_helper-0.0.4
- old
+ new
@@ -1,15 +1,60 @@
require 'table_helper/row'
module PluginAWeek #:nodoc:
module TableHelper
+ # Provides a blank class that can be used to build the columns for a header
+ class HeaderBuilder < BlankSlate
+ reveal :respond_to?
+
+ attr_reader :header
+
+ # Creates a builder for the given header
+ def initialize(header)
+ @header = header
+ end
+
+ # Proxies all missed methods to the header
+ def method_missing(*args)
+ header.send(*args)
+ end
+
+ # Defines the accessor method for the given column name. For example, if
+ # a column with the name :title was defined, then the column would be able
+ # to be read and written like so:
+ #
+ # header.title #=> Accesses the title
+ # header.title "Page Title" #=> Creates a new column with "Page Title" as the content
+ def define_column(name)
+ method_name = name.to_s.gsub('-', '_')
+
+ klass = class << self; self; end
+ klass.class_eval do
+ define_method(method_name) do |*args|
+ header.row.builder.__send__(method_name, *args)
+ end
+ end unless klass.method_defined?(method_name)
+ end
+
+ # Removes the definition for the given cp;i,m
+ def undef_column(name)
+ klass = class << self; self; end
+ klass.class_eval do
+ remove_method(name.gsub('-', '_'))
+ end
+ end
+ end
+
# Represents the header of the table. In HTML, you can think of this as
# the <thead> tag of the table.
class Header < HtmlElement
# The actual header row
- attr_reader :row
+ attr_reader :row
+ # The proxy class used externally to build the actual columns
+ attr_reader :builder
+
# Whether or not the header should be hidden when the collection is
# empty. Default is true.
attr_accessor :hide_when_empty
# Creates a new header for a collection that contains objects of the
@@ -21,10 +66,11 @@
def initialize(collection, klass = nil)
super()
@collection = collection
@row = Row.new
+ @builder = HeaderBuilder.new(self)
@hide_when_empty = true
@customized = true
# If we know what class the objects in the collection are and we can
@@ -36,15 +82,27 @@
klass.column_names.each {|name| column(name)}
@customized = false
end
end
+ # The current columns in this header, in the order in which they will be built
+ def columns
+ row.cells
+ end
+
# Gets the names of all of the columns being displayed in the table
def column_names
row.cell_names
end
+ # Clears all of the current columns from the header
+ def clear
+ # Remove all of the shortcut methods
+ column_names.each {|name| builder.undef_column(name)}
+ row.clear
+ end
+
# Creates a new column with the specified caption. Columns must be
# defined in the order in which they will be rendered.
#
# The caption determines what will be displayed in each cell of the
# header (if the header is rendered). For example,
@@ -59,41 +117,20 @@
# specify html options like so:
#
# header.column :title, 'The Title', :class => 'pretty'
def column(name, *args)
# Clear the header row if this is being customized by the user
- if !@customized
+ unless @customized
@customized = true
-
- # Remove all of the shortcut methods
- column_names.each do |column|
- klass = class << self; self; end
- klass.class_eval do
- remove_method(column)
- end
- end
-
- @row.clear
+ clear
end
- column = @row.cell(name, *args)
+ column = row.cell(name, *args)
column.content_type = :header
column[:scope] ||= 'col'
- # Define a shortcut method to the cell
- name = name.to_s.gsub('-', '_')
- unless respond_to?(name)
- instance_eval <<-end_eval
- def #{name}(*args)
- if args.empty?
- @row.#{name}
- else
- @row.#{name}(*args)
- end
- end
- end_eval
- end
+ builder.define_column(name)
column
end
# Creates and returns the generated html for the header
@@ -103,23 +140,24 @@
content_tag(tag_name, content, html_options)
end
private
- def tag_name
- 'thead'
- end
-
- def content
- @row.html
- end
-
+ # Finds the class representing the objects within the collection
def class_for_collection(collection)
if collection.respond_to?(:proxy_reflection)
collection.proxy_reflection.klass
elsif !collection.empty?
collection.first.class
end
+ end
+
+ def tag_name
+ 'thead'
+ end
+
+ def content
+ @row.html
end
end
end
end