trenni-formatters 2.6.0 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 492fe49e4a836ae2bfd931e505dc45744e50387a
4
- data.tar.gz: 789f8f795d95e35576f8841fbb43cf0ba7665bf6
2
+ SHA256:
3
+ metadata.gz: 6d6feaaa592cf7b7ee7470871eb4a169485b1141978ca45fc0bae655e76494fc
4
+ data.tar.gz: 78e3dec788ea4b9439d64a281f13b1dd8a4b4845d65340d595e4e8489437d93c
5
5
  SHA512:
6
- metadata.gz: 795ef68fecbeb39740a104bd80916a50f723fd16d94987bb9b4118264d6e0cc485cca9e8f82871343214f22fa80e4ea47fa438f54ee5137b51fd43a64aaa1a7d
7
- data.tar.gz: 5d6a141d9ae4ed0cce880ce4747ba9e4eab6e6e312c4343676345a9ea5dc4c2515d995b1e31a3f10d6944804c97f0e3aa7ba29598d2098f96a825ccdb2ea3236
6
+ metadata.gz: 1ed0633355b499980dadbcb900a651020f9718d43bae54b8dbbe2f8e0c491d06dec7bb9cf63e4eab58f6aa5bdba84742a31f1824711c124e95c2a24f8930fd0f
7
+ data.tar.gz: 151c6d08577bfc6481591c3b2c0733083b5d847c02f633525c5225629dc717f45b532b6c957fb27450cda2787e88d939e63d1bc4e6c15fe15bc4e570f2b78c4b
@@ -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
@@ -25,12 +27,60 @@ require 'mapping/descendants'
25
27
  module Trenni
26
28
  module Formatters
27
29
  class Formatter < Mapping::Model
28
- def initialize(options = {})
30
+ def self.for(object, **options)
31
+ self.new(object: object, **options)
32
+ end
33
+
34
+ def initialize(**options)
29
35
  @options = options
36
+
37
+ @object = nil
38
+ end
39
+
40
+ # The target object of the form.
41
+ def object
42
+ @object ||= @options[:object]
43
+ end
44
+
45
+ def nested_name(**options)
46
+ options[:nested_name] || @options[:nested_name]
47
+ end
48
+
49
+ # The name of the field, used for the name attribute of an input.
50
+ def name_for(**options)
51
+ name = options[:name] || options[:field]
52
+
53
+ if suffix = options[:suffix]
54
+ name = "#{name}#{suffix}"
55
+ end
56
+
57
+ if nested_name = self.nested_name(**options)
58
+ "#{nested_name}[#{name}]"
59
+ else
60
+ name
61
+ end
62
+ end
63
+
64
+ def nested_name_for(**options)
65
+ name_for(**options)
66
+ end
67
+
68
+ def nested(name, key = name, klass: self.class)
69
+ options = @options.dup
70
+ target = self.object.send(name)
71
+
72
+ options[:object] = target
73
+ options[:nested_name] = nested_name_for(name: key)
74
+
75
+ formatter = klass.new(**options)
76
+
77
+ return formatter unless block_given?
78
+
79
+ yield formatter
30
80
  end
31
81
 
32
82
  attr :options
33
-
83
+
34
84
  def format_unspecified(object, options)
35
85
  object.to_s
36
86
  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,104 +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)
39
-
40
- if details = details_for(options)
41
- builder.inline(:small) { builder.text details }
42
- end
40
+ builder.text title_for(**options)
43
41
  end
44
42
 
45
43
  builder.inline(:dd) do
