table_helper 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,58 +3,62 @@ require 'table_helper/header'
3
3
  require 'table_helper/body'
4
4
  require 'table_helper/footer'
5
5
 
6
- module PluginAWeek #:nodoc:
7
- module TableHelper
8
- # Represents a table that is displaying data for multiple objects within
9
- # a collection.
10
- class CollectionTable < HtmlElement
11
- def initialize(collection, options = {}, html_options = {}) #:nodoc:
12
- super(html_options)
13
-
14
- options.assert_valid_keys(
15
- :class,
16
- :footer,
17
- :header
18
- )
19
- @options = options.reverse_merge(
20
- :header => true,
21
- :footer => false
22
- )
23
-
24
- @html_options.reverse_merge!(
25
- :cellspacing => '0',
26
- :cellpadding => '0'
27
- )
28
-
29
- @header = Header.new(collection, options[:class])
30
- @body = Body.new(collection, @header)
31
- @footer = Footer.new(collection)
6
+ module TableHelper
7
+ # Represents a table that displays data for multiple objects within a
8
+ # collection.
9
+ class CollectionTable < HtmlElement
10
+ # Creates a new table based on the objects within the given collection.
11
+ #
12
+ # Configuration options:
13
+ # * +class+ - The actual class of the objects contained within the collection. This is used to help build the header columns.
14
+ # * +header+ - Whether or not to display a header. Default is true.
15
+ # * +footer+ - Whether or not to display a footer. Default is false.
16
+ def initialize(collection, options = {}, html_options = {}) #:nodoc:
17
+ super(html_options)
18
+
19
+ options.assert_valid_keys(
20
+ :class,
21
+ :footer,
22
+ :header
23
+ )
24
+ @options = options.reverse_merge(
25
+ :header => true,
26
+ :footer => false
27
+ )
28
+
29
+ @html_options.reverse_merge!(
30
+ :cellspacing => '0',
31
+ :cellpadding => '0'
32
+ )
33
+
34
+ @header = Header.new(collection, options[:class])
35
+ @body = Body.new(collection, @header)
36
+ @footer = Footer.new(collection)
37
+ end
38
+
39
+ # Builds the table by rendering a header (if enabled), body, and footer (if enabled).
40
+ def build(&block)
41
+ @body.build # Build with the defaults
42
+
43
+ elements = []
44
+ elements << @header.builder if @options[:header]
45
+ elements << @body
46
+ elements << @footer if @options[:footer]
47
+
48
+ yield *elements if block_given?
49
+
50
+ @content = ''
51
+ elements.each {|element| @content << element.html}
52
+ @content
53
+ end
54
+
55
+ private
56
+ def tag_name
57
+ 'table'
32
58
  end
33
59
 
34
- # Builds the table by rendering a header, body, and footer.
35
- def build(&block)
36
- @body.build # Build with the defaults
37
-
38
- elements = []
39
- elements << @header.builder if @options[:header]
40
- elements << @body
41
- elements << @footer if @options[:footer]
42
-
43
- yield *elements if block_given?
44
-
45
- @content = ''
46
- elements.each {|element| @content << element.html}
60
+ def content
47
61
  @content
48
62
  end
49
-
50
- private
51
- def tag_name
52
- 'table'
53
- end
54
-
55
- def content
56
- @content
57
- end
58
- end
59
63
  end
60
64
  end
@@ -1,47 +1,45 @@
1
1
  require 'table_helper/row'
2
2
 
3
- module PluginAWeek #:nodoc:
4
- module TableHelper
5
- # Represents the header of the table. In HTML, you can think of this as
6
- # the tfoot tag of the table.
7
- class Footer < HtmlElement
8
- # The actual footer row
9
- attr_reader :row
3
+ module TableHelper
4
+ # Represents the header of the table. In HTML, you can think of this as
5
+ # the <tfoot> tag of the table.
6
+ class Footer < HtmlElement
7
+ # The actual footer row
8
+ attr_reader :row
9
+
10
+ delegate :cell,
11
+ :to => :row
12
+
13
+ # Whether or not the footer should be hidden when the collection is
14
+ # empty. Default is true.
15
+ attr_accessor :hide_when_empty
16
+
17
+ def initialize(collection) #:nodoc:
18
+ super()
10
19
 
