trenni-formatters 2.8.0 → 2.12.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d037e40cc445eb738842fe5d21e393b3b9166a4cd0cc16f663a68d89748029c3
4
- data.tar.gz: 971da30b39aa8c5bfb40d2838ef09083abb25ff054e6ab8d4dfc63b405a5d2dc
3
+ metadata.gz: 518b46786862caa9ff2dced015ea7f14299c274f42bbe7556f9d85ef4fe5a21c
4
+ data.tar.gz: af3c874086ff1d37d39f2294a2037d4cbc63fafc4e3a783f6d2481d579404c14
5
5
  SHA512:
6
- metadata.gz: dab2480c97459bbb95ec16b6c68a006d6cf513ad3888f0484d38b2136a0ea8c62eb948692ecc8d573a98a4030e96365b3b6dfef3fd9aab7229eb7bddffdeef26
7
- data.tar.gz: af3b1cf1cb56ae17c96c1ba08b3975c6667a30b4e303a61453132fb5bf977b630eca7ea9224e5b45fd1e75d096705f7908d233ea8a22d600d9802711d60a3568
6
+ metadata.gz: b044fd11db20ab856fe9608dea7039020c1ec42850260deb3b2ca27c6c56884e7a98aeb52ef53347dde510dc0070a6ab38ac2453e7b9d1fb4cc91f36e3d853f4
7
+ data.tar.gz: 2e59bdcdfec2617347c0dd4ccbdc786057ea3cd2d1618f1f00c51c8cf9506a6f075489a0442163025bb2bb9c08468bee285c44e5a22e91a906a8b3aeb545c68d
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright (c) 2012 Samuel G. D. Williams. <http://www.codeotaku.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -31,6 +33,8 @@ module Trenni
31
33
 
32
34
  def initialize(**options)
33
35
  @options = options
36
+
37
+ @object = nil
34
38
  end
35
39
 
36
40
  # The target object of the form.
@@ -38,6 +42,10 @@ module Trenni
38
42
  @object ||= @options[:object]
39
43
  end
40
44
 
45
+ def nested_name(**options)
46
+ options[:nested_name] || @options[:nested_name]
47
+ end
48
+
41
49
  # The name of the field, used for the name attribute of an input.
42
50
  def name_for(**options)
43
51
  name = options[:name] || options[:field]
@@ -46,7 +54,7 @@ module Trenni
46
54
  name = "#{name}#{suffix}"
47
55
  end
48
56
 
49
- if nested_name = options[:nested_name]
57
+ if nested_name = self.nested_name(**options)
50
58
  "#{nested_name}[#{name}]"
51
59
  else
52
60
  name
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require 'trenni/builder'
24
+
25
+ module Trenni
26
+ module Formatters
27
+ module HTML
28
+ class AcceptCheckbox
29
+ def self.call(formatter, builder, **options, &block)
30
+ instance = self.new(formatter, builder, **options)
31
+
32
+ instance.call(options, &block)
33
+ end
34
+
35
+ def initialize(formatter, builder, **options)
36
+ @formatter = formatter
37
+ @object = formatter.object
38
+
39
+ @builder = builder
40
+
41
+ @options = options
42
+ @field = options[:field]
43
+ end
44
+
45
+ def name_for(**options)
46
+ @formatter.name_for(**options)
47
+ end
48
+
49
+ def title_for(**options)
50
+ @formatter.title_for(**options)
51
+ end
52
+
53
+ def checkbox_attributes_for(**options)
54
+ @formatter.checkbox_attributes_for(**options)
55
+ end
56
+
57
+ def call(**options, &block)
58
+ Builder.fragment(@builder) do |builder|
59
+ builder.inline('span') do
60
+ builder.inline :input, :type => :hidden, :name => name_for(**options), :value => 'false'
61
+
62
+ builder.tag :input, checkbox_attributes_for(**options)
63
+
64
+ builder.text " "
65
+
66
+ builder.capture(self, &block)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -30,109 +32,132 @@ module Trenni
30
32
  include FormFormatter
31
33
 
32
34
  # An input field (single line text).
33
- def input(options = {})
34
- options = @options.merge(options)
35
+ def input(**options)
36
+ options = @options.merge(**options)
35
37
 
36
38
  Builder.fragment do |builder|
37
39
  builder.inline(:dt) do
38
- builder.text title_for(options)
40
+ builder.text title_for(**options)
39
41
  end
40
42
 
41
43
  builder.inline(:dd) do
42
- builder.tag :input, input_attributes_for(options)
44
+ builder.tag :input, input_attributes_for(**options)
43
45
 
