trenni-formatters 0.5.3 → 1.0.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.
- checksums.yaml +4 -4
- data/README.md +9 -5
- data/lib/trenni/formatters/format/markdown.rb +34 -0
- data/lib/trenni/formatters/format/text.rb +50 -0
- data/lib/trenni/formatters/format/time.rb +39 -0
- data/lib/trenni/formatters/formatter.rb +15 -13
- data/lib/trenni/formatters/html/definition_list_form.rb +32 -13
- data/lib/trenni/formatters/html/form_formatter.rb +58 -11
- data/lib/trenni/formatters/html/option_select.rb +7 -7
- data/lib/trenni/formatters/html/{table_select.rb → radio_select.rb} +1 -2
- data/lib/trenni/formatters/version.rb +1 -1
- data/spec/trenni/formatters/form_formatter_spec.rb +81 -12
- data/spec/trenni/formatters/formatters_spec.rb +23 -11
- data/spec/trenni/formatters/html/option_select_spec.rb +43 -3
- data/spec/trenni/formatters/html/radio_select_spec.rb +46 -0
- data/trenni-formatters.gemspec +3 -1
- metadata +25 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38446eb1ee4817cddda1a893f8ac201d994102cd
|
4
|
+
data.tar.gz: 0a5bdcf731d0aab78c21cb8ec379c385aff4c561
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c764c5ed7624b752f6fa3c1171db00f945bb1c449bc115cc06cdd9fe849c4bee7d0124e9ff291fe779e3944d75b4449d7e19b093454cbfb49b5236a8760ceb5
|
7
|
+
data.tar.gz: 693f5abca9f92b155338aa2a7d2bbd0a1f9c61cfec40b5d910e5f226e2333cf5a885524075b9bffb8d42c7a8fd3c3bb421b7755dff4418e20e22eea2d835f278
|
data/README.md
CHANGED
@@ -11,19 +11,23 @@ formatting needs.
|
|
11
11
|
[](https://codeclimate.com/github/ioquatix/trenni-formatters)
|
12
12
|
[](https://coveralls.io/r/ioquatix/trenni-formatters)
|
13
13
|
|
14
|
+
## Motivation
|
15
|
+
|
16
|
+
`Trenni::Formatters` was a library extracted from [Financier](https://github.com/ioquatix/financier) which is a CouchDB backed invoicing system, itself, derived from an old Rails app. I was a bit envious of `form_for` in terms of the ease of generating forms, but found that it wasn't very extendable. I also found myself generating code to format model data as rich HTML. `Trenni::Formatters` attempts to be an easily extendable formatting module which can generate rich text, links and HTML.
|
17
|
+
|
14
18
|
## Installation
|
15
19
|
|
16
20
|
Add this line to your application's Gemfile:
|
17
21
|
|
18
|
-
|
22
|
+
gem 'trenni-formatters'
|
19
23
|
|
20
24
|
And then execute:
|
21
25
|
|
22
|
-
|
26
|
+
$ bundle
|
23
27
|
|
24
28
|
Or install it yourself as:
|
25
29
|
|
26
|
-
|
30
|
+
$ gem install trenni-formatters
|
27
31
|
|
28
32
|
## Usage
|
29
33
|
|
@@ -36,9 +40,9 @@ a mapping corresponding to the objects type:
|
|
36
40
|
"String: #{value}"
|
37
41
|
end
|
38
42
|
|
39
|
-
|
43
|
+
expect(formatter.format("foobar")).to be == "String: foobar"
|
40
44
|
|
41
|
-
For more examples please see `
|
45
|
+
For more examples please see `spec/`.
|
42
46
|
|
43
47
|
## Contributing
|
44
48
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'sanitize'
|
22
|
+
require 'kramdown'
|
23
|
+
|
24
|
+
module Trenni::Formatters::Format
|
25
|
+
module Markdown
|
26
|
+
def markdown(text)
|
27
|
+
config = Sanitize::Config::BASIC.dup
|
28
|
+
|
29
|
+
config[:elements] += ['h1', 'h2', 'h3']
|
30
|
+
|
31
|
+
Sanitize.clean(Kramdown::Document.new(text).to_html, config)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'trenni/strings'
|
22
|
+
require 'mapping/model'
|
23
|
+
|
24
|
+
module Trenni::Formatters::Format
|
25
|
+
module Text
|
26
|
+
def truncated_text(content, options = {}, &block)
|
27
|
+
if content
|
28
|
+
length = options.fetch(:length, 30)
|
29
|
+
|
30
|
+
content = self.class.truncate_text(content, length, options)
|
31
|
+
|
32
|
+
return self.format(content)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.truncate_text(text, truncate_at, options = {})
|
37
|
+
return text.dup unless text.length > truncate_at
|
38
|
+
|
39
|
+
options[:omission] ||= '...'
|
40
|
+
length_with_room_for_omission = truncate_at - options[:omission].length
|
41
|
+
stop = if options[:separator]
|
42
|
+
text.rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
|
43
|
+
else
|
44
|
+
length_with_room_for_omission
|
45
|
+
end
|
46
|
+
|
47
|
+
"#{text[0...stop]}#{options[:omission]}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'trenni/strings'
|
22
|
+
require 'mapping/model'
|
23
|
+
|
24
|
+
module Trenni::Formatters::Format
|
25
|
+
module Time
|
26
|
+
def included(base)
|
27
|
+
base.map(Time) do |object, options|
|
28
|
+
# Ensure we display the time in localtime, and show the year if it is different:
|
29
|
+
if object.localtime.year != Time.now.year
|
30
|
+
object.localtime.strftime("%B %-d, %-l:%M%P, %Y")
|
31
|
+
else
|
32
|
+
object.localtime.strftime("%B %-d, %-l:%M%P")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
@@ -19,24 +19,30 @@
|
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
21
|
require 'trenni/strings'
|
22
|
+
require 'mapping/model'
|
22
23
|
|
23
24
|
module Trenni
|
24
25
|
module Formatters
|
25
|
-
class Formatter
|
26
|
+
class Formatter < Mapping::Model
|
26
27
|
def initialize(options = {})
|
27
28
|
@options = options
|
28
|
-
|
29
|
+
end
|
30
|
+
|
31
|
+
def format_unspecified(object, options)
|
32
|
+
if object
|
33
|
+
Strings::to_html(object.to_s)
|
34
|
+
else
|
35
|
+
options[:blank] || ""
|
36
|
+
end
|
29
37
|
end
|
30
38
|
|
31
39
|
def format(object, options = {})
|
32
|
-
|
33
|
-
|
40
|
+
method_name = self.method_for_mapping(object)
|
41
|
+
|
42
|
+
if self.respond_to?(method_name)
|
43
|
+
self.send(method_name, object, options)
|
34
44
|
else
|
35
|
-
|
36
|
-
Strings::to_html(object.to_s)
|
37
|
-
else
|
38
|
-
options[:blank] || ""
|
39
|
-
end
|
45
|
+
format_unspecified(object, options)
|
40
46
|
end
|
41
47
|
end
|
42
48
|
|
@@ -45,10 +51,6 @@ module Trenni
|
|
45
51
|
def [] key
|
46
52
|
@options[key]
|
47
53
|
end
|
48
|
-
|
49
|
-
def for(klass, &block)
|
50
|
-
@formatters[klass] = block
|
51
|
-
end
|
52
54
|
end
|
53
55
|
end
|
54
56
|
end
|
@@ -34,8 +34,14 @@ module Trenni
|
|
34
34
|
options = @options.merge(options)
|
35
35
|
|
36
36
|
Builder.fragment do |builder|
|
37
|
-
builder.inline(:dt)
|
38
|
-
|
37
|
+
builder.inline(:dt) do
|
38
|
+
builder.text title_for(options)
|
39
|
+
|
40
|
+
if details = details_for(options)
|
41
|
+
builder.inline(:small) { builder.text details }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
39
45
|
builder.inline(:dd) do
|
40
46
|
builder.tag :input, input_attributes_for(options)
|
41
47
|
end
|
@@ -50,7 +56,9 @@ module Trenni
|
|
50
56
|
builder.inline(:dt) { builder.text title_for(options) }
|
51
57
|
|
52
58
|
builder.inline(:dd) do
|
53
|
-
builder.
|
59
|
+
builder.inline :output, output_attributes_for(options) do
|
60
|
+
builder.text value_for(options)
|
61
|
+
end
|
54
62
|
end
|
55
63
|
end
|
56
64
|
end
|
@@ -60,7 +68,13 @@ module Trenni
|
|
60
68
|
options = @options.merge(options)
|
61
69
|
|
62
70
|
Builder.fragment do |builder|
|
63
|
-
builder.
|
71
|
+
builder.tag(:dt) do
|
72
|
+
builder.text title_for(options)
|
73
|
+
|
74
|
+
if details = details_for(options)
|
75
|
+
builder.inline(:small) { builder.text details }
|
76
|
+
end
|
77
|
+
end
|
64
78
|
|
65
79
|
builder.inline(:dd) do
|
66
80
|
builder.tag :textarea, textarea_attributes_for(options) do
|
@@ -77,8 +91,11 @@ module Trenni
|
|
77
91
|
Builder.fragment do |builder|
|
78
92
|
builder.tag(:dd) do
|
79
93
|
builder.tag :input, :type => :hidden, :name => name_for(options), :value => 'false'
|
80
|
-
builder.
|
81
|
-
|
94
|
+
builder.inline(:label) do
|
95
|
+
builder.tag :input, checkbox_attributes_for(options)
|
96
|
+
# We would like a little bit of whitespace between the checkbox and the title.
|
97
|
+
builder.text " " + title_for(options)
|
98
|
+
end
|
82
99
|
end
|
83
100
|
end
|
84
101
|
end
|
@@ -86,13 +103,8 @@ module Trenni
|
|
86
103
|
# A submission button
|
87
104
|
def submit(options = {})
|
88
105
|
options = @options.merge(options)
|
106
|
+
options[:title] ||= submit_title_for(options)
|
89
107
|
|
90
|
-
if title = title_for(options)
|
91
|
-
options[:title] = title
|
92
|
-
else
|
93
|
-
options[:title] ||= new_record? ? 'Create' : 'Update'
|
94
|
-
end
|
95
|
-
|
96
108
|
Builder.fragment do |builder|
|
97
109
|
builder.tag :input, submit_attributes_for(options)
|
98
110
|
end
|
@@ -103,7 +115,14 @@ module Trenni
|
|
103
115
|
buffer = Trenni::Template.buffer(block.binding)
|
104
116
|
|
105
117
|
buffer << Builder.fragment do |builder|
|
106
|
-
builder.inline(:dt)
|
118
|
+
builder.inline(:dt) do
|
119
|
+
builder.text title_for(options)
|
120
|
+
|
121
|
+
if details = details_for(options)
|
122
|
+
builder.inline(:small) { builder.text details }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
107
126
|
builder.tag(:dd) do
|
108
127
|
klass.call(self, options, builder, &block)
|
109
128
|
end
|
@@ -37,10 +37,15 @@ module Trenni
|
|
37
37
|
return !object.saved?
|
38
38
|
end
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
|
+
# Any additional details relating to a field (e.g. explanation text)
|
42
|
+
def details_for(options)
|
43
|
+
options[:details]
|
44
|
+
end
|
45
|
+
|
41
46
|
# The name of the field, used for the name attribute of an input.
|
42
47
|
def name_for(options)
|
43
|
-
|
48
|
+
options[:name] || options[:field]
|
44
49
|
end
|
45
50
|
|
46
51
|
def field_for(options)
|
@@ -49,17 +54,21 @@ module Trenni
|
|
49
54
|
|
50
55
|
# A title is a text string that will be displayed next to or on top of the control to describe it or its value:
|
51
56
|
def title_for(options)
|
52
|
-
title = options[:title]
|
53
|
-
|
54
|
-
|
55
|
-
field_name = field_for(options)
|
57
|
+
if title = options[:title]
|
58
|
+
return title
|
59
|
+
end
|
56
60
|
|
57
|
-
#
|
58
|
-
|
61
|
+
# Generate a title from a field name:
|
62
|
+
if field_name = field_for(options)
|
63
|
+
# Remove postfix "_id" or "_ids":
|
64
|
+
return Strings::to_title(field_name.to_s.sub(/_ids?/, ''))
|
65
|
+
end
|
59
66
|
end
|
60
67
|
|
61
68
|
def object_value_for(options)
|
62
|
-
options[:object]
|
69
|
+
if object = options[:object] and field = field_for(options)
|
70
|
+
object.send(field)
|
71
|
+
end
|
63
72
|
end
|
64
73
|
|
65
74
|
def raw_value_for(options)
|
@@ -71,7 +80,9 @@ module Trenni
|
|
71
80
|
|
72
81
|
# The value of the field.
|
73
82
|
def value_for(options)
|
74
|
-
|
83
|
+
if value = raw_value_for(options)
|
84
|
+
self.format(value, options)
|
85
|
+
end
|
75
86
|
end
|
76
87
|
|
77
88
|
def pattern_for(options)
|
@@ -157,7 +168,11 @@ module Trenni
|
|
157
168
|
:value => title_for(options),
|
158
169
|
}
|
159
170
|
end
|
160
|
-
|
171
|
+
|
172
|
+
def submit_title_for(options)
|
173
|
+
title_for(options) || (new_record? ? 'Create' : 'Update')
|
174
|
+
end
|
175
|
+
|
161
176
|
def hidden_attributes_for(options)
|
162
177
|
return {
|
163
178
|
:type => options[:type] || 'hidden',
|
@@ -176,6 +191,38 @@ module Trenni
|
|
176
191
|
builder.tag :input, hidden_attributes_for(options)
|
177
192
|
end
|
178
193
|
end
|
194
|
+
|
195
|
+
def button_attributes_for(options)
|
196
|
+
return {
|
197
|
+
:type => options[:type] || 'submit',
|
198
|
+
:name => name_for(options),
|
199
|
+
:id => options[:id],
|
200
|
+
:class => options[:class],
|
201
|
+
:disabled => options[:disabled],
|
202
|
+
:value => value_for(options),
|
203
|
+
}
|
204
|
+
end
|
205
|
+
|
206
|
+
def button_title_for(options)
|
207
|
+
type = options.fetch(:type, 'submit').to_sym
|
208
|
+
|
209
|
+
if type == :submit
|
210
|
+
submit_title_for(options)
|
211
|
+
else
|
212
|
+
title_for(options) || Strings::to_title(type.to_s)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# A hidden field.
|
217
|
+
def button(options = {})
|
218
|
+
options = @options.merge(options)
|
219
|
+
|
220
|
+
Builder.fragment do |builder|
|
221
|
+
builder.inline :button, button_attributes_for(options) do
|
222
|
+
builder.text button_title_for(options)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
179
226
|
end
|
180
227
|
end
|
181
228
|
end
|
@@ -42,13 +42,13 @@ module Trenni
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def name_for(options)
|
45
|
-
name = @formatter.name_for(options)
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
if name = @formatter.name_for(options)
|
46
|
+
if options[:multiple]
|
47
|
+
name = "#{name}[]"
|
48
|
+
end
|
49
|
+
|
50
|
+
return name
|
49
51
|
end
|
50
|
-
|
51
|
-
return name
|
52
52
|
end
|
53
53
|
|
54
54
|
def value_for(options)
|
@@ -85,7 +85,7 @@ module Trenni
|
|
85
85
|
end
|
86
86
|
|
87
87
|
def group(options = {}, &block)
|
88
|
-
Builder.fragment do |builder|
|
88
|
+
Builder.fragment(@builder) do |builder|
|
89
89
|
builder.tag :optgroup, group_attributes_for(options) do
|
90
90
|
if options[:optional]
|
91
91
|
item(:title => '', :value => '', :builder => builder)
|
@@ -24,7 +24,7 @@ module Trenni
|
|
24
24
|
module Formatters
|
25
25
|
module HTML
|
26
26
|
# Table based select boxes using per-row checkboxes.
|
27
|
-
class
|
27
|
+
class RadioSelect
|
28
28
|
def self.call(formatter, options, builder, &block)
|
29
29
|
instance = self.new(formatter, options, builder)
|
30
30
|
|
@@ -97,7 +97,6 @@ module Trenni
|
|
97
97
|
end
|
98
98
|
end
|
99
99
|
end
|
100
|
-
|
101
100
|
end
|
102
101
|
end
|
103
102
|
end
|
@@ -20,8 +20,6 @@
|
|
20
20
|
|
21
21
|
require 'trenni/formatters'
|
22
22
|
require 'trenni/formatters/html/definition_list_form'
|
23
|
-
require 'trenni/formatters/html/option_select'
|
24
|
-
require 'trenni/formatters/html/table_select'
|
25
23
|
|
26
24
|
module Trenni::Formatters::FormFormatterSpec
|
27
25
|
class FormFormatter < Trenni::Formatters::Formatter
|
@@ -32,8 +30,8 @@ module Trenni::Formatters::FormFormatterSpec
|
|
32
30
|
let(:formatter) {FormFormatter.new(:object => double(:bar => 10))}
|
33
31
|
|
34
32
|
it "should generate form" do
|
35
|
-
|
36
|
-
expect(
|
33
|
+
result = formatter.input(:field => :bar)
|
34
|
+
expect(result).to be == %Q{<dt>Bar</dt>\n<dd><input name="bar" value="10"/></dd>}
|
37
35
|
end
|
38
36
|
|
39
37
|
it "should have default value" do
|
@@ -42,8 +40,8 @@ module Trenni::Formatters::FormFormatterSpec
|
|
42
40
|
end
|
43
41
|
|
44
42
|
it "should have a different title" do
|
45
|
-
|
46
|
-
expect(
|
43
|
+
result = formatter.input(:field => :bar, :title => "Title")
|
44
|
+
expect(result).to be == %Q{<dt>Title</dt>\n<dd><input name="bar" value="10"/></dd>}
|
47
45
|
end
|
48
46
|
end
|
49
47
|
|
@@ -57,8 +55,8 @@ module Trenni::Formatters::FormFormatterSpec
|
|
57
55
|
expect(attributes[:max]).to be == 20
|
58
56
|
expect(attributes[:step]).to be == 2
|
59
57
|
|
60
|
-
|
61
|
-
expect(
|
58
|
+
result = formatter.input(:field => :bar, :min => 10)
|
59
|
+
expect(result).to be == %Q{<dt>Bar</dt>\n<dd><input name="bar" value="10" min="10"/></dd>}
|
62
60
|
end
|
63
61
|
|
64
62
|
it "should not specify required, readonly or disabled" do
|
@@ -79,16 +77,87 @@ module Trenni::Formatters::FormFormatterSpec
|
|
79
77
|
attributes = formatter.checkbox_attributes_for(:value => true)
|
80
78
|
expect(attributes[:checked]).to be true
|
81
79
|
|
82
|
-
|
83
|
-
expect(
|
80
|
+
result = formatter.checkbox(:field => :bob)
|
81
|
+
expect(result).to be == %Q{<dd>\n\t<input type="hidden" name="bob" value="false"/>\n\t<label><input type="checkbox" name="bob" value="true" checked/> Bob</label>\n</dd>}
|
84
82
|
end
|
85
83
|
|
86
84
|
it "should generate unchecked checkbox" do
|
87
85
|
attributes = formatter.checkbox_attributes_for(:value => false)
|
88
86
|
expect(attributes[:checked]).to be nil
|
89
87
|
|
90
|
-
|
91
|
-
expect(
|
88
|
+
result = formatter.checkbox(:field => :dole)
|
89
|
+
expect(result).to be == %Q{<dd>\n\t<input type="hidden" name="dole" value="false"/>\n\t<label><input type="checkbox" name="dole" value="true"/> Dole</label>\n</dd>}
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe '<input type="hidden">' do
|
94
|
+
let(:formatter) {FormFormatter.new(:object => double(age: 20))}
|
95
|
+
|
96
|
+
it "should generate hidden field" do
|
97
|
+
result = formatter.hidden(:field => :age)
|
98
|
+
expect(result).to be == %Q{<input type="hidden" name="age" value="20"/>}
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should escape characters correctly" do
|
102
|
+
result = formatter.submit
|
103
|
+
expect(result).to be == %Q{<input type="submit" value="Update"/>}
|
104
|
+
end
|
105
|
+
|
106
|
+
it "can have custom title" do
|
107
|
+
result = formatter.submit(title: 'Alice')
|
108
|
+
expect(result).to be == %Q{<input type="submit" value="Alice"/>}
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe '<input type="submit">' do
|
113
|
+
let(:new_record_formatter) {FormFormatter.new(:object => double(new_record?: true))}
|
114
|
+
let(:formatter) {FormFormatter.new(:object => double(new_record?: false))}
|
115
|
+
|
116
|
+
it "should have correct title for new_record?" do
|
117
|
+
result = new_record_formatter.submit
|
118
|
+
expect(result).to be == %Q{<input type="submit" value="Create"/>}
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should escape characters correctly" do
|
122
|
+
result = formatter.submit
|
123
|
+
expect(result).to be == %Q{<input type="submit" value="Update"/>}
|
124
|
+
end
|
125
|
+
|
126
|
+
it "can have custom title" do
|
127
|
+
result = formatter.submit(title: 'Alice')
|
128
|
+
expect(result).to be == %Q{<input type="submit" value="Alice"/>}
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "<textarea>" do
|
133
|
+
let(:formatter) {FormFormatter.new(:object => double(details: "foo<bar>"))}
|
134
|
+
|
135
|
+
it "should escape characters correctly" do
|
136
|
+
result = formatter.textarea(:field => :details)
|
137
|
+
expect(result).to be == %Q{<dt>\n\tDetails\n</dt>\n<dd><textarea name=\"details\">foo<bar></textarea></dd>}
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "<output>" do
|
142
|
+
let(:formatter) {FormFormatter.new(:object => double(bar: 10, bob: true, dole: false))}
|
143
|
+
|
144
|
+
it "should show output value" do
|
145
|
+
result = formatter.output(:field => :bar)
|
146
|
+
expect(result).to be == %Q{<dt>Bar</dt>\n<dd><output name=\"bar\">10</output></dd>}
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should show output value" do
|
150
|
+
result = formatter.output(:name => :total)
|
151
|
+
expect(result).to be == %Q{<dt></dt>\n<dd><output name=\"total\"></output></dd>}
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "<button>" do
|
156
|
+
let(:formatter) {FormFormatter.new}
|
157
|
+
|
158
|
+
it "should generate reset button" do
|
159
|
+
result = formatter.button(:type => :reset)
|
160
|
+
expect(result).to be == %Q{<button type="reset">Reset</button>}
|
92
161
|
end
|
93
162
|
end
|
94
163
|
end
|
@@ -21,25 +21,37 @@
|
|
21
21
|
require 'trenni/formatters'
|
22
22
|
|
23
23
|
module Trenni::FormattersSpec
|
24
|
-
|
25
|
-
|
24
|
+
class TestFormatter < Trenni::Formatters::Formatter
|
25
|
+
def initialize(*)
|
26
26
|
@count = 0
|
27
|
-
|
27
|
+
|
28
|
+
super
|
29
|
+
end
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
attr :count
|
32
|
+
|
33
|
+
map(String) do |value, options|
|
34
|
+
@count += 1
|
35
|
+
|
36
|
+
"String: #{value}"
|
33
37
|
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe Trenni::Formatters do
|
41
|
+
let(:test_formatter) {TestFormatter.new(foo: :bar)}
|
34
42
|
|
35
43
|
it "should format string" do
|
36
|
-
expect(
|
37
|
-
expect(
|
44
|
+
expect(test_formatter.format("foobar")).to be == "String: foobar"
|
45
|
+
expect(test_formatter.count).to be == 1
|
38
46
|
end
|
39
47
|
|
40
48
|
it "should format numbers" do
|
41
|
-
expect(
|
42
|
-
expect(
|
49
|
+
expect(test_formatter.format(10)).to be == "10"
|
50
|
+
expect(test_formatter.count).to be == 0
|
51
|
+
end
|
52
|
+
|
53
|
+
it "has options" do
|
54
|
+
expect(test_formatter[:foo]).to be == :bar
|
43
55
|
end
|
44
56
|
end
|
45
57
|
end
|
@@ -19,6 +19,7 @@
|
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
21
|
require 'trenni/formatters'
|
22
|
+
require 'trenni/formatters/html/option_select'
|
22
23
|
|
23
24
|
module Trenni::Formatters::HTML::OptionSelectSpec
|
24
25
|
class FormFormatter < Trenni::Formatters::Formatter
|
@@ -31,10 +32,9 @@ module Trenni::Formatters::HTML::OptionSelectSpec
|
|
31
32
|
|
32
33
|
describe Trenni::Formatters::HTML::OptionSelect do
|
33
34
|
let(:formatter) {FormFormatter.new(:object => double(:bar => 10))}
|
35
|
+
let(:_out) {Array.new}
|
34
36
|
|
35
|
-
it "should
|
36
|
-
_out = []
|
37
|
-
|
37
|
+
it "should list items" do
|
38
38
|
formatter.select :field => :bar do |select|
|
39
39
|
_out << select.item(:title => "A", :value => 0)
|
40
40
|
_out << select.item(:title => "B", :value => 10)
|
@@ -42,5 +42,45 @@ module Trenni::Formatters::HTML::OptionSelectSpec
|
|
42
42
|
|
43
43
|
expect(_out.join).to be == "<dt>Bar</dt>\n<dd>\n\t<select name=\"bar\">\n\t\t<option value=\"0\">A</option><option value=\"10\" selected>B</option>\n\t</select>\n</dd>"
|
44
44
|
end
|
45
|
+
|
46
|
+
it "should list items for multiple selection" do
|
47
|
+
formatter.select :field => :bar, multiple: true do |select|
|
48
|
+
_out << select.item(:title => "A", :value => 0)
|
49
|
+
_out << select.item(:title => "B", :value => 10)
|
50
|
+
end
|
51
|
+
|
52
|
+
expect(_out.join).to be == "<dt>Bar</dt>\n<dd>\n\t<select name=\"bar[]\" multiple>\n\t\t<option value=\"0\">A</option><option value=\"10\" selected>B</option>\n\t</select>\n</dd>"
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should add optional item" do
|
56
|
+
formatter.select :field => :bar, optional: true do |select|
|
57
|
+
_out << select.item(:title => "A", :value => 0)
|
58
|
+
_out << select.item(:title => "B", :value => 10)
|
59
|
+
end
|
60
|
+
|
61
|
+
expect(_out.join).to be == "<dt>Bar</dt>\n<dd>\n\t<select name=\"bar\">\n\t\t<option value=\"\"></option>\t\t<option value=\"0\">A</option><option value=\"10\" selected>B</option>\n\t</select>\n</dd>"
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should add optional item in group" do
|
65
|
+
formatter.select :field => :bar do |select|
|
66
|
+
select.group(title: 'group', optional: true) do
|
67
|
+
_out << select.item(:title => "A", :value => 0)
|
68
|
+
end
|
69
|
+
_out << select.item(:title => "B", :value => 10)
|
70
|
+
end
|
71
|
+
|
72
|
+
expect(_out.join).to be == "<dt>Bar</dt>\n<dd>\n\t<select name=\"bar\">\n\t\t<optgroup label=\"group\">\n\t\t\t<option value=\"\"></option>\t\t\t<option value=\"0\">A</option>\n\t\t</optgroup>\t\t<option value=\"10\" selected>B</option>\n\t</select>\n</dd>"
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should add a group" do
|
76
|
+
formatter.select :field => :bar do |select|
|
77
|
+
select.group(title: 'group') do
|
78
|
+
_out << select.item(:title => "A", :value => 0)
|
79
|
+
end
|
80
|
+
_out << select.item(:title => "B", :value => 10)
|
81
|
+
end
|
82
|
+
|
83
|
+
expect(_out.join).to be == "<dt>Bar</dt>\n<dd>\n\t<select name=\"bar\">\n\t\t<optgroup label=\"group\">\n\t\t\t<option value=\"0\">A</option>\n\t\t</optgroup>\t\t<option value=\"10\" selected>B</option>\n\t</select>\n</dd>"
|
84
|
+
end
|
45
85
|
end
|
46
86
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Copyright, 2014, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'trenni/formatters'
|
22
|
+
require 'trenni/formatters/html/radio_select'
|
23
|
+
|
24
|
+
module Trenni::Formatters::HTML::RadioSelectSpec
|
25
|
+
class FormFormatter < Trenni::Formatters::Formatter
|
26
|
+
include Trenni::Formatters::HTML::DefinitionListForm
|
27
|
+
|
28
|
+
def select(options = {}, &block)
|
29
|
+
element(Trenni::Formatters::HTML::RadioSelect, options, &block)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe Trenni::Formatters::HTML::RadioSelect do
|
34
|
+
let(:formatter) {FormFormatter.new(:object => double(:bar => 10))}
|
35
|
+
let(:_out) {Array.new}
|
36
|
+
|
37
|
+
it "should list items" do
|
38
|
+
formatter.select :field => :bar do |select|
|
39
|
+
_out << select.item(:title => "A", :value => 0)
|
40
|
+
_out << select.item(:title => "B", :value => 10)
|
41
|
+
end
|
42
|
+
|
43
|
+
expect(_out.join).to be == %Q{<dt>Bar</dt>\n<dd>\n\t<table>\n\t\t<tbody>\n\t\t\t<tr>\n\t\t\t\t<td class="handle"><input type="radio" name="bar" value="0"/></td>\n\t\t\t\t<td class="item">A</td>\n\t\t\t</tr><tr>\n\t\t\t\t<td class="handle"><input type="radio" name="bar" value="10"/></td>\n\t\t\t\t<td class="item">B</td>\n\t\t\t</tr>\n\t\t</tbody>\n\t</table>\n</dd>}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/trenni-formatters.gemspec
CHANGED
@@ -24,7 +24,9 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
25
25
|
spec.require_paths = ["lib"]
|
26
26
|
|
27
|
-
spec.add_dependency "trenni", "~> 1.
|
27
|
+
spec.add_dependency "trenni", "~> 1.5.0"
|
28
|
+
|
29
|
+
spec.add_dependency "mapping", "~> 1.0.0"
|
28
30
|
|
29
31
|
spec.add_development_dependency "bundler", "~> 1.3"
|
30
32
|
spec.add_development_dependency "rspec", "~> 3.4.0"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trenni-formatters
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: trenni
|
@@ -16,14 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.5.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: 1.5.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mapping
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.0.0
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,15 +98,19 @@ files:
|
|
84
98
|
- README.md
|
85
99
|
- Rakefile
|
86
100
|
- lib/trenni/formatters.rb
|
101
|
+
- lib/trenni/formatters/format/markdown.rb
|
102
|
+
- lib/trenni/formatters/format/text.rb
|
103
|
+
- lib/trenni/formatters/format/time.rb
|
87
104
|
- lib/trenni/formatters/formatter.rb
|
88
105
|
- lib/trenni/formatters/html/definition_list_form.rb
|
89
106
|
- lib/trenni/formatters/html/form_formatter.rb
|
90
107
|
- lib/trenni/formatters/html/option_select.rb
|
91
|
-
- lib/trenni/formatters/html/
|
108
|
+
- lib/trenni/formatters/html/radio_select.rb
|
92
109
|
- lib/trenni/formatters/version.rb
|
93
110
|
- spec/trenni/formatters/form_formatter_spec.rb
|
94
111
|
- spec/trenni/formatters/formatters_spec.rb
|
95
112
|
- spec/trenni/formatters/html/option_select_spec.rb
|
113
|
+
- spec/trenni/formatters/html/radio_select_spec.rb
|
96
114
|
- trenni-formatters.gemspec
|
97
115
|
homepage: https://github.com/ioquatix/trenni-formatters
|
98
116
|
licenses: []
|
@@ -113,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
131
|
version: '0'
|
114
132
|
requirements: []
|
115
133
|
rubyforge_project:
|
116
|
-
rubygems_version: 2.
|
134
|
+
rubygems_version: 2.5.2
|
117
135
|
signing_key:
|
118
136
|
specification_version: 4
|
119
137
|
summary: Formatters for Trenni, to assist with typical views and form based interfaces.
|
@@ -121,3 +139,4 @@ test_files:
|
|
121
139
|
- spec/trenni/formatters/form_formatter_spec.rb
|
122
140
|
- spec/trenni/formatters/formatters_spec.rb
|
123
141
|
- spec/trenni/formatters/html/option_select_spec.rb
|
142
|
+
- spec/trenni/formatters/html/radio_select_spec.rb
|