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.
@@ -1,119 +1,116 @@
1
1
  require 'table_helper/body_row'
2
2
 
3
- module PluginAWeek #:nodoc:
4
- module TableHelper
5
- # Represents the body of the table. In HTML, you can think of this as
6
- # the <tbody> tag of the table.
7
- class Body < HtmlElement
8
- # If set to :odd or :even, every odd or even-numbered row will have the
9
- # class 'alternate' appended to its html attributes, respectively.
10
- # Default is nil.
11
- attr_accessor :alternate_rows
3
+ module TableHelper
4
+ # Represents the body of the table. In HTML, you can think of this as
5
+ # the <tbody> tag of the table.
6
+ class Body < HtmlElement
7
+ # If set to :odd or :even, every odd or even-numbered row will have the
8
+ # class 'alternate' appended to its html attributes. Default is nil.
9
+ attr_accessor :alternate_rows
10
+
11
+ # The caption to display in the collection is empty
12
+ attr_accessor :empty_caption
13
+
14
+ def initialize(collection, header) #:nodoc:
15
+ super()
12
16
 
13
- # The caption to display in the collection is empty
14
- attr_accessor :empty_caption
17
+ @collection, @header = collection, header
18
+ @empty_caption = 'No matches found.'
19
+ end
20
+
21
+ def alternate_rows=(value) #:nodoc:
22
+ raise ArgumentError, 'alternate_rows must be set to :odd or :even' if value && ![:odd, :even].include?(value)
23
+ @alternate_rows = value
24
+ end
25
+
26
+ # Builds the body of the table. This includes the actual data that is
27
+ # generated for each object in the collection.
28
+ #
29
+ # +build+ expects a block that defines the data in each cell. Each
30
+ # iteration of the block will provide the object being rendered, the row
31
+ # within the table that will be built and the index of the object. For
32
+ # example,
33
+ #
34
+ # body.build do |row, post, index|
35
+ # row.title "<div class=\"wrapped\">#{post.title}</div>"
36
+ # row.category post.category.name
37
+ # end
38
+ #
39
+ # In addition, to specifying the data, you can also modify the html
40
+ # options of the row. For more information on doing this, see the
41
+ # BodyRow class.
42
+ #
43
+ # If the collection is empty and +empty_caption+ is set on the body,
44
+ # then the actual body will be replaced by a single row containing the
45
+ # html that was stored in +empty_caption+.
46
+ #
47
+ # == Default Values
48
+ #
49
+ # Whenever possible, the default value of a cell will be set to the
50
+ # object's attribute with the same name as the cell. For example,
51
+ # if a Post consists of the attribute +title+, then the cell for the
52
+ # title will be prepopulated with that attribute's value:
53
+ #
54
+ # body.build do |row, post index|
55
+ # row.category post.category.name
56
+ # end
57
+ #
58
+ # <tt>row.title</tt> is already set to post.category so there's no need to
59
+ # manually set the value of that cell. However, it is always possible
60
+ # to override the default value like so:
61
+ #
62
+ # body.build do |row, post, index|
63
+ # row.title link_to(post.title, post_url(post))
64
+ # row.category post.category.name
65
+ # end
66
+ def build(&block)
67
+ @content = ''
15
68
 
16
- def initialize(collection, header) #:nodoc:
17
- super()
69
+ # Display nothing if there are no objects to display
70
+ if @collection.empty? && @empty_caption
71
+ row = Row.new
72
+ row[:class] = 'no_content'
18
73
 