46
- builder.tag :input, input_attributes_for(options)
44
+ builder.tag :input, input_attributes_for(**options)
45
+
46
+ if details = details_for(**options)
47
+ builder.inline(:small, class: 'details') {builder.text details}
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) { 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'
96
+
94
97
  builder.inline(:label) do
95
- builder.tag :input, checkbox_attributes_for(options)
98
+ builder.tag :input, checkbox_attributes_for(**options)
96
99
  # We would like a little bit of whitespace between the checkbox and the title.
97
- builder.text " " + title_for(options)
100
+ builder.text " " + title_for(**options)
101
+ end
102
+
103
+ if details = details_for(**options)
104
+ builder.inline(:small, class: 'details') {builder.text details}
98
105
  end
99
106
  end
100
107
  end
101
108
  end
102
109
 
103
110
  # A submission button
104
- def submit(options = {})
105
- options = @options.merge(options)
106
- options[:title] ||= submit_title_for(options)
111
+ def submit(**options)
112
+ options = @options.merge(**options)
113
+ options[:title] ||= submit_title_for(**options)
107
114
 
108
115
  Builder.fragment do |builder|
109
- builder.tag :input, submit_attributes_for(options)
116
+ builder.tag :input, submit_attributes_for(**options)
110
117
  end
111
118
  end
112
-
113
- def element(klass, options = {}, &block)
114
- options = @options.merge(options)
119
+
120
+ def fieldset(**options, &block)
121
+ options = @options.merge(**options)
115
122
  buffer = Trenni::Template.buffer(block.binding)
116
123
 
117
- buffer << Builder.fragment do |builder|
118
- builder.inline(:dt) do
119
- builder.text title_for(options)
124
+ Builder.fragment(buffer) do |builder|
125
+ builder.tag('fieldset') do
126
+ builder.inline('legend') do
127
+ builder.text title_for(**options)
128
+ end
120
129
 
121
- if details = details_for(options)
122
- builder.inline(:small) { builder.text details }
130
+ builder.tag('dl') do
131
+ yield(builder)
123
132
  end
124
133
  end
134
+ end
135
+ end
136
+
137
+ def element(klass, **options, &block)
138
+ options = @options.merge(**options)
139
+ buffer = Trenni::Template.buffer(block.binding)
140
+
141
+ buffer << Builder.fragment do |builder|
142
+ builder.inline(:dt) do
143
+ builder.text title_for(**options)
144
+ end
125
145
 
126
146
  builder.tag(:dd) do
127
- klass.call(self, options, builder, &block)
147
+ klass.call(self, builder, **options, &block)
148
+
149
+ if details = details_for(**options)
150
+ builder.inline(:small, class: 'details') {builder.text details}
151
+ end
128
152
  end
129
153
  end
130
154
  end
155
+
156
+ def fieldset(**options, &block)
157
+ super do |builder|
158
+ builder.tag(:dl, &block)
159
+ end
160
+ end
131
161
  end
132
162
  end
133
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
@@ -24,99 +26,89 @@ module Trenni
24
26
  module Formatters
25
27
  module HTML
26
28
  module FormFormatter
27
- # The target object of the form.
28
- def object
29
- @object ||= @options[:object]
30
- end
31
-
32
29
  # Return true if the object is begin created or false if it is being updated.
33
30
  def new_record?
34
31
  object.new_record?
35
32
  end
36
33
 
37
34
  # Any additional details relating to a field (e.g. explanation text)
38
- def details_for(options)
35
+ def details_for(**options)
39
36
  options[:details]
40
37
  end
41
38
 
42
- # The name of the field, used for the name attribute of an input.
43
- def name_for(options)
44
- options[:name] || options[:field]
45
- end
46
-
47
- def field_for(options)
39
+ def field_for(**options)
48
40
  options[:field]
49
41
  end
50
42
 
51
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:
52
- def title_for(options)
44
+ def title_for(**options)
53
45
  if title = options[:title]
54
46
  return title
55
47
  end
56
48
 
57
49
  # Generate a title from a field name:
58
- if field_name = field_for(options)
50
+ if field_name = field_for(**options)
59
51
  # Remove postfix "_id" or "_ids":
60
52
  return Strings::to_title(field_name.to_s.sub(/_ids?/, ''))
61
53
  end
62
54
  end
63
55
 
64
- def object_value_for(options)
65
- 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)
66
58
  object.send(field)
67
59
  end
68
60
  end
69
61
 
70
- def raw_value_for(options)
71
- value = options.fetch(:value) { object_value_for(options) }
62
+ def raw_value_for(**options)
63
+ value = options.fetch(:value) {object_value_for(**options)}
72
64
 
73
65
  # Allow to specify a default value if the value given, usually from an object, is nil.
74
66
  value || options[:default]
75
67
  end
76
68
 
77
69
  # The value of the field.
78
- def value_for(options)
79
- if value = raw_value_for(options)
70
+ def value_for(**options)
71
+ if value = raw_value_for(**options)
80
72
  self.format(value, options)
81
73
  end
82
74
  end
83
75
 
84
- def pattern_for(options)
76
+ def pattern_for(**options)
85
77
  options[:pattern]
86
78
  end
87
79
 
88
- def placeholder_for(options)
80
+ def placeholder_for(**options)
89
81
  options[:placeholder]
90
82
  end
91
83
 
92
- def input_attributes_for(options)
84
+ def input_attributes_for(**options)
93
85
  attributes = {
94
86
  :type => options[:type],
95
- :name => name_for(options),
87
+ :name => name_for(**options),
96
88
  :id => options[:id],
97
89
  :class => options[:class],
98
- :value => value_for(options),
90
+ :value => value_for(**options),
99
91
  :required => options[:required],
100
92
  :disabled => options[:disabled],
101
93
  :readonly => options[:readonly],
102
- :pattern => pattern_for(options),
103
- :placeholder => placeholder_for(options),
94
+ :pattern => pattern_for(**options),
95
+ :placeholder => placeholder_for(**options),
104
96
  # for <input type="range|number">
105
- :min => options[:min],
106
- :max => options[:max],
97
+ :min => options[:minimum] || options[:min],
98
+ :max => options[:maximum] || options[:max],
107
99
  :step => options[:step],
108
100
  # for <input type="text">
109
- :minlength => options[:minlength],
110
- :maxlength => options[:maxlength],
101
+ :minlength => options[:minimum] || options[:minlength],
102
+ :maxlength => options[:maximum] || options[:maxlength],
111
103
  :data => options[:data],
112
104
  }
