easy-table 0.2.0

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.
@@ -0,0 +1,36 @@
1
+ module EasyTable::ViewExt::Row
2
+ module Data
3
+ def data_rows collection, attributes, options = {}
4
+ content = []
5
+ reset_cycle('rows')
6
+ collection.each do |obj|
7
+ row_content = data_row(obj, attributes, options)
8
+ content << indent(2) + row_content
9
+ end
10
+ content.join.html_safe
11
+ end
12
+
13
+ def data_row object, attributes, options={}
14
+ row_content = attribute_cells object, attributes, options.clone
15
+
16
+ cls_opt = class_option(:row_classes, options, :name => 'rows')
17
+ options[:row] ||= {}
18
+ options[:row].merge!(cls_opt)
19
+
20
+ indent_tag(2, :tr, row_content, options[:row]).html_safe
21
+ end
22
+
23
+ def attribute_cells object, attributes, options = {}
24
+ options.delete(:row_classes)
25
+ content = []
26
+ reset_cycle('cells')
27
+ attributes.each do |attrib|
28
+ cls_opt = class_option(:cell_classes, options, :name => 'cells')
29
+
30
+ content << cell(object, attrib, options.merge(cls_opt))
31
+ content << ''.indent(2) if attrib == attributes.last
32
+ end
33
+ content.join.html_safe
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,30 @@
1
+ require 'require_all'
2
+ require_all File.dirname(__FILE__) + '/table'
3
+ require 'easy-table/row'
4
+
5
+ module EasyTable::ViewExt
6
+ module Table
7
+ def table(collection, headers, options = {}, &block)
8
+ obj_type = get_obj_type collection
9
+ set_options! options
10
+
11
+ return options[:placeholder] unless collection.any?
12
+
13
+ options.delete :placeholder
14
+ caption = options.delete :caption
15
+ footer = options.delete :footer
16
+
17
+
18
+ render_table options do
19
+ [
20
+ render_caption(caption),
21
+ render_header(headers),
22
+ render_footer(footer, headers),
23
+ render_tbody(collection, &block)
24
+ ].compact.join.html_safe
25
+ end
26
+ end
27
+
28
+ includes :base, :data
29
+ end
30
+ end
@@ -0,0 +1,29 @@
1
+ require 'easy-table/row'
2
+
3
+ module EasyTable::ViewExt::Table
4
+ module Base
5
+ def render_table options = {}, &block
6
+ content_tag :table, options do
7
+ yield.indent(0)
8
+ end
9
+ end
10
+
11
+ def render_tbody collection, options={}, &block
12
+ indent_tag 1, :tbody do
13
+ table_body(collection, options, &block).indent(1)
14
+ end
15
+ end
16
+
17
+ def table_body collection, options = {}, &block
18
+ content = []
19
+ collection.each do |obj|
20
+ content << with_output_buffer { yield obj, options }
21
+ end
22
+ content.join.html_safe
23
+ end
24
+
25
+ def render_caption caption
26
+ indent_tag(1, :caption, caption) if !caption.blank?
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,56 @@
1
+ module EasyTable::ViewExt::Table
2
+ module Data
3
+ def data_table(collection, headers, options = {})
4
+ obj_type = get_obj_type collection
5
+ set_options! options
6
+
7
+ return options[:placeholder] unless collection.any?
8
+
9
+ # try to extract attributes from headers!
10
+ attributes = options[:attributes] || extract_attributes(collection.first, headers)
11
+
12
+ arg_err = "You must specify an :attributes hash option to indicate which attributes of #{obj_type.camelize} should be rendered in the table!"
13
+ raise ArgumentError, arg_err if !attributes.any?
14
+
15
+ rows_options = options.delete(:rows) || {}
16
+
17
+ options.delete :placeholder
18
+ caption = options.delete :caption
19
+ footer = options.delete :footer
20
+
21
+
22
+ render_table options do
23
+ [
24
+ render_caption(caption),
25
+ render_header(headers),
26
+ render_footer(footer, headers),
27
+ indent_tag(1, :tbody) do
28
+ data_rows(collection, attributes, rows_options).indent 1
29
+ end
30
+ ].compact.join
31
+ end
32
+ end
33
+
34
+ def extract_attributes obj, headers
35
+ headers.map do |header|
36
+ att = header.to_s.underscore
37
+ attrib = obj.send att
38
+ att ? att : nil
39
+ end.compact
40
+ end
41
+
42
+ def set_options! options={}, obj_type=nil
43
+ options.reverse_merge!({
44
+ :placeholder => 'Nothing to display',
45
+ :caption => nil,
46
+ :summary => nil,
47
+ :footer => '',
48
+ :class => obj_type
49
+ })
50
+ end
51
+
52
+ def get_obj_type collection
53
+ collection.first.class.to_s
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,21 @@
1
+ module EasyTable::ViewExt
2
+ module Tag
3
+ def indent_tag lv, *args, &block
4
+ (indent(lv) + content_tag(*args, &block)).html_safe
5
+ end
6
+
7
+ def do_tag *args, &block
8
+ indent_tag 0, *args, &block
9
+ end
10
+
11
+ def indent(lv)
12
+ "\n" + (" " * lv)
13
+ end
14
+ end
15
+ end
16
+
17
+ class String
18
+ def indent lv
19
+ self << "\n" + (" " * lv)
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ require 'sugar-high/blank'
2
+ require 'sugar-high/array'
3
+ require 'sugar-high/arguments'
4
+
5
+ module EasyTable::ViewExt
6
+ module Util
7
+ def class_option id, options, cycle_options={}
8
+ return {} if !options[id]
9
+ {:class => get_class(options[id], :name => cycle_options[:name] || nil) }
10
+ end
11
+
12
+ def get_class *classes
13
+ options = last_option classes
14
+ return cycle_class(options[:name]) if classes.blank?
15
+
16
+ classes = [classes].flatten
17
+ name = options[:name]
18
+
19
+ return cycle(*classes, :name => name) if name
20
+ cycle(*classes)
21
+ end
22
+
23
+ def cycle_class name=nil
24
+ name ? cycle('odd', 'even', :name => name) : cycle('odd', 'even')
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ require 'active_support/inflector'
2
+ require 'require_all'
3
+ require 'sugar-high/includes'
4
+ require 'sugar-high/blank'
5
+ require 'sugar-high/blank'
6
+ require 'sugar-high/array'
7
+
8
+ require 'easy-table/namespaces'
9
+
10
+ require 'easy-table/table'
11
+ require 'easy-table/row'
12
+ require 'easy-table/cell'
13
+ require 'easy-table/tag'
14
+
15
+ module EasyTable
16
+ module ViewExt
17
+ includes :table, :row, :cell, :tag, :util
18
+ end
19
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ require 'sugar-high/includes'
4
+ require 'easy-table/namespaces'
5
+ require 'easy-table/cell'
6
+
7
+ describe EasyTable::ViewExt::Cell do
8
+ extend_view_with EasyTable::ViewExt, :cell, :tag
9
+
10
+ before :each do
11
+ @post = stub(:title => 'my post', :id => 1, :author => 'kristian' )
12
+ end
13
+
14
+ describe '#cell' do
15
+ it 'should display a cell with the post title' do
16
+ with_engine(:erb) do |e|
17
+ res = e.run_template_locals :post => @post do %{
18
+ <%= cell post, :title %>
19
+ }
20
+ end
21
+ res.should match(/<td>my post<\/td>/)
22
+ end
23
+ end
24
+
25
+ it 'should display a cell with a class' do
26
+ with_engine(:erb) do |e|
27
+ res = e.run_template_locals :post => @post do %{
28
+ <%= cell post, :title, :class => 'posting' %>
29
+ }
30
+ end
31
+ res.should match(/<td class="posting">my post<\/td>/)
32
+ end
33
+ end
34
+ end
35
+
36
+ describe '#cells' do
37
+ it 'should display cells for post' do
38
+ with_engine do |e|
39
+ res = e.run_template_locals :post => @post do %{
40
+ <%= cells post, %w{id title} %>
41
+ }
42
+ end
43
+ res.should match /<td>1<\/td>/
44
+ res.should match /<td>my post<\/td>/
45
+ end
46
+ end
47
+
48
+ it 'should display cells for post with classes' do
49
+ with_engine do |e|
50
+ res = e.run_template_locals :post => @post do %{
51
+ <%= cells post, %w{id title}, :classes => %w{red blue} %>
52
+ }
53
+ end
54
+ res.should match /<td class="red">1<\/td>/
55
+ res.should match /<td class="blue">my post<\/td>/
56
+ end
57
+ end
58
+ end
59
+
60
+ describe '#headers' do
61
+ it 'should display header cells' do
62
+ with_engine do |e|
63
+ res = e.run_template do %{
64
+ <%= header_row %w{Id Title} %>
65
+ }
66
+ end
67
+ res.should match /<th>Id<\/th>/
68
+ res.should match /<th>Title<\/th>/
69
+ end
70
+ end
71
+ end
72
+
73
+ end
74
+
75
+
@@ -0,0 +1,100 @@
1
+ require 'spec_helper'
2
+
3
+ require 'sugar-high/includes'
4
+ require 'easy-table/namespaces'
5
+ require 'easy-table/cell'
6
+ require 'easy-table/row'
7
+
8
+ describe EasyTable::ViewExt::Row do
9
+ extend_view_with EasyTable::ViewExt, :row, :cell, :tag
10
+
11
+ before :each do
12
+ @post = stub(:title => 'my post', :id => 1, :author => 'kristian' )
13
+ @post2 = stub(:title => 'my other post', :id => 2, :author => 'mike' )
14
+
15
+ @posts = [@post, @post2]
16
+ end
17
+
18
+ describe '#attribute_cells' do
19
+ it 'should display cells with data' do
20
+ with_engine(:erb) do |e|
21
+ res = e.run_template_locals :post => @post do %{
22
+ <%= attribute_cells post, %w{id title} %>
23
+ }
24
+ end
25
+ res.should_not match /<tr>/
26
+ res.should match /<td>1<\/td>/
27
+ res.should match /<td>my post<\/td>/
28
+ end
29
+ end
30
+ end
31
+
32
+ describe '#data_row' do
33
+ it 'should display a row with data' do
34
+ with_engine(:erb) do |e|
35
+ res = e.run_template_locals :post => @post do %{
36
+ <%= data_row post, %w{id title} %>
37
+ }
38
+ end
39
+ res.should match /<tr>/
40
+ res.should match /<td>1<\/td>/
41
+ res.should match /<td>my post<\/td>/
42
+ end
43
+ end
44
+
45
+ it 'should display a row with data and row class' do
46
+ with_engine(:erb) do |e|
47
+ res = e.run_template_locals :post => @post do %{
48
+ <%= data_row post, %w{id title}, :row => {:class => 'my_data_row'} %>
49
+ }
50
+ end
51
+ res.should match /<tr class="my_data_row">/
52
+ res.should match /<td>1<\/td>/
53
+ res.should match /<td>my post<\/td>/
54
+ end
55
+ end
56
+
57
+ it 'should display a row with data' do
58
+ with_engine(:erb) do |e|
59
+ res = e.run_template_locals :post => @post do %{
60
+ <%= data_row post, %w{id title}, :row => {:class => 'my_data_row'}, :cell_classes => %w{number label} %>
61
+ }
62
+ end
63
+ res.should match /<tr class="my_data_row">/
64
+ res.should match /<td class="number">1<\/td>/
65
+ res.should match /<td class="label">my post<\/td>/
66
+ end
67
+ end
68
+ end
69
+
70
+ describe '#data_rows' do
71
+ it 'should display a row with cells' do
72
+ with_engine(:erb) do |e|
73
+ res = e.run_template_locals :posts => @posts do %{
74
+ <%= data_rows posts, %w{id title} %>
75
+ }
76
+ end
77
+ res.should match /<tr>/
78
+ res.should match /<td>1<\/td>/
79
+ res.should match /<td>my post<\/td>/
80
+ res.should match /<td>2<\/td>/
81
+ res.should match /<td>my other post<\/td>/
82
+ end
83
+ end
84
+
85
+ it 'should display a row with cells with cycling classes' do
86
+ with_engine(:erb) do |e|
87
+ res = e.run_template_locals :posts => @posts do %{
88
+ <%= data_rows posts, %w{id title}, :row_classes => %w{row1 row2}, :cell_classes => %w{number label} %>
89
+ }
90
+ end
91
+ res.should match /<tr class="row1">/
92
+ res.should match /<tr class="row2">/
93
+ res.should match /<td class="number">1<\/td>/
94
+ res.should match /<td class="label">my post<\/td>/
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ require 'sugar-high/includes'
4
+ require 'easy-table/namespaces'
5
+ require 'easy-table/row'
6
+
7
+ describe EasyTable::ViewExt::Row do
8
+ extend_view_with EasyTable::ViewExt, :row, :cell, :tag
9
+
10
+ before :each do
11
+ @post = stub(:title => 'my post', :id => 1, :author => 'kristian' )
12
+ end
13
+
14
+ describe '#row' do
15
+ it 'should display a cell with the post title' do
16
+ with_engine(:erb) do |e|
17
+ res = e.run_template_locals :post => @post do %{
18
+ <%= row post, :class => :mine do |post| %>
19
+ <%= cells post, %w{id title} %>
20
+ <% end %>
21
+ }
22
+ end
23
+ res.should match /<tr class="mine">/
24
+ res.should match /<td>1<\/td>/
25
+ res.should match /<td>my post<\/td>/
26
+ end
27
+ end
28
+ end
29
+
30
+ describe '#render_header' do
31
+ it 'should display a header with header cells' do
32
+ with_engine(:erb) do |e|
33
+ res = e.run_template_locals :post => @post do %{
34
+ <%= render_header %w{Id Title} %>
35
+ }
36
+ end
37
+ res.should match /<thead>/
38
+ res.should match /<tr>/
39
+ res.should match /<th>Id<\/th>/
40
+ res.should match /<th>Title<\/th>/
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '#render_footer' do
46
+ it 'should display a footer spanning the length of the header' do
47
+ with_engine(:erb) do |e|
48
+ res = e.run_template_locals :post => @post do %{
49
+ <%= render_footer 'a nice table', %w{id title} %>
50
+ }
51
+ end
52
+ res.should match /<tfoot>/
53
+ res.should match /colspan="2"/
54
+ end
55
+ end
56
+
57
+ it 'should display a footer spanning 2 cells' do
58
+ with_engine(:erb) do |e|
59
+ res = e.run_template_locals :post => @post do %{
60
+ <%= render_footer 'a nice table', 2%>
61
+ }
62
+ end
63
+ res.should match /<tfoot>/
64
+ res.should match /colspan="2"/
65
+ end
66
+ end
67
+ end
68
+ end