19
- @collection, @header = collection, header
20
- @empty_caption = 'No matches found.'
21
- end
22
-
23
- def alternate_rows=(value) #:nodoc:
24
- raise ArgumentError, 'alternate_rows must be set to :odd or :even' if value && ![:odd, :even].include?(value)
25
- @alternate_rows = value
26
- end
27
-
28
- # Builds the body of the table. This includes the actual data that is
29
- # generated for each object in the collection.
30
- #
31
- # build expects a block that defines the data in each cell. Each
32
- # iteration of the block will provide the object being rendered, the row
33
- # within the table that will be built and the index of the object. For
34
- # example,
35
- #
36
- # body.build do |row, post, index|
37
- # row.title "<div class=\"wrapped\">#{post.title}</div>"
38
- # row.category post.category.name
39
- # end
40
- #
41
- # In addition, to specifying the data, you can also modify the html
42
- # options of the row. For more information on doing this, see the
43
- # BodyRow class.
44
- #
45
- # If the collection is empty and +empty_caption+ is set on the Body,
46
- # then the actual body will be replaced by a single row containing the
47
- # html that was stored in +empty_caption+.
48
- #
49
- # == Default Values
50
- #
51
- # Whenever possible, the default value of a cell will be set to the
52
- # object's attribute with the same name as the cell. For example,
53
- # if a Post consists of the attribute +title+, then the cell for the
54
- # title will be prepopulated with that attribute's value:
55
- #
56
- # body.build do |row, post index|
57
- # row.category post.category.name
58
- # end
59
- #
60
- # +row.title+ is already set to post.category so there's no need to
61
- # manually set the value of that cell. However, it is always possible
62
- # to override the default value like so:
63
- #
64
- # body.build do |row, post, index|
65
- # row.title link_to(post.title, post_url(post))
66
- # row.category post.category.name
67
- # end
68
- def build(&block)
69
- @content = ''
74
+ html_options = {}
75
+ html_options[:colspan] = @header.column_names.size if @header.column_names.size > 1
76
+ row.cell nil, @empty_caption, html_options
70
77
 
71
- # Display nothing if there are no objects to display
72
- if @collection.empty? && @empty_caption
73
- row = Row.new
74
- row[:class] = 'no_content'
75
-
76
- html_options = {}
77
- html_options[:colspan] = @header.column_names.size if @header.column_names.size > 1
78
- row.cell nil, @empty_caption, html_options
79
-
80
- @content << row.html
81
- else
82
- @collection.each_with_index do |object, i|
83
- @content << build_row(object, i, &block)
84
- end
78
+ @content << row.html
79
+ else
80
+ @collection.each_with_index do |object, i|
81
+ @content << build_row(object, i, &block)
85
82
  end
86
-
87
- @content
88
83
  end
89
84
 
90
- # Builds a row for an object in the table.
91
- #
92
- # The provided block should set the values for each cell in the row.
93
- def build_row(object, index = @collection.index(object), &block)
94
- row = BodyRow.new(object, @header)
95
- row.alternate = alternate_rows ? index.send("#{@alternate_rows}?") : false
96
-
97
- yield row.builder, object, index if block_given?
98
-
99
- row.html
100
- end
85
+ @content
86
+ end
87
+
88
+ # Builds a row for an object in the table.
89
+ #
90
+ # The provided block should set the values for each cell in the row.
91
+ def build_row(object, index = @collection.index(object), &block)
92
+ row = BodyRow.new(object, @header)
93
+ row.alternate = alternate_rows ? index.send("#{@alternate_rows}?") : false
101
94
 
102
- def html #:nodoc:
103
- html_options = @html_options.dup
104
- html_options[:class] = (html_options[:class].to_s + ' alternate').strip if alternate_rows
105
-
106
- content_tag(tag_name, content, html_options)
107
- end
95
+ yield row.builder, object, index if block_given?
108
96
 
109
- private
110
- def tag_name
111
- 'tbody'
112
- end
113
-
114
- def content
115
- @content
116
- end
97
+ row.html
117
98
  end
99
+
100
+ def html #:nodoc:
101
+ html_options = @html_options.dup
102
+ html_options[:class] = (html_options[:class].to_s + ' alternate').strip if alternate_rows
103
+
104
+ content_tag(tag_name, content, html_options)
105
+ end
106
+
107
+ private
108
+ def tag_name
109
+ 'tbody'
110
+ end
111
+
112
+ def content
113
+ @content
114
+ end
118
115
  end
119
116
  end
@@ -1,86 +1,70 @@
1
1
  require 'table_helper/row'