44
- if details = details_for(options)
45
- builder.inline(:small, class: 'details') { builder.text details }
46
+ if details = details_for(**options)
47
+ builder.inline(:small, class: 'details') {builder.text details}
46
48
  end
47
49
  end
48
50
  end
49
51
  end
50
52
 
51
53
  # An output field for the result of a computation.
52
- def output(options = {})
53
- options = @options.merge(options)
54
+ def output(**options)
55
+ options = @options.merge(**options)
54
56
 
55
57
  Builder.fragment do |builder|
56
- builder.inline(:dt) { builder.text title_for(options) }
58
+ builder.inline(:dt) {builder.text title_for(**options)}
57
59
 
58
60
  builder.inline(:dd) do
59
- builder.inline :output, output_attributes_for(options) do
60
- builder.text value_for(options)
61
+ builder.inline :output, output_attributes_for(**options) do
62
+ builder.text value_for(**options)
61
63
  end
62
64
  end
63
65
  end
64
66
  end
65
67
 
66
68
  # A textarea field (multi-line text).
67
- def textarea(options = {})
68
- options = @options.merge(options)
69
+ def textarea(**options)
70
+ options = @options.merge(**options)
69
71
 
70
72
  Builder.fragment do |builder|
71
73
  builder.tag(:dt) do
72
- builder.text title_for(options)
74
+ builder.text title_for(**options)
73
75
 
74
- if details = details_for(options)
75
- builder.inline(:small, class: 'details') { builder.text details }
76
+ if details = details_for(**options)
77
+ builder.inline(:small, class: 'details') {builder.text details}
76
78
  end
77
79
  end
78
80
 
79
81
  builder.inline(:dd) do
80
- builder.tag :textarea, textarea_attributes_for(options) do
81
- builder.text value_for(options)
82
+ builder.tag :textarea, textarea_attributes_for(**options) do
83
+ builder.text value_for(**options)
82
84
  end
83
85
  end
84
86
  end
85
87
  end
86
88
 
87
89
  # A checkbox field.
88
- def checkbox(options)
89
- options = @options.merge(options)
90
+ def checkbox(**options)
91
+ options = @options.merge(**options)
90
92
 
91
93
  Builder.fragment do |builder|
92
94
  builder.tag(:dd) do
93
- builder.tag :input, :type => :hidden, :name => name_for(options), :value => 'false'
95
+ builder.tag :input, :type => :hidden, :name => name_for(**options), :value => 'false'
94
96
 
95
97
  builder.inline(:label) do
96
- builder.tag :input, checkbox_attributes_for(options)
98
+ builder.tag :input, checkbox_attributes_for(**options)
97
99
  # We would like a little bit of whitespace between the checkbox and the title.
98
- builder.text " " + title_for(options)
100
+ builder.text " " + title_for(**options)
99
101
  end
100
102
 
101
- if details = details_for(options)
102
- builder.inline(:small, class: 'details') { builder.text details }
103
+ if details = details_for(**options)
104
+ builder.inline(:small, class: 'details') {builder.text details}
103
105
  end
104
106
  end
105
107
  end
106
108
  end
107
109
 
108
110
  # A submission button
109
- def submit(options = {})
110
- options = @options.merge(options)
111
- options[:title] ||= submit_title_for(options)
111
+ def submit(**options)
112
+ options = @options.merge(**options)
113
+ options[:title] ||= submit_title_for(**options)
112
114
 
113
115
  Builder.fragment do |builder|
114
- builder.tag :input, submit_attributes_for(options)
116
+ builder.tag :input, submit_attributes_for(**options)
115
117
  end
116
118
  end
117
-
118
- def element(klass, options = {}, &block)
119
- options = @options.merge(options)
119
+
120
+ def fieldset(**options, &block)
121
+ options = @options.merge(**options)
122
+ buffer = Trenni::Template.buffer(block.binding)
123
+
124
+ Builder.fragment(buffer) do |builder|
125
+ builder.tag('fieldset') do
126
+ builder.inline('legend') do
127
+ builder.text title_for(**options)
128
+ end
129
+
130
+ builder.tag('dl') do
131
+ yield(builder)
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ def element(klass, **options, &block)
138
+ options = @options.merge(**options)
120
139
  buffer = Trenni::Template.buffer(block.binding)
121
140
 
122
141
  buffer << Builder.fragment do |builder|
123
142
  builder.inline(:dt) do
124
- builder.text title_for(options)
143
+ builder.text title_for(**options)
125
144
  end
126
145
 
127
146
  builder.tag(:dd) do
128
- klass.call(self, options, builder, &block)
147
+ klass.call(self, builder, **options, &block)
129
148
 