11
- delegate :cell,
12
- :to => :row
13
-
14
- # Whether or not the footer should be hidden when the collection is
15
- # empty. Default is true.
16
- attr_accessor :hide_when_empty
20
+ @collection = collection
21
+ @row = Row.new
22
+ @hide_when_empty = true
23
+ end
24
+
25
+ def html #:nodoc:
26
+ html_options = @html_options.dup
27
+ html_options[:style] = 'display: none;' if @collection.empty? && hide_when_empty
17
28
 
18
- def initialize(collection) #:nodoc:
19
- super()
20
-
21
- @collection = collection
22
- @row = Row.new
23
- @hide_when_empty = true
29
+ content_tag(tag_name, content, html_options)
30
+ end
31
+
32
+ private
33
+ def tag_name
34
+ 'tfoot'
24
35
  end
25
36
 
26
- def html #:nodoc:
27
- html_options = @html_options.dup
28
- html_options[:style] = 'display: none;' if @collection.empty? && hide_when_empty
29
-
30
- content_tag(tag_name, content, html_options)
37
+ # Generates the html for the footer. The footer generally consists of a
38
+ # summary of the data in the body. This row will be wrapped inside of
39
+ # a tfoot tag. If the collection is empty and hide_when_empty was set
40
+ # to true, then the footer will be hidden.
41
+ def content
42
+ @row.html
31
43
  end
32
-
33
- private
34
- def tag_name
35
- 'tfoot'
36
- end
37
-
38
- # Generates the html for the footer. The footer generally consists of a
39
- # summary of the data in the body. This row will be wrapped inside of
40
- # a tfoot tag. If the collection is empty and hide_when_empty was set
41
- # to true, then the footer will be hidden.
42
- def content
43
- @row.html
44
- end
45
- end
46
44
  end
47
45
  end
@@ -1,163 +1,161 @@
1
1
  require 'table_helper/row'
2
2
 
3
- module PluginAWeek #:nodoc:
4
- module TableHelper
5
- # Provides a blank class that can be used to build the columns for a header
6
- class HeaderBuilder < BlankSlate
7
- reveal :respond_to?
8
-
9
- attr_reader :header
10
-
11
- # Creates a builder for the given header
12
- def initialize(header)
13
- @header = header
14
- end
15
-
16
- # Proxies all missed methods to the header
17
- def method_missing(*args)
18
- header.send(*args)
19
- end
20
-
21
- # Defines the accessor method for the given column name. For example, if
22
- # a column with the name :title was defined, then the column would be able
23
- # to be read and written like so:
24
- #
25
- # header.title #=> Accesses the title
26
- # header.title "Page Title" #=> Creates a new column with "Page Title" as the content
27
- def define_column(name)
28
- method_name = name.to_s.gsub('-', '_')
29
-
30
- klass = class << self; self; end
31
- klass.class_eval do
32
- define_method(method_name) do |*args|
33
- header.row.builder.__send__(method_name, *args)
34
- end
35
- end unless klass.method_defined?(method_name)
36
- end
3
+ module TableHelper
4
+ # Provides a blank class that can be used to build the columns for a header
5
+ class HeaderBuilder < BlankSlate #:nodoc:
6
+ reveal :respond_to?
7
+
8
+ attr_reader :header
9
+
10
+ # Creates a builder for the given header
11
+ def initialize(header)
12
+ @header = header
13
+ end
14
+
15
+ # Proxies all missed methods to the header
16
+ def method_missing(*args)
17
+ header.send(*args)
18
+ end
19
+
20
+ # Defines the accessor method for the given column name. For example, if
21
+ # a column with the name :title was defined, then the column would be able
22
+ # to be read and written like so:
23
+ #
24
+ # header.title #=> Accesses the title
25
+ # header.title "Page Title" #=> Creates a new column with "Page Title" as the content
26
+ def define_column(name)
27
+ method_name = name.to_s.gsub('-', '_')
37
28
 