113
105
 
114
106
  return attributes
115
107
  end
116
108
 
117
- def output_attributes_for(options)
109
+ def output_attributes_for(**options)
118
110
  attributes = {
119
- :name => name_for(options),
111
+ :name => name_for(**options),
120
112
  :id => options[:id],
121
113
  :class => options[:class],
122
114
  :for => options[:for],
@@ -127,30 +119,30 @@ module Trenni
127
119
  return attributes
128
120
  end
129
121
 
130
- def textarea_attributes_for(options)
122
+ def textarea_attributes_for(**options)
131
123
  return {
132
- :name => name_for(options),
124
+ :name => name_for(**options),
133
125
  :id => options[:id],
134
126
  :class => options[:class],
135
127
  :required => options[:required],
136
128
  :disabled => options[:disabled],
137
129
  :readonly => options[:readonly],
138
- :pattern => pattern_for(options),
139
- :placeholder => placeholder_for(options),
130
+ :pattern => pattern_for(**options),
131
+ :placeholder => placeholder_for(**options),
140
132
  :minlength => options[:minlength],
141
133
  :maxlength => options[:maxlength],
142
134
  :data => options[:data],
143
135
  }
144
136
  end
145
137
 
146
- def checkbox_attributes_for(options)
138
+ def checkbox_attributes_for(**options)
147
139
  return {
148
140
  :type => options[:type] || 'checkbox',
149
141
  :id => options[:id],
150
142
  :class => options[:class],
151
- :name => name_for(options),
143
+ :name => name_for(**options),
152
144
  :value => 'true',
153
- :checked => raw_value_for(options),
145
+ :checked => raw_value_for(**options),
154
146
  :required => options[:required],
155
147
  :disabled => options[:disabled],
156
148
  :readonly => options[:readonly],
@@ -158,71 +150,86 @@ module Trenni
158
150
  }
159
151
  end
160
152
 
161
- def submit_attributes_for(options)
153
+ def submit_attributes_for(**options)
162
154
  return {
163
155
  :type => options[:type] || 'submit',
164
- :name => name_for(options),
156
+ :name => name_for(**options),
165
157
  :id => options[:id],
166
158
  :class => options[:class],
167
159
  :disabled => options[:disabled],
168
- :value => title_for(options),
160
+ :value => title_for(**options),
169
161
  :data => options[:data],
170
162
  }
171
163
  end
172
164
 
173
- def submit_title_for(options)
174
- title_for(options) || (new_record? ? 'Create' : 'Update')
165
+ def submit_title_for(**options)
166
+ title_for(**options) || (new_record? ? 'Create' : 'Update')
175
167
  end
176
168
 
177
- def hidden_attributes_for(options)
169
+ def hidden_attributes_for(**options)
178
170
  return {
179
171
  :type => options[:type] || 'hidden',
180
172
  :id => options[:id],
181
173
  :class => options[:class],
182
- :name => name_for(options),
183
- :value => value_for(options),
174
+ :name => name_for(**options),
175
+ :value => value_for(**options),
184
176
  :data => options[:data],
185
177
  }
186
178
  end
187
179
 
188
180
  # A hidden field.
189
- def hidden(options = {})
190
- options = @options.merge(options)
181
+ def hidden(**options)
182
+ options = @options.merge(**options)
191
183
 
192
184
  Builder.fragment do |builder|
193
- builder.tag :input, hidden_attributes_for(options)
185
+ builder.tag :input, hidden_attributes_for(**options)
194
186
  end
195
187
  end
196
188
 
197
- def button_attributes_for(options)
189
+ def button_attributes_for(**options)
198
190
  return {
199
191
  :type => options[:type] || 'submit',
200
- :name => name_for(options),
192
+ :name => name_for(**options),
201
193
  :id => options[:id],
202
194
  :class => options[:class],
203
195
  :disabled => options[:disabled],
204
- :value => value_for(options),
196
+ :value => value_for(**options),
205
197
  :data => options[:data],
206
198
  }
207
199
  end
208
200
 
209
- def button_title_for(options)
201
+ def button_title_for(**options)
210
202
  type = options.fetch(:type, 'submit').to_sym
211
203
 
212
204
  if type == :submit
213
- submit_title_for(options)
205
+ submit_title_for(**options)
214
206
  else
215
- title_for(options) || Strings::to_title(type.to_s)
207
+ title_for(**options) || Strings::to_title(type.to_s)
216
208
  end
217
209
  end
218
210
 
219
211
  # A hidden field.
220
- def button(options = {})
221
- options = @options.merge(options)
212
+ def button(**options)
213
+ options = @options.merge(**options)
222
214
 
223
215
  Builder.fragment do |builder|
224
- builder.inline :button, button_attributes_for(options) do
225
- 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)
226
233
  end
227
234
  end
228
235
  end