html_tables 0.0.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/.gitignore +15 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +42 -0
- data/Rakefile +2 -0
- data/html_tables.gemspec +22 -0
- data/lib/html_tables.rb +9 -0
- data/lib/html_tables/data_table.rb +78 -0
- data/lib/html_tables/data_table_helper.rb +104 -0
- data/lib/html_tables/format_for_output.rb +20 -0
- data/lib/html_tables/railtie.rb +9 -0
- data/lib/html_tables/version.rb +5 -0
- data/lib/html_tables/yielded_object.rb +45 -0
- metadata +123 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Fábio D. Batista
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# html_tables
|
2
|
+
|
3
|
+
This gem was extracted from some projects on my company. Everyone is welcome to use and improve upon.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'html_tables'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install html_tables
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
HAML example:
|
22
|
+
|
23
|
+
= data_table_for(@products, name: :products_table) do |t|
|
24
|
+
- t.column(:code, align: :center, width: '9em')
|
25
|
+
- t.column(:description) { |p| p.descriptions.first }
|
26
|
+
- t.column(:pricing)
|
27
|
+
- t.column(:quantity, width: '9em') do |p|
|
28
|
+
- if p.quantity == 0
|
29
|
+
%span.label.label-important.stack-right(title = 'Out of stock')
|
30
|
+
%i.icon-flag.icon-white
|
31
|
+
- else
|
32
|
+
.c= number_with_delimiter p.quantity
|
33
|
+
- t.column(:situation, align: :center, width: '9em')
|
34
|
+
- t.nodata 'No product found.'
|
35
|
+
|
36
|
+
## Contributing
|
37
|
+
|
38
|
+
1. Fork it
|
39
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
40
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
41
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
42
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/html_tables.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/html_tables/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Fábio David Batista"]
|
6
|
+
gem.email = ["fabio@elementarsistemas.com.br"]
|
7
|
+
gem.description = %q{Simple DSL for HTML data tables}
|
8
|
+
gem.summary = %q{This gem was extracted from some projects on my company. Everyone is welcome to use and improve upon.}
|
9
|
+
gem.homepage = "http://elementarsistemas.com.br/"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "html_tables"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = HtmlTables::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency 'i18n'
|
19
|
+
gem.add_dependency 'actionpack'
|
20
|
+
gem.add_dependency 'railties'
|
21
|
+
gem.add_dependency 'activerecord'
|
22
|
+
end
|
data/lib/html_tables.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'html_tables/version'
|
4
|
+
|
5
|
+
require 'html_tables/format_for_output'
|
6
|
+
require 'html_tables/yielded_object'
|
7
|
+
require 'html_tables/data_table'
|
8
|
+
require 'html_tables/data_table_helper'
|
9
|
+
require 'html_tables/railtie' if defined?(Rails::Railtie)
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module HtmlTables
|
4
|
+
class DataTable
|
5
|
+
attr_reader :collection, :options, :row_classes
|
6
|
+
attr_accessor :nodata_message, :item_url_block
|
7
|
+
|
8
|
+
def initialize(builder, collection, options = { })
|
9
|
+
@builder = builder
|
10
|
+
@collection = collection
|
11
|
+
@options = options
|
12
|
+
@row_classes = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def auto_generate_columns!
|
16
|
+
model.accessible_attributes.each do |attr|
|
17
|
+
col = model_columns[attr]
|
18
|
+
object_to_yield.column col.name unless col.nil?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def model
|
23
|
+
@model ||= collection.model_name.constantize if collection.respond_to?(:model_name)
|
24
|
+
@model ||= collection.first.try(:class)
|
25
|
+
@model ||= options[:name].to_s.singularize.constantize
|
26
|
+
end
|
27
|
+
|
28
|
+
def model_columns
|
29
|
+
@model_columns ||= ActiveSupport::HashWithIndifferentAccess[*model.columns.map { |c| [c.name, c] }.flatten]
|
30
|
+
end
|
31
|
+
|
32
|
+
def object_to_yield
|
33
|
+
@ctl ||= YieldedObject.new(self)
|
34
|
+
end
|
35
|
+
|
36
|
+
def columns
|
37
|
+
@columns ||= ActiveSupport::OrderedHash.new
|
38
|
+
end
|
39
|
+
|
40
|
+
def header_for(column_id)
|
41
|
+
return nil if column_id.nil?
|
42
|
+
return columns[column_id][:header] if columns[column_id][:header]
|
43
|
+
return @builder.content_tag(:i, nil, class: 'icon-check') if columns[column_id][:checkbox]
|
44
|
+
v ||= I18n.t(column_id, scope: [:tables, options[:name] || :default], raise: true) rescue nil
|
45
|
+
v ||= I18n.t(column_id, scope: [:tables, :default], raise: true) rescue nil
|
46
|
+
v ||= I18n.t(column_id, scope: [:activerecord, :attributes, model.model_name.underscore], raise: true) rescue nil
|
47
|
+
v ||= model_columns[column_id].human_name rescue nil
|
48
|
+
|
49
|
+
v || column_id.to_s.humanize
|
50
|
+
end
|
51
|
+
|
52
|
+
def url_for(item)
|
53
|
+
(item_url_block.call(item) unless item_url_block.nil?) || @builder.url_for(item) rescue nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def row_options_for(item)
|
57
|
+
h = { }
|
58
|
+
|
59
|
+
url = self.url_for(item)
|
60
|
+
h[:data] = { url: url } if url
|
61
|
+
|
62
|
+
classes = []
|
63
|
+
self.row_classes.each do |cls, opts|
|
64
|
+
next if opts[:if] && !test(item, &opts[:if])
|
65
|
+
next if opts[:unless] && test(item, &opts[:unless])
|
66
|
+
classes << cls
|
67
|
+
end
|
68
|
+
|
69
|
+
h[:class] = classes.uniq * ' ' unless classes.empty?
|
70
|
+
|
71
|
+
h
|
72
|
+
end
|
73
|
+
|
74
|
+
def test(item)
|
75
|
+
yield item
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module HtmlTables
|
4
|
+
module DataTableHelper
|
5
|
+
def data_table_for(collection, options = {})
|
6
|
+
t = DataTable.new(self, collection, options)
|
7
|
+
if block_given?
|
8
|
+
yield t.object_to_yield
|
9
|
+
else
|
10
|
+
t.auto_generate_columns!
|
11
|
+
end
|
12
|
+
|
13
|
+
cls = %w(table table-striped table-bordered)
|
14
|
+
cls << 'table-condensed' if options[:condensed]
|
15
|
+
content_tag(:table, class: cls) do
|
16
|
+
content_tag(:caption, options[:caption] || controller_name, class: ('hidden' unless options[:caption])) +
|
17
|
+
content_tag(:colgroup) do
|
18
|
+
b = ''.html_safe
|
19
|
+
t.columns.each do |_, opts|
|
20
|
+
col_opts = { }
|
21
|
+
col_opts[:style] = "width: #{opts[:width]}" if opts[:width]
|
22
|
+
b << content_tag(:col, col_opts) { }
|
23
|
+
end
|
24
|
+
b
|
25
|
+
end +
|
26
|
+
content_tag(:thead) do
|
27
|
+
content_tag(:tr) do
|
28
|
+
t.columns.map do |name, opts|
|
29
|
+
header_opts = {}
|
30
|
+
header_opts[:class] = 'check' if opts[:checkbox]
|
31
|
+
header_opts[:header_title] = opts[:header_title] if opts[:header_title]
|
32
|
+
content_tag(:th, t.header_for(name), header_opts)
|
33
|
+
end.join.html_safe
|
34
|
+
end
|
35
|
+
end +
|
36
|
+
content_tag(:tbody) do
|
37
|
+
b = ''.html_safe
|
38
|
+
if collection.each do |item|
|
39
|
+
b << content_tag(:tr, t.row_options_for(item)) do
|
40
|
+
t.columns.map do |name, opts|
|
41
|
+
render_td(item, name, opts)
|
42
|
+
end.join.html_safe
|
43
|
+
end
|
44
|
+
end.size == 0 then
|
45
|
+
b << content_tag(:tr, class: 'nodata') do
|
46
|
+
content_tag(:td, colspan: t.columns.size) { t.nodata_message }
|
47
|
+
end unless t.nodata_message.nil?
|
48
|
+
end
|
49
|
+
b
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def render_td(item, column, opts)
|
55
|
+
td_options = {}
|
56
|
+
|
57
|
+
if opts[:align] == :center
|
58
|
+
td_options[:class] = 'c'
|
59
|
+
end
|
60
|
+
|
61
|
+
if opts[:title]
|
62
|
+
td_options[:title] = if opts[:title].respond_to?(:call)
|
63
|
+
opts[:title].call(item)
|
64
|
+
else
|
65
|
+
opts[:title].to_s
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
v = if opts[:checkbox]
|
70
|
+
checked = nil
|
71
|
+
checked = opts[:block].call(item) if opts[:block]
|
72
|
+
ck_opts = opts.select { |k, _| [:disabled].include?(k) }
|
73
|
+
check_box_tag "#{column}[]", item.id, checked, ck_opts
|
74
|
+
elsif opts[:radio]
|
75
|
+
radio_button_tag "#{column}[]", item.id
|
76
|
+
elsif opts[:block]
|
77
|
+
capture(item, &opts[:block])
|
78
|
+
else
|
79
|
+
tmp = item.send(column)
|
80
|
+
tmp = item.send("#{column}_text") rescue tmp if tmp.is_a?(Symbol)
|
81
|
+
tmp
|
82
|
+
end
|
83
|
+
|
84
|
+
if ::Rails.env.development? && v.is_a?(ActiveRecord::Base)
|
85
|
+
btn = content_tag(:div, class: 'entity-shortcut') do
|
86
|
+
link_to(url_for(v), class: 'btn btn-small') do
|
87
|
+
content_tag(:i, nil, class: 'icon-share')
|
88
|
+
end
|
89
|
+
end rescue nil
|
90
|
+
end
|
91
|
+
|
92
|
+
v = if v.is_a?(Enumerable)
|
93
|
+
v.inject(''.html_safe) { |b, i| b << ', ' unless b.blank?; b << i.format_for_output }
|
94
|
+
else
|
95
|
+
v.format_for_output
|
96
|
+
end
|
97
|
+
v = v.to_s unless v.nil? || v.is_a?(String)
|
98
|
+
|
99
|
+
v = ''.html_safe << btn << v if btn
|
100
|
+
|
101
|
+
content_tag(:td, v, td_options)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module HtmlTables
|
4
|
+
module FormatForOutput
|
5
|
+
def format_for_output
|
6
|
+
case self
|
7
|
+
when Date, Time, DateTime
|
8
|
+
I18n.l(self, format: :short)
|
9
|
+
when ActiveRecord::Base
|
10
|
+
self.to_label(:short)
|
11
|
+
when TrueClass, FalseClass
|
12
|
+
I18n.t(self.to_s)
|
13
|
+
else
|
14
|
+
self
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
Object.send(:include, HtmlTables::FormatForOutput)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module HtmlTables
|
4
|
+
class YieldedObject
|
5
|
+
attr_reader :t
|
6
|
+
|
7
|
+
def initialize(data_table)
|
8
|
+
@t = data_table
|
9
|
+
end
|
10
|
+
|
11
|
+
# Adds a checkbox column to the DataTable.
|
12
|
+
# If a block is supplied, it is used to determine the initial state of the checkbox.
|
13
|
+
def checkbox(id = nil, options = { }, &block)
|
14
|
+
options[:block] = block if block_given?
|
15
|
+
t.columns[id] = options.reverse_merge! checkbox: true, align: :center
|
16
|
+
end
|
17
|
+
|
18
|
+
# Adds a radio button column to the DataTable.
|
19
|
+
def radio(id = nil, options = { })
|
20
|
+
t.columns[id] = options.reverse_merge! radio: true, align: :center
|
21
|
+
end
|
22
|
+
|
23
|
+
# Adds a regular column to the DataTable.
|
24
|
+
def column(id, options = { }, &block)
|
25
|
+
options[:block] = block if block_given?
|
26
|
+
t.columns[id] = options
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
|
30
|
+
# Sets the 'no-data' message. If not set, no message will be displayed when there's no records to show.
|
31
|
+
def nodata(msg)
|
32
|
+
t.nodata_message = msg
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def item_url(&block)
|
37
|
+
t.item_url_block = block
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def row_class(cls, options = { })
|
42
|
+
t.row_classes << [cls, options]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: html_tables
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Fábio David Batista
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-13 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: i18n
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: actionpack
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: railties
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: activerecord
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: Simple DSL for HTML data tables
|
79
|
+
email:
|
80
|
+
- fabio@elementarsistemas.com.br
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- Gemfile
|
87
|
+
- LICENSE
|
88
|
+
- README.md
|
89
|
+
- Rakefile
|
90
|
+
- html_tables.gemspec
|
91
|
+
- lib/html_tables.rb
|
92
|
+
- lib/html_tables/data_table.rb
|
93
|
+
- lib/html_tables/data_table_helper.rb
|
94
|
+
- lib/html_tables/format_for_output.rb
|
95
|
+
- lib/html_tables/railtie.rb
|
96
|
+
- lib/html_tables/version.rb
|
97
|
+
- lib/html_tables/yielded_object.rb
|
98
|
+
homepage: http://elementarsistemas.com.br/
|
99
|
+
licenses: []
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options: []
|
102
|
+
require_paths:
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
none: false
|
112
|
+
requirements:
|
113
|
+
- - ! '>='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
requirements: []
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 1.8.24
|
119
|
+
signing_key:
|
120
|
+
specification_version: 3
|
121
|
+
summary: This gem was extracted from some projects on my company. Everyone is welcome
|
122
|
+
to use and improve upon.
|
123
|
+
test_files: []
|