38
- # Removes the definition for the given cp;i,m
39
- def undef_column(name)
40
- klass = class << self; self; end
41
- klass.class_eval do
42
- remove_method(name.gsub('-', '_'))
29
+ klass = class << self; self; end
30
+ klass.class_eval do
31
+ define_method(method_name) do |*args|
32
+ header.row.builder.__send__(method_name, *args)
43
33
  end
34
+ end unless klass.method_defined?(method_name)
35
+ end
36
+
37
+ # Removes the definition for the given cp;i,m
38
+ def undef_column(name)
39
+ klass = class << self; self; end
40
+ klass.class_eval do
41
+ remove_method(name.gsub('-', '_'))
44
42
  end
45
43
  end
44
+ end
45
+
46
+ # Represents the header of the table. In HTML, you can think of this as
47
+ # the <thead> tag of the table.
48
+ class Header < HtmlElement
49
+ # The actual header row
50
+ attr_reader :row
51
+
52
+ # The proxy class used externally to build the actual columns
53
+ attr_reader :builder
54
+
55
+ # Whether or not the header should be hidden when the collection is
56
+ # empty. Default is true.
57
+ attr_accessor :hide_when_empty
46
58
 
47
- # Represents the header of the table. In HTML, you can think of this as
48
- # the <thead> tag of the table.
49
- class Header < HtmlElement
50
- # The actual header row
51
- attr_reader :row
59
+ # Creates a new header for a collection that contains objects of the
60
+ # given class.
61
+ #
62
+ # If the class is known, then the header will be pre-filled with
63
+ # the columns defined in that class (assuming it's an ActiveRecord
64
+ # class).
65
+ def initialize(collection, klass = nil)
66
+ super()
52
67
 
53
- # The proxy class used externally to build the actual columns
54
- attr_reader :builder
68
+ @collection = collection
69
+ @row = Row.new
70
+ @builder = HeaderBuilder.new(self)
55
71
 
56
- # Whether or not the header should be hidden when the collection is
57
- # empty. Default is true.
58
- attr_accessor :hide_when_empty
72
+ @hide_when_empty = true
73
+ @customized = true
59
74
 
60
- # Creates a new header for a collection that contains objects of the
61
- # given class.
62
- #
63
- # If the class is known, then the header will be pre-filled with
64
- # the columns defined in that class (assuming it's an ActiveRecord
65
- # class).
66
- def initialize(collection, klass = nil)
67
- super()
68
-
69
- @collection = collection
70
- @row = Row.new
71
- @builder = HeaderBuilder.new(self)
72
-
73
- @hide_when_empty = true
75
+ # If we know what class the objects in the collection are and we can
76
+ # figure out what columns are defined in that class, then we can
77
+ # pre-fill the header with those columns so that the user doesn't
78
+ # have to
79
+ klass ||= class_for_collection(collection)
80
+ if klass && klass.respond_to?(:column_names)
81
+ klass.column_names.each {|name| column(name)}
82
+ @customized = false
83
+ end
84
+ end
85
+
86
+ # The current columns in this header, in the order in which they will be built
87
+ def columns
88
+ row.cells
89
+ end
90
+
91
+ # Gets the names of all of the columns being displayed in the table
92
+ def column_names
93
+ row.cell_names
94
+ end
95
+
96
+ # Clears all of the current columns from the header
97
+ def clear
98
+ # Remove all of the shortcut methods
99
+ column_names.each {|name| builder.undef_column(name)}
100
+ row.clear
101
+ end
102
+
103
+ # Creates a new column with the specified caption. Columns must be
104
+ # defined in the order in which they will be rendered.
105
+ #
106
+ # The caption determines what will be displayed in each cell of the
107
+ # header (if the header is rendered). For example,
108
+ #
109
+ # header.column :title, 'The Title'
110
+ #
111
+ # ...will create a column the displays "The Title" in the cell.
112
+ #
113
+ # = Setting html options
114
+ #
115
+ # In addition to customizing the content of the column, you can also
116
+ # specify html options like so:
117
+ #
118
+ # header.column :title, 'The Title', :class => 'pretty'
119
+ def column(name, *args)
120
+ # Clear the header row if this is being customized by the user
121
+ unless @customized
74
122
  @customized = true