130
- if details = details_for(options)
131
- builder.inline(:small, class: 'details') { builder.text details }
149
+ if details = details_for(**options)
150
+ builder.inline(:small, class: 'details') {builder.text details}
132
151
  end
133
152
  end
134
153
  end
135
154
  end
155
+
156
+ def fieldset(**options, &block)
157
+ super do |builder|
158
+ builder.tag(:dl, &block)
159
+ end
160
+ end
136
161
  end
137
162
  end
138
163
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
4
  #
3
5
  # Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -30,83 +32,83 @@ module Trenni
30
32
  end
31
33
 
32
34
  # Any additional details relating to a field (e.g. explanation text)
33
- def details_for(options)
35
+ def details_for(**options)
34
36
  options[:details]
35
37
  end
36
38
 
37
- def field_for(options)
39
+ def field_for(**options)
38
40
  options[:field]
39
41
  end
40
42
 
41
43
  # A title is a text string that will be displayed next to or on top of the control to describe it or its value:
42
- def title_for(options)
44
+ def title_for(**options)
43
45
  if title = options[:title]
44
46
  return title
45
47
  end
46
48
 
47
49
  # Generate a title from a field name:
48
- if field_name = field_for(options)
50
+ if field_name = field_for(**options)
49
51
  # Remove postfix "_id" or "_ids":
50
52
  return Strings::to_title(field_name.to_s.sub(/_ids?/, ''))
51
53
  end
52
54
  end
53
55
 
54
- def object_value_for(options)
55
- if object = options[:object] and field = field_for(options)
56
+ def object_value_for(**options)
57
+ if object = options[:object] and field = field_for(**options)
56
58
  object.send(field)
57
59
  end
58
60
  end
59
61
 
60
- def raw_value_for(options)
61
- value = options.fetch(:value) { object_value_for(options) }
62
+ def raw_value_for(**options)
63
+ value = options.fetch(:value) {object_value_for(**options)}
62
64
 
63
65
  # Allow to specify a default value if the value given, usually from an object, is nil.
64
66
  value || options[:default]
65
67
  end
66
68
 
67
69
  # The value of the field.
68
- def value_for(options)
69
- if value = raw_value_for(options)
70
+ def value_for(**options)
71
+ if value = raw_value_for(**options)
70
72
  self.format(value, options)
71
73
  end
72
74
  end
73
75
 
74
- def pattern_for(options)
76
+ def pattern_for(**options)
75
77
  options[:pattern]
76
78
  end
77
79
 
78
- def placeholder_for(options)
80
+ def placeholder_for(**options)
79
81
  options[:placeholder]
80
82
  end
81
83
 
82
- def input_attributes_for(options)
84
+ def input_attributes_for(**options)
83
85
  attributes = {
84
86
  :type => options[:type],
85
- :name => name_for(options),
87
+ :name => name_for(**options),
86
88
  :id => options[:id],
87
89
  :class => options[:class],
88
- :value => value_for(options),
90
+ :value => value_for(**options),
89
91
  :required => options[:required],
90
92
  :disabled => options[:disabled],
91
93
  :readonly => options[:readonly],
92
- :pattern => pattern_for(options),
93
- :placeholder => placeholder_for(options),
94
+ :pattern => pattern_for(**options),
95
+ :placeholder => placeholder_for(**options),
94
96
  # for <input type="range|number">
95
- :min => options[:min],
96
- :max => options[:max],
97
+ :min => options[:minimum] || options[:min],
98
+ :max => options[:maximum] || options[:max],
97
99
  :step => options[:step],
98
100
  # for <input type="text">
99
- :minlength => options[:minlength],
100
- :maxlength => options[:maxlength],
101
+ :minlength => options[:minimum] || options[:minlength],
102
+ :maxlength => options[:maximum] || options[:maxlength],
101
103
  :data => options[:data],
102
104
  }
103
105
 
104
106
  return attributes
105
107
  end
106
108
 