2
2
 
3
- module PluginAWeek #:nodoc:
4
- module TableHelper
5
- # Represents a single row within the body of a table. The row can consist
6
- # of either data cells or header cells.
7
- #
8
- # == Borders
9
- #
10
- # Each row has an optional special border row that can be generated either
11
- # immediately before or immediately after this row. A separate border row
12
- # is usually used when you cannot express borders in the css of the row
13
- # containing the data (e.g. dotted borders in Internet Explorer).
14
- #
15
- # To modify the properties of the border, you can access +row.border+ like
16
- # so:
17
- #
18
- # r = BodyRow.new
19
- # r.border_type = :before
20
- # r.border[:style] = 'color: #ff0000;'
21
- #
22
- # == Alternating rows
23
- #
24
- # Alternating rows can be automated by setting the +alternate+ property.
25
- # For example,
26
- #
27
- # r = BodyRow.new
28
- # r.alternate = true
29
- class BodyRow < Row
30
- # True if this is an alternating row, otherwise false. Default is false.
31
- attr_accessor :alternate
3
+ module TableHelper
4
+ # Represents a single row within the body of a table. The row can consist
5
+ # of either data cells or header cells.
6
+ #
7
+ # == Alternating rows
8
+ #
9
+ # Alternating rows can be automated by setting the +alternate+ property.
10
+ # For example,
11
+ #
12
+ # r = BodyRow.new
13
+ # r.alternate = true
14
+ class BodyRow < Row
15
+ # True if this is an alternating row, otherwise false. Default is false.
16
+ attr_accessor :alternate
17
+
18
+ def initialize(object, header) #:nodoc:
19
+ super()
32
20
 
33
- def initialize(object, header) #:nodoc:
34
- super()
35
-
36
- @header = header
37
- @alternate = false
38
- @html_options[:class] = ('row ' + @html_options[:class].to_s).strip
21
+ @header = header
22
+ @alternate = false
23
+ @html_options[:class] = ('row ' + @html_options[:class].to_s).strip
24
+
25
+ # For each column defined in the table, see if we can prepopulate the
26
+ # cell based on the data in the object. If not, we can at least
27
+ # provide shortcut accessors to the cell
28
+ @header.column_names.each do |column|
29
+ if object.respond_to?(column)
30
+ cell(column, object.send(column))
31
+ else
32
+ builder.define_cell(column)
33
+ end
34
+ end
35
+ end
36
+
37
+ # Generates the html for this row in additional to the border row
38
+ # (if specified)
39
+ def html
40
+ original_options = @html_options.dup
41
+ @html_options[:class] = (@html_options[:class].to_s + ' alternate').strip if alternate
42
+ html = super
43
+ @html_options = original_options
44
+ html
45
+ end
46
+
47
+ private
48
+ # Builds the row's cells based on the order of the columns in the
49
+ # header. If a cell cannot be found for a specific column, then a blank
50
+ # cell is rendered.
51
+ def content
52
+ number_to_skip = 0 # Keeps track of the # of columns to skip
39
53
 
40
- # For each column defined in the table, see if we can prepopulate the
41
- # cell based on the data in the object. If not, we can at least
42
- # provide shortcut accessors to the cell
54
+ html = ''
43
55
  @header.column_names.each do |column|
44
- if object.respond_to?(column)
45
- cell(column, object.send(column))
56
+ number_to_skip -= 1 and next if number_to_skip > 0
57
+
58
+ if cell = @cells[column]
59
+ number_to_skip = (cell[:colspan] || 1) - 1
46
60
  else
47
- builder.define_cell(column)
61
+ cell = Cell.new(column, '', :class => 'empty')
48
62
  end
63
+
64
+ html << cell.html
49
65
  end
50
- end
51
-
52
- # Generates the html for this row in additional to the border row
53
- # (if specified)
54
- def html
55
- original_options = @html_options.dup
56
- @html_options[:class] = (@html_options[:class].to_s + ' alternate').strip if alternate
57
- html = super
58
- @html_options = original_options
66
+
59
67
  html