75
-
76
- # If we know what class the objects in the collection are and we can
77
- # figure out what columns are defined in that class, then we can
78
- # pre-fill the header with those columns so that the user doesn't
79
- # have to
80
- klass ||= class_for_collection(collection)
81
- if klass && klass.respond_to?(:column_names)
82
- klass.column_names.each {|name| column(name)}
83
- @customized = false
84
- end
123
+ clear
85
124
  end
86
125
 
87
- # The current columns in this header, in the order in which they will be built
88
- def columns
89
- row.cells
90
- end
126
+ column = row.cell(name, *args)
127
+ column.content_type = :header
128
+ column[:scope] ||= 'col'
91
129
 
92
- # Gets the names of all of the columns being displayed in the table
93
- def column_names
94
- row.cell_names
95
- end
130
+ builder.define_column(name)
96
131
 
97
- # Clears all of the current columns from the header
98
- def clear
99
- # Remove all of the shortcut methods
100
- column_names.each {|name| builder.undef_column(name)}
101
- row.clear
102
- end
132
+ column
133
+ end
134
+
135
+ # Creates and returns the generated html for the header
136
+ def html
137
+ html_options = @html_options.dup
138
+ html_options[:style] = 'display: none;' if @collection.empty? && hide_when_empty
103
139
 
104
- # Creates a new column with the specified caption. Columns must be
105
- # defined in the order in which they will be rendered.
106
- #
107
- # The caption determines what will be displayed in each cell of the
108
- # header (if the header is rendered). For example,
109
- #
110
- # header.column :title, 'The Title'
111
- #
112
- # ...will create a column the displays "The Title" in the cell.
113
- #
114
- # = Setting html options
115
- #
116
- # In addition to customizing the content of the column, you can also
117
- # specify html options like so:
118
- #
119
- # header.column :title, 'The Title', :class => 'pretty'
120
- def column(name, *args)
121
- # Clear the header row if this is being customized by the user
122
- unless @customized
123
- @customized = true
124
- clear
140
+ content_tag(tag_name, content, html_options)
141
+ end
142
+
143
+ private
144
+ # Finds the class representing the objects within the collection
145
+ def class_for_collection(collection)
146
+ if collection.respond_to?(:proxy_reflection)
147
+ collection.proxy_reflection.klass
148
+ elsif !collection.empty?
149
+ collection.first.class
125
150
  end
126
-
127
- column = row.cell(name, *args)
128
- column.content_type = :header
129
- column[:scope] ||= 'col'
130
-
131
- builder.define_column(name)
132
-
133
- column
134
151
  end
135
152
 
136
- # Creates and returns the generated html for the header
137
- def html
138
- html_options = @html_options.dup
139
- html_options[:style] = 'display: none;' if @collection.empty? && hide_when_empty
140
-
141
- content_tag(tag_name, content, html_options)
153
+ def tag_name
154
+ 'thead'
142
155
  end
143
156
 
144
- private
145
- # Finds the class representing the objects within the collection
146
- def class_for_collection(collection)
147
- if collection.respond_to?(:proxy_reflection)
148
- collection.proxy_reflection.klass
149
- elsif !collection.empty?
150
- collection.first.class
151
- end
152
- end
153
-
154
- def tag_name
155
- 'thead'
156
- end
157
-
158
- def content
159
- @row.html
160
- end
161
- end
157
+ def content
158
+ @row.html
159
+ end
162
160
  end
163
161
  end