107
- def output_attributes_for(options)
109
+ def output_attributes_for(**options)
108
110
  attributes = {
109
- :name => name_for(options),
111
+ :name => name_for(**options),
110
112
  :id => options[:id],
111
113
  :class => options[:class],
112
114
  :for => options[:for],
@@ -117,30 +119,30 @@ module Trenni
117
119
  return attributes
118
120
  end
119
121
 
120
- def textarea_attributes_for(options)
122
+ def textarea_attributes_for(**options)
121
123
  return {
122
- :name => name_for(options),
124
+ :name => name_for(**options),
123
125
  :id => options[:id],
124
126
  :class => options[:class],
125
127
  :required => options[:required],
126
128
  :disabled => options[:disabled],
127
129
  :readonly => options[:readonly],
128
- :pattern => pattern_for(options),
129
- :placeholder => placeholder_for(options),
130
+ :pattern => pattern_for(**options),
131
+ :placeholder => placeholder_for(**options),
130
132
  :minlength => options[:minlength],
131
133
  :maxlength => options[:maxlength],
132
134
  :data => options[:data],
133
135
  }
134
136
  end
135
137
 
136
- def checkbox_attributes_for(options)
138
+ def checkbox_attributes_for(**options)
137
139
  return {
138
140
  :type => options[:type] || 'checkbox',
139
141
  :id => options[:id],
140
142
  :class => options[:class],
141
- :name => name_for(options),
143
+ :name => name_for(**options),
142
144
  :value => 'true',
143
- :checked => raw_value_for(options),
145
+ :checked => raw_value_for(**options),
144
146
  :required => options[:required],
145
147
  :disabled => options[:disabled],
146
148
  :readonly => options[:readonly],
@@ -148,71 +150,86 @@ module Trenni
148
150
  }
149
151
  end
150
152
 
151
- def submit_attributes_for(options)
153
+ def submit_attributes_for(**options)
152
154
  return {
153
155
  :type => options[:type] || 'submit',
154
- :name => name_for(options),
156
+ :name => name_for(**options),
155
157
  :id => options[:id],
156
158
  :class => options[:class],
157
159
  :disabled => options[:disabled],
158
- :value => title_for(options),
160
+ :value => title_for(**options),
159
161
  :data => options[:data],
160
162
  }
161
163
  end
162
164
 
163
- def submit_title_for(options)
164
- title_for(options) || (new_record? ? 'Create' : 'Update')
165
+ def submit_title_for(**options)
166
+ title_for(**options) || (new_record? ? 'Create' : 'Update')
165
167
  end
166
168
 
167
- def hidden_attributes_for(options)
169
+ def hidden_attributes_for(**options)
168
170
  return {
169
171
  :type => options[:type] || 'hidden',
170
172
  :id => options[:id],
171
173
  :class => options[:class],
172
- :name => name_for(options),
173
- :value => value_for(options),
174
+ :name => name_for(**options),
175
+ :value => value_for(**options),
174
176
  :data => options[:data],
175
177
  }
176
178
  end
177
179
 
178
180
  # A hidden field.
179
- def hidden(options = {})
180
- options = @options.merge(options)
181
+ def hidden(**options)
182
+ options = @options.merge(**options)
181
183
 
182
184
  Builder.fragment do |builder|
183
- builder.tag :input, hidden_attributes_for(options)
185
+ builder.tag :input, hidden_attributes_for(**options)
184
186
  end
185
187
  end
186
188
 
187
- def button_attributes_for(options)
189
+ def button_attributes_for(**options)
188
190
  return {
189
191
  :type => options[:type] || 'submit',
190
- :name => name_for(options),
192
+ :name => name_for(**options),
191
193
  :id => options[:id],
192
194
  :class => options[:class],
193
195
  :disabled => options[:disabled],
194
- :value => value_for(options),
196
+ :value => value_for(**options),
195
197
  :data => options[:data],
196
198
  }
197
199
  end
198
200
 
199
- def button_title_for(options)
201
+ def button_title_for(**options)
200
202
  type = options.fetch(:type, 'submit').to_sym
201
203
 
202
204
  if type == :submit
203
- submit_title_for(options)
205
+ submit_title_for(**options)
204
206
  else
205
- title_for(options) || Strings::to_title(type.to_s)
207
+ title_for(**options) || Strings::to_title(type.to_s)
206
208
  end
207
209
  end
208
210
 
209
211
  # A hidden field.
210
- def button(options = {})
211
- options = @options.merge(options)
212
+ def button(**options)
213
+ options = @options.merge(**options)
212
214
 
213
215
  Builder.fragment do |builder|
214
- builder.inline :button, button_attributes_for(options) do
215
- builder.text button_title_for(options)
216
+ builder.inline :button, button_attributes_for(**options) do
217
+ builder.text button_title_for(**options)
218
+ end
219
+ end
220
+ end
221
+
222
+ def fieldset(**options, &block)
223
+ options = @options.merge(**options)
224
+ buffer = Trenni::Template.buffer(block.binding)
225
+
226
+ Builder.fragment(buffer) do |builder|
227
+ builder.tag('fieldset') do
228
+ builder.inline('legend') do
229
+ builder.text title_for(**options)
230
+ end
231
+
232
+ yield(builder)
216
233
  end
217
234
  end
218
235
  end