60
68
  end
61
-
62
- private
63
- # Builds the row's cells based on the order of the columns in the
64
- # header. If a cell cannot be found for a specific column, then a blank
65
- # cell is rendered.
66
- def content
67
- number_to_skip = 0 # Keeps track of the # of columns to skip
68
-
69
- html = ''
70
- @header.column_names.each do |column|
71
- number_to_skip -= 1 and next if number_to_skip > 0
72
-
73
- if cell = @cells[column]
74
- number_to_skip = (cell[:colspan] || 1) - 1
75
- else
76
- cell = Cell.new(column, '', :class => 'empty')
77
- end
78
-
79
- html << cell.html
80
- end
81
-
82
- html
83
- end
84
- end
85
69
  end
86
70
  end
@@ -1,51 +1,49 @@
1
- module PluginAWeek #:nodoc:
2
- module TableHelper
3
- # Represents a single cell within a table. This can either be a regular
4
- # data cell (td) or a header cell (th). By default, all cells will have
5
- # their column name appended to the cell's class attribute.
6
- #
7
- # == Creating data cells
8
- #
9
- # Cell.new(:author, 'John Doe').build
10
- #
11
- # ...would generate the following tag:
12
- #
13
- # <td class="author">John Doe</td>
14
- #
15
- # == Creating header cells
16
- #
17
- # c = Cell.new(:author, 'Author Name')
18
- # c.content_type = :header
19
- # c.build
20
- #
21
- # ...would generate the following tag:
22
- #
23
- # <th class="author">Author Name</th>
24
- class Cell < HtmlElement
25
- def initialize(class_name, content = class_name.to_s.titleize, html_options = {}) #:nodoc
26
- super(html_options)
27
-
28
- @content = content
29
- @html_options[:class] = ("#{class_name} " + @html_options[:class].to_s).strip if class_name
30
-
31
- self.content_type = :data
32
- end
1
+ module TableHelper
2
+ # Represents a single cell within a table. This can either be a regular
3
+ # data cell (td) or a header cell (th). By default, all cells will have
4
+ # their column name appended to the cell's class attribute.
5
+ #
6
+ # == Creating data cells
7
+ #
8
+ # Cell.new(:author, 'John Doe').build
9
+ #
10
+ # ...would generate the following tag:
11
+ #
12
+ # <td class="author">John Doe</td>
13
+ #
14
+ # == Creating header cells
15
+ #
16
+ # c = Cell.new(:author, 'Author Name')
17
+ # c.content_type = :header
18
+ # c.build
19
+ #
20
+ # ...would generate the following tag:
21
+ #
22
+ # <th class="author">Author Name</th>
23
+ class Cell < HtmlElement
24
+ def initialize(class_name, content = class_name.to_s.titleize, html_options = {}) #:nodoc
25
+ super(html_options)
33
26
 
34
- # Indicates what type of content will be stored in this cell. This can
35
- # either be set to either :data or :header.
36
- def content_type=(value)
37
- raise ArgumentError, "content_type must be set to :data or :header, was: #{value.inspect}" unless [:data, :header].include?(value)
38
- @content_type = value
39
- end
27
+ @content = content
28
+ @html_options[:class] = ("#{class_name} " + @html_options[:class].to_s).strip if class_name
40
29
 
41
- private
42
- def tag_name
43
- @content_type == :data ? 'td' : 'th'
44
- end
45
-
46
- def content
47
- @content
48
- end
30
+ self.content_type = :data
31
+ end
32
+
33
+ # Indicates what type of content will be stored in this cell. This can
34
+ # be set to either :data or :header.
35
+ def content_type=(value)
36
+ raise ArgumentError, "content_type must be set to :data or :header, was: #{value.inspect}" unless [:data, :header].include?(value)
37
+ @content_type = value
49
38
  end
39
+
40
+ private
41
+ def tag_name
42
+ @content_type == :data ? 'td' : 'th'
43
+ end
44
+
45
+ def content
46
+ @content
47
+ end
50
48
  end
51
49
  end