table_cloth 0.1.0 → 0.1.1

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.
data/.travis.yml ADDED
@@ -0,0 +1,2 @@
1
+ before_install:
2
+ - gem install nokogiri -- --with-cflags='--std=gnu99'
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Table Cloth gives you an easy to use DSL for creating and rendering tables in rails.
4
4
 
5
+ [![Build Status](https://travis-ci.org/bobbytables/table_cloth.png)](https://travis-ci.org/bobbytables/table_cloth)
6
+
5
7
  ## Installation
6
8
 
7
9
  Add this line to your application's Gemfile:
@@ -72,6 +74,67 @@ The second approach to making tables with Table Cloth is in the view.
72
74
  <% end %>
73
75
  ```
74
76
 
77
+ ## Columns
78
+
79
+ You can create your own column by making a class that responds to ```.value(object, view)```
80
+
81
+ ```ruby
82
+ class ImageColumn < TableCloth::Column
83
+ def value(object, view)
84
+ view.raw(view.image_tag(object.image_url))
85
+ end
86
+ end
87
+ ```
88
+
89
+ In your table
90
+ ```
91
+ <%= simple_table_for @users do |table| %>
92
+ <% table.column :name %>
93
+ <% table.column :image, using: ImageColumn %>
94
+ <% end %>
95
+ ```
96
+
97
+ ## Actions
98
+
99
+ A lot of tables have an actions column to give you the full CRUD effect. They can be painful but Table Cloth incorporates a way to easily add them to your definition.
100
+
101
+ ```
102
+ class UserTable < TableCloth::Base
103
+ column :name
104
+ action {|object, view| view.link_to 'View', object }
105
+ action(if: :admin?) {|object, view| view.link_to 'Delete', object, method: :delete }
106
+
107
+ def admin?
108
+ view.current_user.admin?
109
+ end
110
+ end
111
+ ```
112
+
113
+
114
+ ## Configuration
115
+
116
+ Create an initializer called ```table_cloth.rb```
117
+
118
+ Configuration looks like this:
119
+
120
+ ```ruby
121
+ TableCloth::Configuration.configure do |config|
122
+ config.table.class = 'table table-bordered'
123
+ config.thead.class = ''
124
+ config.tbody.class = ''
125
+ config.tr.class =''
126
+ config.th.class =''
127
+ config.td.class =''
128
+ end
129
+ ```
130
+
131
+ You can set any value on table element configurations. For example:
132
+
133
+ ```ruby
134
+ config.table.cellpadding = 1
135
+ config.td.valign = 'top'
136
+ ```
137
+
75
138
  ## Contributing
76
139
 
77
140
  1. Fork it
data/Rakefile CHANGED
@@ -1 +1,4 @@
1
- require "bundler/gem_tasks"
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new(:spec)
4
+ task default: :spec
@@ -5,5 +5,17 @@ module TableCloth
5
5
  def initialize(options)
6
6
  @options = options
7
7
  end
8
+
9
+ def available?(table)
10
+ if options[:if] && options[:if].is_a?(Symbol)
11
+ return !!table.send(options[:if])
12
+ end
13
+
14
+ if options[:unless] && options[:unless].is_a?(Symbol)
15
+ return !table.send(options[:unless])
16
+ end
17
+
18
+ true
19
+ end
8
20
  end
9
21
  end
@@ -39,8 +39,10 @@ module TableCloth
39
39
  options = args.extract_options! || {}
40
40
  options[:proc] = block if block_given?
41
41
 
42
+ column_class = options.delete(:using) || Column
43
+
42
44
  args.each do |name|
43
- add_column name, Column.new(name, options)
45
+ add_column name, column_class.new(name, options)
44
46
  end
45
47
  end
46
48
 
@@ -71,6 +73,7 @@ module TableCloth
71
73
  end
72
74
 
73
75
  columns[:actions].actions << action
76
+ action
74
77
  end
75
78
 
76
79
  def has_actions?
@@ -7,7 +7,7 @@ module TableCloth
7
7
  @options = options
8
8
  end
9
9
 
10
- def value(object, view)
10
+ def value(object, view, table=nil)
11
11
  if options[:proc] && options[:proc].respond_to?(:call)
12
12
  view.capture(object, options, view, &options[:proc])
13
13
  else
@@ -16,7 +16,7 @@ module TableCloth
16
16
  end
17
17
 
18
18
  def human_name
19
- name.to_s.humanize
19
+ options[:label] || name.to_s.humanize
20
20
  end
21
21
 
22
22
  def available?(table)
@@ -1,9 +1,13 @@
1
1
  module TableCloth
2
2
  module Columns
3
3
  class Action < Column
4
- def value(object, view_context)
4
+ def value(object, view_context, table)
5
5
  actions_html = actions.inject('') do |links, action|
6
- links + "\n" + view_context.capture(object, view_context, &action.options[:proc])
6
+ if action.available?(table)
7
+ links + "\n" + view_context.capture(object, view_context, &action.options[:proc])
8
+ else
9
+ links
10
+ end
7
11
  end
8
12
 
9
13
  view_context.raw(actions_html)
@@ -12,6 +16,10 @@ module TableCloth
12
16
  def actions
13
17
  @actions ||= []
14
18
  end
19
+
20
+ def available?(table)
21
+ actions.any? {|a| a.available?(table) }
22
+ end
15
23
  end
16
24
  end
17
25
  end
@@ -33,7 +33,7 @@ module TableCloth
33
33
 
34
34
  def row_values(object)
35
35
  column_values = table.columns.inject([]) do |values, (key, column)|
36
- values << column.value(object, view_context); values
36
+ values << column.value(object, view_context, table); values
37
37
  end
38
38
  end
39
39
 
@@ -1,3 +1,3 @@
1
1
  module TableCloth
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -3,6 +3,13 @@ require 'spec_helper'
3
3
  describe TableCloth::Base do
4
4
  subject { Class.new(TableCloth::Base) }
5
5
  let(:view_context) { ActionView::Base.new }
6
+ let(:dummy_model) do
7
+ DummyModel.new.tap do |d|
8
+ d.id = 1
9
+ d.email = 'robert@example.com'
10
+ d.name = 'robert'
11
+ end
12
+ end
6
13
 
7
14
  context 'columns' do
8
15
  it 'has a column method' do
@@ -19,12 +26,12 @@ describe TableCloth::Base do
19
26
 
20
27
  it '.columns returns all columns' do
21
28
  subject.column :name
22
- subject.columns.size.should == 1
29
+ subject.should have(1).columns
23
30
  end
24
31
 
25
32
  it 'excepts multiple column names' do
26
33
  subject.column :name, :email
27
- subject.columns.size.should == 2
34
+ subject.should have(2).columns
28
35
  end
29
36
 
30
37
  it 'stores a proc if given in options' do
@@ -44,17 +51,52 @@ describe TableCloth::Base do
44
51
  subject.action { '/' }
45
52
  subject.new([], view_context).column_names.should include 'Actions'
46
53
  end
47
- end
48
54
 
49
- context 'conditions' do
50
- let(:dummy_model) do
51
- DummyModel.new.tap do |d|
52
- d.id = 1
53
- d.email = 'robert@example.com'
54
- d.name = 'robert'
55
+ it '.column_names does not include actions if all action conditions fail' do
56
+ subject.action(if: :admin?) { '/' }
57
+ table = subject.new([], view_context)
58
+ def table.admin?
59
+ false
60
+ end
61
+
62
+ table.column_names.should_not include 'Actions'
63
+ end
64
+
65
+ it '.column_names include actions when only partial are available' do
66
+ subject.action(if: :admin?) { '/' }
67
+ subject.action(if: :awesome?) { '/' }
68
+ table = subject.new([], view_context)
69
+ def table.admin?
70
+ false
71
+ end
72
+
73
+ def table.awesome?
74
+ true
75
+ end
76
+
77
+ table.column_names.should include 'Actions'
78
+ end
79
+
80
+ it '.column_names uses a name given to it' do
81
+ subject.column :email, label: 'Email Address'
82
+ subject.new([], view_context).column_names.should include 'Email Address'
83
+ end
84
+
85
+ it '.column can take a custom column' do
86
+ email_column = Class.new(TableCloth::Column) do
87
+ def value(object, view)
88
+ "AN EMAIL!"
89
+ end
55
90
  end
91
+
92
+ subject.column :email, using: email_column
93
+ subject.new([dummy_model], view_context)
94
+
95
+ subject.columns[:email].value(dummy_model, view_context).should == "AN EMAIL!"
56
96
  end
97
+ end
57
98
 
99
+ context 'conditions' do
58
100
  context 'if' do
59
101
  subject { DummyTable.new([dummy_model], view_context) }
60
102
 
@@ -98,7 +140,23 @@ describe TableCloth::Base do
98
140
 
99
141
  it 'it adds an acion' do
100
142
  subject.action { '/' }
101
- subject.columns[:actions].actions.size.should == 1
143
+ subject.columns[:actions].should have(1).actions
144
+ end
145
+
146
+ context 'conditionals' do
147
+ let!(:table_class) { Class.new(DummyTable) }
148
+ subject { table_class.new([dummy_model], view_context) }
149
+
150
+ it 'accepts if condition' do
151
+ action = table_class.action(if: :admin?) { '/conditioned' }
152
+ action.available?(subject).should be_true
153
+ end
154
+
155
+
156
+ it 'accepts unless condition' do
157
+ action = table_class.action(unless: :admin?) { '/conditioned' }
158
+ action.available?(subject).should be_false
159
+ end
102
160
  end
103
161
  end
104
162
  end
@@ -28,4 +28,21 @@ describe TableCloth::Columns::Action do
28
28
  link.should be_present
29
29
  link[:href].should == '1'
30
30
  end
31
+
32
+ it '.value only returns actions that pass' do
33
+ admin_action = dummy_table.action(if: :admin?) { '/admin' }
34
+ moderator_action = dummy_table.action(if: :moderator?) { '/moderator' }
35
+ table = dummy_table.new([], view_context)
36
+
37
+ def table.admin?
38
+ true
39
+ end
40
+
41
+ def table.moderator?
42
+ false
43
+ end
44
+
45
+ dummy_table.columns[:actions].value(dummy_model, view_context, table).should include '/admin'
46
+ dummy_table.columns[:actions].value(dummy_model, view_context, table).should_not include '/moderator'
47
+ end
31
48
  end
data/table_cloth.gemspec CHANGED
@@ -22,6 +22,7 @@ Gem::Specification.new do |gem|
22
22
  gem.add_development_dependency('nokogiri')
23
23
  gem.add_development_dependency('pry')
24
24
  gem.add_development_dependency('guard-rspec')
25
+ gem.add_development_dependency('rake')
25
26
 
26
27
  gem.add_dependency('actionpack', '~> 3.2')
27
28
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: table_cloth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-02 00:00:00.000000000 Z
12
+ date: 2012-10-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -91,6 +91,22 @@ dependencies:
91
91
  - - ! '>='
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rake
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
94
110
  - !ruby/object:Gem::Dependency
95
111
  name: actionpack
96
112
  requirement: !ruby/object:Gem::Requirement
@@ -116,6 +132,7 @@ extra_rdoc_files: []
116
132
  files:
117
133
  - .gitignore
118
134
  - .rspec
135
+ - .travis.yml
119
136
  - Gemfile
120
137
  - Guardfile
121
138
  - LICENSE.txt