forma 0.1.1 → 0.1.2
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 +7 -0
- data/lib/forma/action.rb +39 -14
- data/lib/forma/config.rb +4 -0
- data/lib/forma/field.rb +204 -83
- data/lib/forma/form.rb +5 -2
- data/lib/forma/helpers.rb +21 -0
- data/lib/forma/html.rb +5 -3
- data/lib/forma/table.rb +9 -1
- data/lib/forma/utils.rb +22 -0
- data/lib/forma/version.rb +1 -1
- data/test/utils_test.rb +15 -0
- data/vendor/assets/javascripts/forma.js +51 -0
- data/vendor/assets/stylesheets/forma-min.css +47 -41
- data/vendor/assets/stylesheets/forma.css +89 -20
- data/vendor/less/forma.less +45 -12
- metadata +15 -29
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 16aaf06c56a52180e7b4aea01508cb4bdc9fcb74
|
4
|
+
data.tar.gz: 4e1a5437ff778c502118d0cebc20fc97c03f2e8c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 84ae57199011563b025ca909d30b6047bd3865e25a54dd8d606732b8631de098411743b58b60b6e002ec615f52c8206032320ffd27a44afdbd5b764e5b2ad18f
|
7
|
+
data.tar.gz: c07481957ed0302a27a3325491e364fabf6effb634438ba6c15e6175e307fe23ddfa2057783942062486263444234e80a0b97d9e55c4b70eaac7c650bc7006bb
|
data/lib/forma/action.rb
CHANGED
@@ -15,31 +15,56 @@ module Forma
|
|
15
15
|
@confirm = h[:confirm]
|
16
16
|
@as = h[:as]
|
17
17
|
@tooltip = h[:tooltip]
|
18
|
+
@select = h[:select]
|
19
|
+
@condition = h[:condition]
|
18
20
|
end
|
19
21
|
|
20
22
|
def to_html(model)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
23
|
+
if eval_condition(model)
|
24
|
+
if @select
|
25
|
+
el(
|
26
|
+
'a',
|
27
|
+
attrs: {
|
28
|
+
id: @id, class: ['ff-action', 'btn', 'btn-mini', 'ff-select-action', 'btn-xs', 'btn-default'],
|
29
|
+
href: '#', 'data-original-title' => @tooltip,
|
30
|
+
'data-value-id' => model.id, 'data-value-type' => model.class.name, 'data-value-text' => model.to_s
|
31
|
+
},
|
32
|
+
children: [ el('i', attrs: { class: 'icon icon-download fa fa-hand-o-left' }) ]
|
33
|
+
)
|
34
|
+
else
|
35
|
+
children = [ (el('img', attrs: { src: eval_icon(model) }) if @icon.present?), el('span', text: eval_label(model)) ]
|
36
|
+
button = (@as.to_s == 'button')
|
37
|
+
el(
|
38
|
+
'a',
|
39
|
+
attrs: {
|
40
|
+
id: @id,
|
41
|
+
class: ['ff-action', ('btn btn-default' if button)],
|
42
|
+
href: eval_url(model), 'data-method' => @method, 'data-confirm' => @confirm,
|
43
|
+
'data-original-title' => @tooltip
|
44
|
+
},
|
45
|
+
children: children
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
33
49
|
end
|
34
50
|
|
35
51
|
private
|
36
52
|
|
37
53
|
def eval_url(model)
|
38
|
-
@url.is_a?(Proc) ? @url.call(model) : @url.to_s
|
54
|
+
@url.is_a?(Proc) ? @url.call(model).to_s : @url.to_s
|
39
55
|
end
|
40
56
|
|
41
57
|
def eval_label(model)
|
42
|
-
@label.is_a?(Proc) ? @label.call(model) : @label.to_s
|
58
|
+
@label.is_a?(Proc) ? @label.call(model).to_s : @label.to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
def eval_icon(model)
|
62
|
+
@icon.is_a?(Proc) ? @icon.call(model).to_s : @icon.to_s
|
63
|
+
end
|
64
|
+
|
65
|
+
def eval_condition(model)
|
66
|
+
if @condition then @condition.is_a?(Proc) ? @condition.call(model) : @condition
|
67
|
+
else true end
|
43
68
|
end
|
44
69
|
end
|
45
70
|
end
|
data/lib/forma/config.rb
CHANGED
@@ -34,9 +34,13 @@ module Forma
|
|
34
34
|
class NumberConfig
|
35
35
|
attr_accessor :delimiter
|
36
36
|
attr_accessor :separator
|
37
|
+
attr_accessor :max_digits
|
38
|
+
attr_accessor :min_digits
|
37
39
|
def initialize
|
38
40
|
self.delimiter = ','
|
39
41
|
self.separator = '.'
|
42
|
+
self.max_digits = 3
|
43
|
+
self.min_digits = 2
|
40
44
|
end
|
41
45
|
end
|
42
46
|
|
data/lib/forma/field.rb
CHANGED
@@ -5,7 +5,7 @@ module Forma
|
|
5
5
|
include Forma::Utils
|
6
6
|
include Forma::Html
|
7
7
|
|
8
|
-
attr_reader :label, :hint, :i18n, :name, :tag
|
8
|
+
attr_reader :label, :hint, :i18n, :name, :tag, :inline_hint
|
9
9
|
attr_reader :required, :autofocus, :readonly
|
10
10
|
attr_reader :width, :height
|
11
11
|
attr_reader :before, :after
|
@@ -17,6 +17,7 @@ module Forma
|
|
17
17
|
def initialize(h = {})
|
18
18
|
h = h.symbolize_keys
|
19
19
|
@id = h[:id]; @label = h[:label]; @hint = h[:hint]; @i18n = h[:i18n]
|
20
|
+
@inline_hint = h[:inline_hint]
|
20
21
|
@required = h[:required]; @autofocus = h[:autofocus]; @readonly = (not not h[:readonly])
|
21
22
|
@width = h[:width]; @height = h[:height]
|
22
23
|
@before = h[:before]; @after = h[:after]
|
@@ -26,6 +27,9 @@ module Forma
|
|
26
27
|
@model_name = h[:model_name]; @child_model_name = h[:child_model_name]
|
27
28
|
@actions = h[:actions] || []
|
28
29
|
@tag = h[:tag]
|
30
|
+
@empty = h[:empty]
|
31
|
+
@force_nonempty = h[:force_nonempty]
|
32
|
+
@class = h[:class]
|
29
33
|
end
|
30
34
|
|
31
35
|
def action(url, h={})
|
@@ -40,22 +44,16 @@ module Forma
|
|
40
44
|
else
|
41
45
|
chain = [ self.model_name, self.name ]
|
42
46
|
end
|
47
|
+
chain.map { |x| x.to_s.gsub '.', '_' }
|
43
48
|
end
|
44
49
|
|
45
50
|
def id
|
46
51
|
if @id then @id
|
47
|
-
else name_as_chain.
|
52
|
+
else name_as_chain.select{ |x| x.present? }.join('_') end
|
48
53
|
end
|
49
54
|
|
50
55
|
def parameter_name
|
51
|
-
|
52
|
-
p_name = ''
|
53
|
-
chain.reverse.each_with_index do |n, i|
|
54
|
-
if i == 0 then p_name = n
|
55
|
-
elsif i == length - 1 then p_name = "#{n}[#{p_name}]"
|
56
|
-
else p_name = "#{n}_attributes[#{p_name}]" end
|
57
|
-
end
|
58
|
-
p_name
|
56
|
+
parameter_name_from_chain(name_as_chain)
|
59
57
|
end
|
60
58
|
|
61
59
|
# Convert this element into HTML.
|
@@ -63,15 +61,15 @@ module Forma
|
|
63
61
|
val = self.value
|
64
62
|
if edit and not readonly
|
65
63
|
edit = edit_element(val)
|
66
|
-
el('div', children: [ before_element, icon_element, edit, after_element, actions_element ])
|
64
|
+
el('div', children: [ before_element, icon_element, edit, after_element, actions_element, inline_hint_element ])
|
67
65
|
else
|
68
|
-
if val.present? or val == false
|
66
|
+
if val.present? or val == false or @force_nonempty
|
69
67
|
view = view_element(val)
|
70
68
|
view = el('a', attrs: { href: eval_url }, children: [ view ]) if @url
|
71
|
-
el('div',
|
69
|
+
el('div', attrs: { class: (@class ? eval_with_model(@class) : nil) },
|
70
|
+
children: [ before_element, icon_element, view, after_element, actions_element, inline_hint_element ])
|
72
71
|
else
|
73
|
-
|
74
|
-
el('div', children: [ empty, actions_element ])
|
72
|
+
el('div', children: [ empty_element, actions_element ])
|
75
73
|
end
|
76
74
|
end
|
77
75
|
end
|
@@ -94,7 +92,9 @@ module Forma
|
|
94
92
|
end
|
95
93
|
|
96
94
|
def localized_label
|
97
|
-
|
95
|
+
unless self.label == false
|
96
|
+
self.label.present? ? self.label : I18n.t(localization_key, default: self.name)
|
97
|
+
end
|
98
98
|
end
|
99
99
|
|
100
100
|
def localized_hint
|
@@ -103,35 +103,28 @@ module Forma
|
|
103
103
|
|
104
104
|
protected
|
105
105
|
|
106
|
-
def
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
def after_element
|
115
|
-
el('span', text: after, attrs: { class: 'ff-field-after' }) if after.present?
|
116
|
-
end
|
117
|
-
|
118
|
-
def empty_element
|
119
|
-
el('span', attrs: { class: 'ff-empty' }, text: Forma.config.texts.empty)
|
120
|
-
end
|
121
|
-
|
122
|
-
def actions_element
|
123
|
-
if @actions.any?
|
124
|
-
el('div', attrs: { class: 'ff-field-actions' }, children: @actions.map { |action| action.to_html(@model) })
|
106
|
+
def parameter_name_from_chain(chain)
|
107
|
+
length = chain.length
|
108
|
+
p_name = ''
|
109
|
+
chain.select{ |x| x.present? }.reverse.each_with_index do |n, i|
|
110
|
+
if i == 0 then p_name = n
|
111
|
+
elsif i == length - 1 then p_name = "#{n}[#{p_name}]"
|
112
|
+
else p_name = "#{n}_attributes[#{p_name}]" end
|
125
113
|
end
|
114
|
+
p_name
|
126
115
|
end
|
127
116
|
|
128
|
-
def
|
129
|
-
|
130
|
-
end
|
117
|
+
def icon_element; el('img', attrs: { src: eval_icon, style: { 'margin-right' => '4px' } }) if @icon.present? end
|
118
|
+
def before_element; el('span', text: eval_with_model(before), attrs: { class: 'ff-field-before' }) if before.present? end
|
119
|
+
def after_element; el('span', text: eval_with_model(after), attrs: { class: 'ff-field-after' }) if after.present? end
|
120
|
+
def empty_element; el('span', attrs: { class: 'ff-empty' }, text: Forma.config.texts.empty) unless @empty == false end
|
121
|
+
def actions_element; el('div', attrs: { class: 'ff-field-actions' }, children: @actions.map { |action| action.to_html(@model) }) if @actions.any? end
|
122
|
+
def inline_hint_element; el('div', attrs: { class: 'ff-inline-hint' }, text: @inline_hint) if @inline_hint.present? end
|
123
|
+
def eval_url; eval_with_model(@url) end
|
124
|
+
def eval_icon; eval_with_model(@icon) end
|
131
125
|
|
132
|
-
|
133
|
-
|
134
|
-
end
|
126
|
+
private
|
127
|
+
def eval_with_model(val, h={}); val.is_a?(Proc) ? val.call(h[:model] || self.model) : val.to_s end
|
135
128
|
end
|
136
129
|
|
137
130
|
# Complex field.
|
@@ -150,24 +143,17 @@ module Forma
|
|
150
143
|
end
|
151
144
|
|
152
145
|
def value
|
153
|
-
|
154
|
-
if val then val
|
155
|
-
else
|
156
|
-
@fields.each { |f| f.model = self.model }
|
157
|
-
@fields.map { |f| f.value }
|
158
|
-
end
|
146
|
+
@model
|
159
147
|
end
|
160
148
|
|
161
149
|
def edit_element(val)
|
162
150
|
el(
|
163
151
|
'div',
|
164
152
|
attrs: { class: 'ff-complex-field' },
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
children: [ fv[0].edit_element(fv[1]) ]
|
170
|
-
)
|
153
|
+
children: @fields.map { |f|
|
154
|
+
f.model = self.model
|
155
|
+
f.model_name = self.model_name
|
156
|
+
el('div', attrs: { class: 'ff-complex-part' }, children: [ f.to_html(true) ])
|
171
157
|
}
|
172
158
|
)
|
173
159
|
end
|
@@ -176,15 +162,20 @@ module Forma
|
|
176
162
|
el(
|
177
163
|
'div',
|
178
164
|
attrs: { class: 'ff-complex-field' },
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
attrs: { class: 'ff-complex-part' },
|
183
|
-
children: [ fv[0].view_element(fv[1]) ]
|
184
|
-
)
|
165
|
+
children: @fields.map { |f|
|
166
|
+
f.model = self.model
|
167
|
+
el('div', attrs: { class: 'ff-complex-part' }, children: [ f.to_html(false) ])
|
185
168
|
}
|
186
169
|
)
|
187
170
|
end
|
171
|
+
|
172
|
+
def errors
|
173
|
+
@fields.map { |f| f.model = @model; f.errors }.flatten
|
174
|
+
end
|
175
|
+
|
176
|
+
def has_errors?
|
177
|
+
errors.any?
|
178
|
+
end
|
188
179
|
end
|
189
180
|
|
190
181
|
# Map field.
|
@@ -336,21 +327,36 @@ module Forma
|
|
336
327
|
def initialize(h = {})
|
337
328
|
h = h.symbolize_keys
|
338
329
|
@formatter = h[:formatter]
|
330
|
+
@@date_counter ||= 0
|
331
|
+
@@date_counter += 1
|
332
|
+
@date_counter = @@date_counter
|
339
333
|
super(h)
|
340
334
|
end
|
341
335
|
|
342
336
|
def view_element(val)
|
343
|
-
|
337
|
+
val = val.respond_to?(:localtime) ? val.localtime : val
|
338
|
+
el('span', text: val.strftime(formatter || Forma.config.date.formatter))
|
344
339
|
end
|
345
340
|
|
346
341
|
def edit_element(val)
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
342
|
+
input_id = "ff-date-#{@date_counter}"
|
343
|
+
val = Date.strptime(val) if (val.present? and val.is_a?(String)) rescue nil
|
344
|
+
el('div', children: [
|
345
|
+
el('input', attrs: {
|
346
|
+
id: input_id,
|
347
|
+
name: parameter_name,
|
348
|
+
value: val.to_s,
|
349
|
+
type: 'hidden'
|
350
|
+
}),
|
351
|
+
el('input', attrs: {
|
352
|
+
class: 'ff-date',
|
353
|
+
type: 'text',
|
354
|
+
value: (val.strftime('%d-%b-%Y') if val.present?),
|
355
|
+
autofocus: @autofocus,
|
356
|
+
style: { width: "#{width || 100}px" },
|
357
|
+
'data-altfield' => input_id,
|
358
|
+
})
|
359
|
+
])
|
354
360
|
end
|
355
361
|
end
|
356
362
|
|
@@ -369,22 +375,59 @@ module Forma
|
|
369
375
|
|
370
376
|
# Image upload field.
|
371
377
|
class ImageField < SimpleField
|
378
|
+
def initialize(h = {})
|
379
|
+
h = h.symbolize_keys
|
380
|
+
@popover = h[:popover]
|
381
|
+
@height = h[:height] || 200
|
382
|
+
@width = h[:width] || 200
|
383
|
+
super(h)
|
384
|
+
end
|
385
|
+
|
372
386
|
def view_element(val)
|
373
|
-
|
387
|
+
popover_data = {}
|
388
|
+
image_url = val.respond_to?(:url) ? val.url : val.to_s
|
389
|
+
if @popover
|
390
|
+
popover_data['data-original-title'] = eval_with_model(@popover[:title])
|
391
|
+
url = eval_with_model(@popover[:url])
|
392
|
+
popover_data['data-content'] = %Q{<div style="height: #{@height}px; width: #{@width}px;"><img src="#{url}"></img></div>}
|
393
|
+
popover_data['data-html'] = 'true'
|
394
|
+
popover_data['data-placement'] = @popover[:placement]
|
395
|
+
el('img', attrs: { src: image_url, class: 'ff-popover' }.merge(popover_data))
|
396
|
+
else
|
397
|
+
el('img', attrs: { src: image_url })
|
398
|
+
end
|
374
399
|
end
|
375
400
|
|
376
401
|
def edit_element(val)
|
377
|
-
el('input', attrs: {
|
378
|
-
|
379
|
-
|
380
|
-
|
402
|
+
el('input', attrs: { name: parameter_name, type: 'file' })
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
# Image upload field.
|
407
|
+
class FileField < SimpleField
|
408
|
+
def view_element(val)
|
409
|
+
el('div', text: 'NO IMPLEMENTATION')
|
410
|
+
end
|
411
|
+
|
412
|
+
def edit_element(val)
|
413
|
+
el('input', attrs: { name: parameter_name, type: 'file' })
|
381
414
|
end
|
382
415
|
end
|
383
416
|
|
384
417
|
# Number field.
|
385
418
|
class NumberField < TextField
|
419
|
+
include Forma::Utils
|
420
|
+
def initialize(h = {})
|
421
|
+
h = h.symbolize_keys
|
422
|
+
@min_digits = h[:min_digits] || Forma.config.num.min_digits
|
423
|
+
@max_digits = h[:max_digits] || Forma.config.num.max_digits
|
424
|
+
@separator = h[:separator] || Forma.config.num.separator
|
425
|
+
@delimiter = h[:delimiter] || Forma.config.num.delimiter
|
426
|
+
super(h)
|
427
|
+
end
|
428
|
+
|
386
429
|
def view_element(val)
|
387
|
-
el('code', text: "#{val}")
|
430
|
+
el('code', text: "#{number_format(val.to_f, max_digits: @max_digits, min_digits: @min_digits)}")
|
388
431
|
end
|
389
432
|
end
|
390
433
|
|
@@ -408,8 +451,8 @@ module Forma
|
|
408
451
|
data = normalize_data(@collection, @empty)
|
409
452
|
selection = val.present? ? val : @default
|
410
453
|
el('select', attrs: { name: parameter_name }, children: data.map { |text, value|
|
411
|
-
if value.nil? then el('option', attrs: { selected: selection.blank? }, text: text)
|
412
|
-
else el('option', attrs: { selected: (true if selection == value), value: value }, text: text)
|
454
|
+
if value.nil? then el('option', attrs: { selected: selection.blank? , value: ""}, text: text)
|
455
|
+
else el('option', attrs: { selected: (true if selection.to_s == value.to_s), value: value }, text: text)
|
413
456
|
end
|
414
457
|
})
|
415
458
|
end
|
@@ -419,11 +462,64 @@ module Forma
|
|
419
462
|
def normalize_data(collection, empty)
|
420
463
|
if collection.is_a?(Hash) then data = collection.to_a
|
421
464
|
else data = collection.map { |x| [x.to_s, x.id] } end
|
422
|
-
if empty != false then data
|
465
|
+
if empty != false then data = ([[empty.to_s, nil]] + data) end
|
423
466
|
Hash[data]
|
424
467
|
end
|
425
468
|
end
|
426
469
|
|
470
|
+
# Array field.
|
471
|
+
class ArrayField < SimpleField
|
472
|
+
def initialize(h={})
|
473
|
+
h = h.symbolize_keys
|
474
|
+
@item_actions = h[:item_actions] || []
|
475
|
+
@item_url = h[:item_url]
|
476
|
+
super(h)
|
477
|
+
end
|
478
|
+
|
479
|
+
def view_element(val)
|
480
|
+
el('div', attrs: { class: ['ff-array-field'] }, children: val.map { |x|
|
481
|
+
el('div', attrs: { class: 'ff-array-part' }, children: [
|
482
|
+
if @item_url then el('a', attrs: { href: eval_with_model(@item_url, model: x) }, text: x.to_s) else el('span', text: x.to_s) end,
|
483
|
+
(el('span', attrs: { class: 'ff-actions' }, children: @item_actions.map { |a| a.to_html(x) } ) if @item_actions.any?)
|
484
|
+
])
|
485
|
+
})
|
486
|
+
end
|
487
|
+
|
488
|
+
def edit_element(val)
|
489
|
+
el('div', text: 'NO IMPLEMENTATION')
|
490
|
+
end
|
491
|
+
|
492
|
+
def item_action(url, h={})
|
493
|
+
h[:url] = url
|
494
|
+
@item_actions << Action.new(h)
|
495
|
+
end
|
496
|
+
end
|
497
|
+
|
498
|
+
# Table field.
|
499
|
+
class TableField < SimpleField
|
500
|
+
def initialize(h={})
|
501
|
+
h = h.symbolize_keys
|
502
|
+
h[:label] = false
|
503
|
+
h[:force_nonempty] = true
|
504
|
+
@table = Forma::Table.new(h[:table] || {})
|
505
|
+
super(h)
|
506
|
+
end
|
507
|
+
|
508
|
+
def view_element(val)
|
509
|
+
@table.models = val
|
510
|
+
@table.to_html
|
511
|
+
end
|
512
|
+
|
513
|
+
def edit_element(val)
|
514
|
+
el('div', text: 'NO IMPLEMENTATION')
|
515
|
+
end
|
516
|
+
|
517
|
+
def table
|
518
|
+
yield @table if block_given?
|
519
|
+
@table
|
520
|
+
end
|
521
|
+
end
|
522
|
+
|
427
523
|
# Selection field.
|
428
524
|
class SelectField < SimpleField
|
429
525
|
def initialize(h={})
|
@@ -431,21 +527,46 @@ module Forma
|
|
431
527
|
@search_url = h[:search_url]
|
432
528
|
@search_width = h[:search_width] || 500
|
433
529
|
@search_height = h[:search_height] || 600
|
530
|
+
@polymorphic = h[:polymorphic]
|
434
531
|
super(h)
|
435
532
|
end
|
436
533
|
|
437
|
-
def
|
438
|
-
|
534
|
+
def id_field_name
|
535
|
+
chain = name_as_chain
|
536
|
+
chain[chain.length - 1] = "#{chain.last}_id"
|
537
|
+
parameter_name_from_chain(chain)
|
538
|
+
end
|
539
|
+
|
540
|
+
def type_field_name
|
541
|
+
chain = name_as_chain
|
542
|
+
chain[chain.length - 1] = "#{chain.last}_type"
|
543
|
+
parameter_name_from_chain(chain)
|
439
544
|
end
|
440
545
|
|
546
|
+
def view_element(val); el(@tag || 'span', text: val.to_s) end
|
547
|
+
|
441
548
|
def edit_element(val)
|
442
|
-
el('
|
443
|
-
|
444
|
-
el('
|
445
|
-
|
446
|
-
|
549
|
+
inputs = [ el('input', attrs: { id: "#{self.id}_id_value", type: 'hidden', value: "#{val and val.id}", name: id_field_name }) ]
|
550
|
+
if @polymorphic
|
551
|
+
inputs << el('input',
|
552
|
+
attrs: { id: "#{self.id}_type_value", type: 'hidden', value: "#{val and val.class.to_s}", name: type_field_name }
|
553
|
+
)
|
554
|
+
end
|
555
|
+
text_element = el(
|
556
|
+
'span',
|
557
|
+
attrs: { id: "#{self.id}_text", class: ['ff-select-label', ('ff-empty' if val.blank?)] },
|
558
|
+
text: (val.present? ? val.to_s : Forma.config.texts.empty)
|
559
|
+
)
|
560
|
+
buttons = el('div', attrs: { class: 'btn-group' }, children: [
|
561
|
+
el('a', attrs: { class: 'ff-select-link btn btn-mini btn-default btn-xs', 'data-id' => self.id, 'data-url' => @search_url, 'data-width' => @search_width, 'data-height' => @search_height }, children: [
|
562
|
+
el('i', attrs: { class: 'icon icon-search fa fa-search' })
|
563
|
+
]),
|
564
|
+
el('a', attrs: { class: 'ff-clear-selection-action btn btn-mini btn-default btn-xs', 'data-id' => self.id }, children: [
|
565
|
+
el('i', attrs: { class: 'icon icon-trash fa fa-trash-o' })
|
447
566
|
])
|
448
567
|
])
|
568
|
+
children = inputs + [ text_element, buttons ]
|
569
|
+
el('div', attrs: { id: self.id, class: 'ff-select-field' }, children: children)
|
449
570
|
end
|
450
571
|
end
|
451
572
|
end
|
data/lib/forma/form.rb
CHANGED
@@ -109,7 +109,7 @@ module Forma
|
|
109
109
|
end
|
110
110
|
|
111
111
|
def auth_token_element
|
112
|
-
if @auth_token.present?
|
112
|
+
if @auth_token.present? and @method != 'get'
|
113
113
|
el('div', attrs: { style: {padding: 0, margin: 0, height: 0, width: 0, display: 'inline'} }, children: [
|
114
114
|
el('input', attrs: { type: 'hidden', name: 'authenticity_token', value: @auth_token })
|
115
115
|
])
|
@@ -138,7 +138,10 @@ module Forma
|
|
138
138
|
]
|
139
139
|
)
|
140
140
|
end
|
141
|
-
|
141
|
+
value_class = ['ff-value']
|
142
|
+
value_class << 'ff-required' if fld.required
|
143
|
+
value_class << 'ff-value-no-label' if fld.label == false
|
144
|
+
value_element = el('div', attrs: { class: value_class }, children: [
|
142
145
|
fld.to_html(@edit), (field_error_element(fld.errors) if has_errors),
|
143
146
|
])
|
144
147
|
el(
|
data/lib/forma/helpers.rb
CHANGED
@@ -92,6 +92,13 @@ module Forma
|
|
92
92
|
add_field(field)
|
93
93
|
end
|
94
94
|
|
95
|
+
def file_field(name, opts={})
|
96
|
+
opts[:name] = name
|
97
|
+
field = Forma::FileField.new(opts)
|
98
|
+
yield field if block_given?
|
99
|
+
add_field(field)
|
100
|
+
end
|
101
|
+
|
95
102
|
def number_field(name, opts = {})
|
96
103
|
opts[:name] = name
|
97
104
|
field = Forma::NumberField.new(opts)
|
@@ -113,6 +120,20 @@ module Forma
|
|
113
120
|
yield field if block_given?
|
114
121
|
add_field(field)
|
115
122
|
end
|
123
|
+
|
124
|
+
def array_field(name, opts = {})
|
125
|
+
opts[:name] = name
|
126
|
+
field = Forma::ArrayField.new(opts)
|
127
|
+
yield field if block_given?
|
128
|
+
add_field(field)
|
129
|
+
end
|
130
|
+
|
131
|
+
def table_field(name, opts = {})
|
132
|
+
opts[:name] = name
|
133
|
+
field = Forma::TableField.new(opts)
|
134
|
+
yield field if block_given?
|
135
|
+
add_field(field)
|
136
|
+
end
|
116
137
|
end
|
117
138
|
|
118
139
|
module WithTitleElement
|
data/lib/forma/html.rb
CHANGED
@@ -44,7 +44,7 @@ module Forma::Html
|
|
44
44
|
module_function :attr
|
45
45
|
module_function :el
|
46
46
|
|
47
|
-
private
|
47
|
+
# private
|
48
48
|
|
49
49
|
class Attr; end
|
50
50
|
|
@@ -57,8 +57,10 @@ module Forma::Html
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def to_s
|
60
|
-
if @name
|
61
|
-
%Q{#{@name}="#{@value}"}
|
60
|
+
if @name == 'value'
|
61
|
+
%Q{#{@name}="#{ERB::Util.html_escape(@value)}"}
|
62
|
+
elsif @name.present? and @value.present?
|
63
|
+
%Q{#{@name}="#{ERB::Util.html_escape(@value)}"}
|
62
64
|
end
|
63
65
|
end
|
64
66
|
end
|
data/lib/forma/table.rb
CHANGED
@@ -6,6 +6,7 @@ module Forma
|
|
6
6
|
include Forma::WithTitleElement
|
7
7
|
attr_reader :collapsible, :collapsed, :icon, :title
|
8
8
|
attr_reader :title_actions
|
9
|
+
attr_accessor :models
|
9
10
|
|
10
11
|
def initialize(h = {})
|
11
12
|
h = h.symbolize_keys
|
@@ -108,7 +109,14 @@ module Forma
|
|
108
109
|
if @paginate and @context
|
109
110
|
self_from_block = eval("self", @context.binding)
|
110
111
|
s = self_from_block.send(:will_paginate, @models, @paginate_options)
|
111
|
-
el('div', html: s.to_s)
|
112
|
+
paginate = el('div', html: s.to_s)
|
113
|
+
el('div', attrs: { class: 'ff-paginate' }, children: [
|
114
|
+
paginate,
|
115
|
+
(el('div', attrs: { class: 'ff-totals' }, children: [
|
116
|
+
el('code', text: "#{@models.total_entries}"),
|
117
|
+
el('span', text: @paginate_options[:records] || 'records')
|
118
|
+
]) if @models.total_entries > 0)
|
119
|
+
])
|
112
120
|
end
|
113
121
|
end
|
114
122
|
end
|
data/lib/forma/utils.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
require 'action_controller'
|
3
|
+
|
2
4
|
module Forma
|
3
5
|
module Utils
|
6
|
+
include ActionView::Helpers::NumberHelper
|
7
|
+
|
4
8
|
def singular_name(model)
|
5
9
|
if model.respond_to?(:model_name); model.model_name.singular_route_key # Mongoid
|
6
10
|
elsif model.class.respond_to?(:table_name); model.class.table_name.singularize # ActiveModel
|
@@ -18,7 +22,25 @@ module Forma
|
|
18
22
|
val
|
19
23
|
end
|
20
24
|
|
25
|
+
def number_format(num, h = {})
|
26
|
+
max_digits = h[:max_digits] || 2
|
27
|
+
max_digits = 0 if max_digits < 0
|
28
|
+
min_digits = h[:min_digits] || 0
|
29
|
+
min_digits = max_digits if min_digits > max_digits
|
30
|
+
separator = h[:separator] || '.'
|
31
|
+
delimiter = h[:delimiter] || ','
|
32
|
+
formatted = number_with_precision(num, precision: max_digits, separator: separator, delimiter: delimiter, strip_insignificant_zeros: true)
|
33
|
+
nums = formatted.split(separator)
|
34
|
+
length_after_separator = (nums[1] || '').length
|
35
|
+
if length_after_separator >= min_digits
|
36
|
+
formatted
|
37
|
+
else
|
38
|
+
"#{nums[0]}#{separator}#{(nums[1] || '').ljust(min_digits, '0')}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
21
42
|
module_function :singular_name
|
22
43
|
module_function :extract_value
|
44
|
+
module_function :number_format
|
23
45
|
end
|
24
46
|
end
|
data/lib/forma/version.rb
CHANGED
data/test/utils_test.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
class UtilsTest < Test::Unit::TestCase
|
5
|
+
include Forma::Utils
|
6
|
+
|
7
|
+
def test_number_format
|
8
|
+
assert_equal '123,456', number_format(123_456)
|
9
|
+
assert_equal '123,456.00', number_format(123_456, min_digits: 2)
|
10
|
+
assert_equal '123,456.79', number_format(123_456.789)
|
11
|
+
assert_equal '123,456.789', number_format(123_456.789, max_digits: 3)
|
12
|
+
assert_equal '123,456.789', number_format(123_456.789, max_digits: 4)
|
13
|
+
assert_equal '123,456.7890', number_format(123_456.789, max_digits: 4, min_digits: 4)
|
14
|
+
end
|
15
|
+
end
|
@@ -69,6 +69,35 @@
|
|
69
69
|
});
|
70
70
|
};
|
71
71
|
|
72
|
+
var initializeSelectActions = function() {
|
73
|
+
$('.ff-select-action').click(function() {
|
74
|
+
var valueId = window.name + '_id_value';
|
75
|
+
var typeId = window.name + '_type_value';
|
76
|
+
var labelId = window.name + '_text';
|
77
|
+
var valueElement = window.opener.$('#' + valueId);
|
78
|
+
var labelElement = window.opener.$('#' + labelId);
|
79
|
+
var typeElement = window.opener.$('#' + typeId);
|
80
|
+
valueElement.val($(this).attr('data-value-id'));
|
81
|
+
if (typeElement) { typeElement.val($(this).attr('data-value-type')); }
|
82
|
+
labelElement.html($(this).attr('data-value-text'));
|
83
|
+
labelElement.removeClass('ff-empty');
|
84
|
+
window.close();
|
85
|
+
return false;
|
86
|
+
});
|
87
|
+
$('.ff-clear-selection-action').click(function() {
|
88
|
+
var valueId = $(this).attr('data-id') + '_id_value';
|
89
|
+
var labelId = $(this).attr('data-id') + '_text';
|
90
|
+
var typeId = $(this).attr('data-id') + '_type_value';
|
91
|
+
var valueElement = $('#' + valueId);
|
92
|
+
var labelElement = $('#' + labelId);
|
93
|
+
var typeElement = $('#' + typeId);
|
94
|
+
valueElement.val(null);
|
95
|
+
if (typeElement) { typeElement.val(null); }
|
96
|
+
labelElement.text('(empty)');
|
97
|
+
labelElement.addClass('ff-empty');
|
98
|
+
});
|
99
|
+
};
|
100
|
+
|
72
101
|
// google map initialization
|
73
102
|
|
74
103
|
var mapsData = {};
|
@@ -121,6 +150,24 @@
|
|
121
150
|
}
|
122
151
|
};
|
123
152
|
|
153
|
+
var initPopovers = function() {
|
154
|
+
$('.ff-popover').popover({ trigger: 'click' });
|
155
|
+
};
|
156
|
+
|
157
|
+
var initDatePicker = function() {
|
158
|
+
var pickers = $('.ff-date');
|
159
|
+
for (var i = 0, l = pickers.length; i < l; i++) {
|
160
|
+
var picker = $(pickers[i]);
|
161
|
+
picker.datepicker({
|
162
|
+
dateFormat: 'dd-M-yy',
|
163
|
+
altField: '#' + picker.attr('data-altfield'), altFormat: 'yy-mm-dd',
|
164
|
+
onClose: function(dateText, inst) {
|
165
|
+
if(dateText == '') { $(inst.settings["altField"]).val(dateText); }
|
166
|
+
},
|
167
|
+
});
|
168
|
+
}
|
169
|
+
};
|
170
|
+
|
124
171
|
// prepare function
|
125
172
|
|
126
173
|
var ready = function() {
|
@@ -129,7 +176,11 @@
|
|
129
176
|
initializeFormSubmit();
|
130
177
|
initializeTooltips();
|
131
178
|
initGoogleMaps();
|
179
|
+
initPopovers();
|
180
|
+
initDatePicker();
|
181
|
+
// selectors
|
132
182
|
initializeSelectFields();
|
183
|
+
initializeSelectActions();
|
133
184
|
};
|
134
185
|
|
135
186
|
// turbolink initilization!
|
@@ -1,41 +1,47 @@
|
|
1
|
-
.user-select-none{user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none
|
2
|
-
.ff-form,.ff-table{margin-bottom:16px
|
3
|
-
.ff-form .ff-action img,.ff-table .ff-action img{padding-right:4px;height:16px;width:16px
|
4
|
-
.ff-form .ff-title,.ff-table .ff-title{position:relative
|
5
|
-
.ff-form .ff-title .ff-active-title img,.ff-table .ff-title .ff-active-title img{height:16px;width:16px;overflow:hidden;margin-right:4px
|
6
|
-
.ff-form .ff-title .ff-title-actions,.ff-table .ff-title .ff-title-actions{position:absolute;right:0;top:4px;padding:0 8px
|
7
|
-
.ff-form .ff-collapse,.ff-table .ff-collapse{background:url(/
|
8
|
-
.ff-form .ff-collapsed.ff-collapse,.ff-table .ff-collapsed.ff-collapse{background:url(/
|
9
|
-
.ff-form .ff-field-hint,.ff-table .ff-field-hint{background:url(/
|
10
|
-
.ff-form .ff-tabs,.ff-table .ff-tabs{padding:4px 0
|
11
|
-
.ff-form .ff-tabs ul.ff-tabs-header li.ff-selected,.ff-table .ff-tabs ul.ff-tabs-header li.ff-selected{background:#
|
12
|
-
.ff-form .ff-tabs .ff-tab-actions,.ff-table .ff-tabs .ff-tab-actions{padding:4px 8px;background:#
|
13
|
-
.ff-form .ff-tabs .ff-cols,.ff-table .ff-tabs .ff-cols{margin:4px 0 0 0;position:relative;font-size:13px
|
14
|
-
.ff-form .ff-tabs .ff-cols .ff-col-50,.ff-table .ff-tabs .ff-cols .ff-col-50{width:50%;float:left
|
15
|
-
.ff-form .ff-tabs .ff-cols .ff-col:first-child .ff-col-inner,.ff-table .ff-tabs .ff-cols .ff-col:first-child .ff-col-inner{padding-right:4px
|
16
|
-
.ff-form .ff-tabs .ff-cols .ff-col:last-child .ff-col-inner,.ff-table .ff-tabs .ff-cols .ff-col:last-child .ff-col-inner{padding-left:4px
|
17
|
-
.ff-form .ff-tabs .ff-cols .ff-col-inner,.ff-table .ff-tabs .ff-cols .ff-col-inner{padding:0;position:relative
|
18
|
-
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-label,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-label{display:table-cell;vertical-align:top;position:relative;width:150px;padding:4px 4px 4px 8px;background-color:#c8ffb0;border-right:3px solid transparent
|
19
|
-
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-label .ff-field-hint,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-label .ff-field-hint{display:block;height:16px;width:16px;position:absolute;right:0;top:8px;background-position:-96px -96px
|
20
|
-
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-value,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-value{display:table-cell;padding:4px;vertical-align:top
|
21
|
-
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-
|
22
|
-
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-field-
|
23
|
-
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-
|
24
|
-
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-
|
25
|
-
.ff-form .ff-tabs .ff-cols
|
26
|
-
.ff-form .ff-tabs
|
27
|
-
.ff-form .ff-tabs
|
28
|
-
.ff-form .ff-tabs
|
29
|
-
.ff-form .ff-tabs .ff-
|
30
|
-
.ff-form .ff-form-errors,.ff-table .ff-form-errors{margin:8px;padding:8px;border:1px solid red;background:#fee;color:red
|
31
|
-
.ff-form ul.ff-form-errors li,.ff-table ul.ff-form-errors li{margin-left:16px
|
32
|
-
.ff-form .ff-field-errors,.ff-table .ff-field-errors{color:red;padding:4px 0
|
33
|
-
.ff-form .ff-bottom-actions,.ff-table .ff-bottom-actions{padding:8px;border-top:1px solid #b1b1b1;background:#e0e0e0
|
34
|
-
.ff-form table.ff-common-table,.ff-table table.ff-common-table{margin-top:8px;width:100%;border-collapse:collapse
|
35
|
-
.ff-form table.ff-common-table thead .ff-field-hint,.ff-table table.ff-common-table thead .ff-field-hint{display:inline-block;height:16px;width:16px;background-position:-96px -96px
|
36
|
-
.ff-form table.ff-common-table tbody td,.ff-table table.ff-common-table tbody td{padding:4px 8px;border-bottom:1px solid #3316ff;}
|
37
|
-
.ff-
|
38
|
-
.ff-table-
|
39
|
-
.ff-
|
40
|
-
.ff-form .ff-
|
41
|
-
.
|
1
|
+
.user-select-none{user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}
|
2
|
+
.ff-form,.ff-table{margin-bottom:16px}.ff-form .ff-action,.ff-table .ff-action{margin-left:4px;font-size:13px}.ff-form .ff-action:first-child,.ff-table .ff-action:first-child{margin-left:0}
|
3
|
+
.ff-form .ff-action img,.ff-table .ff-action img{padding-right:4px;height:16px;width:16px}
|
4
|
+
.ff-form .ff-title,.ff-table .ff-title{position:relative}.ff-form .ff-title .ff-active-title,.ff-table .ff-title .ff-active-title{user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;cursor:pointer;display:inline-block;padding:4px 8px;font-weight:bold;font-size:14px}.ff-form .ff-title .ff-active-title .ff-collapse,.ff-table .ff-title .ff-active-title .ff-collapse{display:inline-block;height:14px;width:14px;margin-right:4px;margin-top:2px}
|
5
|
+
.ff-form .ff-title .ff-active-title img,.ff-table .ff-title .ff-active-title img{height:16px;width:16px;overflow:hidden;margin-right:4px}
|
6
|
+
.ff-form .ff-title .ff-title-actions,.ff-table .ff-title .ff-title-actions{position:absolute;right:0;top:4px;padding:0 8px}
|
7
|
+
.ff-form .ff-collapse,.ff-table .ff-collapse{background:url(/glyphicons-halflings.png) -313px -119px}
|
8
|
+
.ff-form .ff-collapsed.ff-collapse,.ff-table .ff-collapsed.ff-collapse{background:url(/glyphicons-halflings.png) -456px -72px}
|
9
|
+
.ff-form .ff-field-hint,.ff-table .ff-field-hint{background:url(/glyphicons-halflings.png) -456px -72px}
|
10
|
+
.ff-form .ff-tabs,.ff-table .ff-tabs{padding:4px 0}.ff-form .ff-tabs ul.ff-tabs-header,.ff-table .ff-tabs ul.ff-tabs-header{font-size:13px;list-style-type:none;margin:0;padding:0;position:relative;border-bottom:1px solid #b1b1b1}.ff-form .ff-tabs ul.ff-tabs-header li,.ff-table .ff-tabs ul.ff-tabs-header li{user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;cursor:pointer;display:inline-block;padding:4px 8px;margin-left:8px;margin-bottom:-1px;border:1px solid transparent}.ff-form .ff-tabs ul.ff-tabs-header li img,.ff-table .ff-tabs ul.ff-tabs-header li img{margin:0 4px;height:16px;width:16px}
|
11
|
+
.ff-form .ff-tabs ul.ff-tabs-header li.ff-selected,.ff-table .ff-tabs ul.ff-tabs-header li.ff-selected{background:#ffc;border:1px solid #b1b1b1;border-bottom:1px solid #ffc}
|
12
|
+
.ff-form .ff-tabs .ff-tab-actions,.ff-table .ff-tabs .ff-tab-actions{padding:4px 8px;background:#ffc;border:1px solid #b1b1b1;margin-top:-1px}
|
13
|
+
.ff-form .ff-tabs .ff-cols,.ff-table .ff-tabs .ff-cols{margin:4px 0 0 0;position:relative;font-size:13px}.ff-form .ff-tabs .ff-cols .ff-col-100,.ff-table .ff-tabs .ff-cols .ff-col-100{width:100%}
|
14
|
+
.ff-form .ff-tabs .ff-cols .ff-col-50,.ff-table .ff-tabs .ff-cols .ff-col-50{width:50%;float:left}
|
15
|
+
.ff-form .ff-tabs .ff-cols .ff-col:first-child .ff-col-inner,.ff-table .ff-tabs .ff-cols .ff-col:first-child .ff-col-inner{padding-right:4px}
|
16
|
+
.ff-form .ff-tabs .ff-cols .ff-col:last-child .ff-col-inner,.ff-table .ff-tabs .ff-cols .ff-col:last-child .ff-col-inner{padding-left:4px}
|
17
|
+
.ff-form .ff-tabs .ff-cols .ff-col-inner,.ff-table .ff-tabs .ff-cols .ff-col-inner{padding:0;position:relative}.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field{position:relative;border-bottom:1px solid #b1b1b1}.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field:first-child,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field:first-child{border-top:1px solid #b1b1b1}
|
18
|
+
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-label,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-label{display:table-cell;vertical-align:top;position:relative;width:150px;padding:4px 4px 4px 8px;background-color:#c8ffb0;border-right:3px solid transparent}.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-label.ff-required,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-label.ff-required{border-right:3px solid #cf0000}
|
19
|
+
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-label .ff-field-hint,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-label .ff-field-hint{display:block;height:16px;width:16px;position:absolute;right:0;top:8px;background-position:-96px -96px}
|
20
|
+
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-value,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-value{display:table-cell;padding:4px;vertical-align:top}.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-value .ff-field-actions,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-value .ff-field-actions{display:inline-block;border-left:1px solid #b1b1b1;padding-left:8px;margin-left:8px}
|
21
|
+
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-value.ff-value-no-label,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-value.ff-value-no-label{display:block}
|
22
|
+
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-select-field,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-select-field{display:inline-block}.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-select-field .ff-select-link,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-select-field .ff-select-link{margin-left:4px}
|
23
|
+
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-select-field .ff-select-label,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-select-field .ff-select-label{display:inline-block;padding:0 4px}
|
24
|
+
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-array-field,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-array-field{display:inline}.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-array-field .ff-array-part,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-array-field .ff-array-part{-webkit-border-radius:5px;-moz-border-radius:5px;-ms-border-radius:5px;-o-border-radius:5px;border-radius:5px;display:inline-block;margin:0 4px 4px 0;padding:2px 8px;border:1px solid #ddd;background:#fafafa}.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-array-field .ff-array-part .ff-action,.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-array-field .ff-array-part .ff-action{margin-left:4px}
|
25
|
+
.ff-form .ff-tabs .ff-cols:after,.ff-table .ff-tabs .ff-cols:after{content:".";display:block;clear:both;width:0;height:0;overflow:hidden}
|
26
|
+
.ff-form .ff-tabs input,.ff-table .ff-tabs input{padding:4px;margin:0;font-size:13px}
|
27
|
+
.ff-form .ff-tabs select,.ff-table .ff-tabs select{padding:4px;margin:0;font-size:13px;width:auto}
|
28
|
+
.ff-form .ff-tabs .ff-error input,.ff-table .ff-tabs .ff-error input{border:1px solid red;color:red;background:#fff8f8}
|
29
|
+
.ff-form .ff-tabs .ff-inline-hint,.ff-table .ff-tabs .ff-inline-hint{padding:4px 2px;color:#88f;font-size:12px}
|
30
|
+
.ff-form .ff-form-errors,.ff-table .ff-form-errors{margin:8px;padding:8px;border:1px solid red;background:#fee;color:red}
|
31
|
+
.ff-form ul.ff-form-errors li,.ff-table ul.ff-form-errors li{margin-left:16px}
|
32
|
+
.ff-form .ff-field-errors,.ff-table .ff-field-errors{color:red;padding:4px 0}
|
33
|
+
.ff-form .ff-bottom-actions,.ff-table .ff-bottom-actions{padding:8px;border-top:1px solid #b1b1b1;background:#e0e0e0}
|
34
|
+
.ff-form table.ff-common-table,.ff-table table.ff-common-table{margin-top:8px;width:100%;border-collapse:collapse}.ff-form table.ff-common-table thead,.ff-table table.ff-common-table thead{text-align:left;border-top:1px solid #3316ff;border-bottom:1px solid #3316ff;background:#c8ffb0}.ff-form table.ff-common-table thead th,.ff-table table.ff-common-table thead th{font-size:13px;font-weight:normal;padding:4px 8px}
|
35
|
+
.ff-form table.ff-common-table thead .ff-field-hint,.ff-table table.ff-common-table thead .ff-field-hint{display:inline-block;height:16px;width:16px;background-position:-96px -96px}
|
36
|
+
.ff-form table.ff-common-table tbody td,.ff-table table.ff-common-table tbody td{font-size:13px;padding:4px 8px;border-bottom:1px solid #3316ff;background:white}
|
37
|
+
.ff-form .ff-paginate .ff-totals,.ff-table .ff-paginate .ff-totals{padding:4px}.ff-form .ff-paginate .ff-totals span,.ff-table .ff-paginate .ff-totals span{padding-left:4px}
|
38
|
+
.ff-form .ff-field-before,.ff-table .ff-field-before{padding-right:8px}
|
39
|
+
.ff-form .ff-field-after,.ff-table .ff-field-after{padding-left:8px}
|
40
|
+
.ff-form .ff-complex-field .ff-complex-part,.ff-table .ff-complex-field .ff-complex-part{display:inline-block;padding-right:8px}
|
41
|
+
.ff-form .ff-complex-field .ff-field,.ff-table .ff-complex-field .ff-field{display:inline-block;border:none;padding-right:8px}
|
42
|
+
.ff-form .ff-select-field,.ff-table .ff-select-field{-webkit-border-radius:5px;-moz-border-radius:5px;-ms-border-radius:5px;-o-border-radius:5px;border-radius:5px;border:1px solid #ddd;padding:3px 3px 2px 3px;background:#ffc}.ff-form .ff-select-field .ff-select-label,.ff-table .ff-select-field .ff-select-label{min-width:100px}
|
43
|
+
.ff-empty{color:#a0a0a0}
|
44
|
+
.ff-table-empty{padding:32px;text-align:center;background-color:#f6f6f6;border:1px solid #a0a0a0;border-top:none}
|
45
|
+
.ff-map{width:100%;height:100%;overflow:hidden;position:absolute;top:0;left:0;right:0;bottom:0}.ff-map img{max-width:none}
|
46
|
+
.ff-form .ff-title,.ff-table .ff-title{background-color:#cfc8ff;border-bottom:2px solid #3316ff;border-top:2px solid #3316ff}
|
47
|
+
.tooltip-inner{white-space:pre;max-width:none}
|
@@ -11,6 +11,7 @@
|
|
11
11
|
.ff-form .ff-action,
|
12
12
|
.ff-table .ff-action {
|
13
13
|
margin-left: 4px;
|
14
|
+
font-size: 13px;
|
14
15
|
}
|
15
16
|
.ff-form .ff-action:first-child,
|
16
17
|
.ff-table .ff-action:first-child {
|
@@ -62,15 +63,15 @@
|
|
62
63
|
}
|
63
64
|
.ff-form .ff-collapse,
|
64
65
|
.ff-table .ff-collapse {
|
65
|
-
background: url(/
|
66
|
+
background: url(/glyphicons-halflings.png) -313px -119px;
|
66
67
|
}
|
67
68
|
.ff-form .ff-collapsed.ff-collapse,
|
68
69
|
.ff-table .ff-collapsed.ff-collapse {
|
69
|
-
background: url(/
|
70
|
+
background: url(/glyphicons-halflings.png) -456px -72px;
|
70
71
|
}
|
71
72
|
.ff-form .ff-field-hint,
|
72
73
|
.ff-table .ff-field-hint {
|
73
|
-
background: url(/
|
74
|
+
background: url(/glyphicons-halflings.png) -456px -72px;
|
74
75
|
}
|
75
76
|
.ff-form .ff-tabs,
|
76
77
|
.ff-table .ff-tabs {
|
@@ -78,8 +79,10 @@
|
|
78
79
|
}
|
79
80
|
.ff-form .ff-tabs ul.ff-tabs-header,
|
80
81
|
.ff-table .ff-tabs ul.ff-tabs-header {
|
82
|
+
font-size: 13px;
|
81
83
|
list-style-type: none;
|
82
84
|
margin: 0;
|
85
|
+
padding: 0;
|
83
86
|
position: relative;
|
84
87
|
border-bottom: 1px solid #b1b1b1;
|
85
88
|
}
|
@@ -189,28 +192,43 @@
|
|
189
192
|
padding-left: 8px;
|
190
193
|
margin-left: 8px;
|
191
194
|
}
|
192
|
-
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-
|
193
|
-
.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-
|
194
|
-
|
195
|
-
}
|
196
|
-
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-field-after,
|
197
|
-
.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-field-after {
|
198
|
-
padding-left: 8px;
|
199
|
-
}
|
200
|
-
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-complex-field .ff-complex-part,
|
201
|
-
.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-complex-field .ff-complex-part {
|
202
|
-
display: inline-block;
|
203
|
-
padding-right: 8px;
|
195
|
+
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-value.ff-value-no-label,
|
196
|
+
.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-value.ff-value-no-label {
|
197
|
+
display: block;
|
204
198
|
}
|
205
|
-
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-
|
206
|
-
.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-
|
199
|
+
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-select-field,
|
200
|
+
.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-select-field {
|
207
201
|
display: inline-block;
|
208
|
-
border: none;
|
209
|
-
padding-right: 8px;
|
210
202
|
}
|
211
203
|
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-select-field .ff-select-link,
|
212
204
|
.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-select-field .ff-select-link {
|
213
|
-
margin-left:
|
205
|
+
margin-left: 4px;
|
206
|
+
}
|
207
|
+
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-select-field .ff-select-label,
|
208
|
+
.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-select-field .ff-select-label {
|
209
|
+
display: inline-block;
|
210
|
+
padding: 0 4px;
|
211
|
+
}
|
212
|
+
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-array-field,
|
213
|
+
.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-array-field {
|
214
|
+
display: inline;
|
215
|
+
}
|
216
|
+
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-array-field .ff-array-part,
|
217
|
+
.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-array-field .ff-array-part {
|
218
|
+
-webkit-border-radius: 5px;
|
219
|
+
-moz-border-radius: 5px;
|
220
|
+
-ms-border-radius: 5px;
|
221
|
+
-o-border-radius: 5px;
|
222
|
+
border-radius: 5px;
|
223
|
+
display: inline-block;
|
224
|
+
margin: 0 4px 4px 0;
|
225
|
+
padding: 2px 8px;
|
226
|
+
border: 1px solid #ddd;
|
227
|
+
background: #fafafa;
|
228
|
+
}
|
229
|
+
.ff-form .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-array-field .ff-array-part .ff-action,
|
230
|
+
.ff-table .ff-tabs .ff-cols .ff-col-inner .ff-field .ff-array-field .ff-array-part .ff-action {
|
231
|
+
margin-left: 4px;
|
214
232
|
}
|
215
233
|
.ff-form .ff-tabs .ff-cols:after,
|
216
234
|
.ff-table .ff-tabs .ff-cols:after {
|
@@ -240,6 +258,12 @@
|
|
240
258
|
color: red;
|
241
259
|
background: #fff8f8;
|
242
260
|
}
|
261
|
+
.ff-form .ff-tabs .ff-inline-hint,
|
262
|
+
.ff-table .ff-tabs .ff-inline-hint {
|
263
|
+
padding: 4px 2px;
|
264
|
+
color: #88f;
|
265
|
+
font-size: 12px;
|
266
|
+
}
|
243
267
|
.ff-form .ff-form-errors,
|
244
268
|
.ff-table .ff-form-errors {
|
245
269
|
margin: 8px;
|
@@ -278,6 +302,7 @@
|
|
278
302
|
}
|
279
303
|
.ff-form table.ff-common-table thead th,
|
280
304
|
.ff-table table.ff-common-table thead th {
|
305
|
+
font-size: 13px;
|
281
306
|
font-weight: normal;
|
282
307
|
padding: 4px 8px;
|
283
308
|
}
|
@@ -290,8 +315,52 @@
|
|
290
315
|
}
|
291
316
|
.ff-form table.ff-common-table tbody td,
|
292
317
|
.ff-table table.ff-common-table tbody td {
|
318
|
+
font-size: 13px;
|
293
319
|
padding: 4px 8px;
|
294
320
|
border-bottom: 1px solid #3316ff;
|
321
|
+
background: white;
|
322
|
+
}
|
323
|
+
.ff-form .ff-paginate .ff-totals,
|
324
|
+
.ff-table .ff-paginate .ff-totals {
|
325
|
+
padding: 4px;
|
326
|
+
}
|
327
|
+
.ff-form .ff-paginate .ff-totals span,
|
328
|
+
.ff-table .ff-paginate .ff-totals span {
|
329
|
+
padding-left: 4px;
|
330
|
+
}
|
331
|
+
.ff-form .ff-field-before,
|
332
|
+
.ff-table .ff-field-before {
|
333
|
+
padding-right: 8px;
|
334
|
+
}
|
335
|
+
.ff-form .ff-field-after,
|
336
|
+
.ff-table .ff-field-after {
|
337
|
+
padding-left: 8px;
|
338
|
+
}
|
339
|
+
.ff-form .ff-complex-field .ff-complex-part,
|
340
|
+
.ff-table .ff-complex-field .ff-complex-part {
|
341
|
+
display: inline-block;
|
342
|
+
padding-right: 8px;
|
343
|
+
}
|
344
|
+
.ff-form .ff-complex-field .ff-field,
|
345
|
+
.ff-table .ff-complex-field .ff-field {
|
346
|
+
display: inline-block;
|
347
|
+
border: none;
|
348
|
+
padding-right: 8px;
|
349
|
+
}
|
350
|
+
.ff-form .ff-select-field,
|
351
|
+
.ff-table .ff-select-field {
|
352
|
+
-webkit-border-radius: 5px;
|
353
|
+
-moz-border-radius: 5px;
|
354
|
+
-ms-border-radius: 5px;
|
355
|
+
-o-border-radius: 5px;
|
356
|
+
border-radius: 5px;
|
357
|
+
border: 1px solid #ddd;
|
358
|
+
padding: 3px 3px 2px 3px;
|
359
|
+
background: #ffffcc;
|
360
|
+
}
|
361
|
+
.ff-form .ff-select-field .ff-select-label,
|
362
|
+
.ff-table .ff-select-field .ff-select-label {
|
363
|
+
min-width: 100px;
|
295
364
|
}
|
296
365
|
.ff-empty {
|
297
366
|
color: #a0a0a0;
|
data/vendor/less/forma.less
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
.user-select-none { user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;}
|
2
2
|
.rounded-corners(@radius: 5px) { -webkit-border-radius: @radius; -moz-border-radius: @radius; -ms-border-radius: @radius; -o-border-radius: @radius; border-radius: @radius; }
|
3
3
|
|
4
|
-
@halflings: url(/
|
5
|
-
@halflings-white: url(/
|
4
|
+
@halflings: url(/glyphicons-halflings.png);
|
5
|
+
@halflings-white: url(/glyphicons-halflings-white.png);
|
6
6
|
@border-color: #b1b1b1;
|
7
7
|
@selected-tab-color: #ffffcc;
|
8
8
|
@base-font-size: 13px;
|
@@ -15,6 +15,7 @@
|
|
15
15
|
margin-bottom: 16px;
|
16
16
|
.ff-action {
|
17
17
|
margin-left: 4px;
|
18
|
+
font-size: 13px;
|
18
19
|
&:first-child { margin-left: 0; };
|
19
20
|
img { padding-right: 4px; height: 16px; width: 16px; }
|
20
21
|
}
|
@@ -33,7 +34,8 @@
|
|
33
34
|
.ff-tabs {
|
34
35
|
padding: 4px 0;
|
35
36
|
ul.ff-tabs-header {
|
36
|
-
|
37
|
+
font-size: 13px;
|
38
|
+
list-style-type: none; margin: 0; padding: 0; position: relative;
|
37
39
|
border-bottom: 1px solid @border-color;
|
38
40
|
li { .user-select-none; cursor: pointer; display: inline-block;
|
39
41
|
padding: 4px 8px; margin-left: 8px; margin-bottom: -1px;
|
@@ -74,15 +76,21 @@
|
|
74
76
|
.ff-value {
|
75
77
|
display: table-cell; padding: 4px; vertical-align: top;
|
76
78
|
.ff-field-actions { display: inline-block; border-left: 1px solid @border-color; padding-left: 8px; margin-left: 8px; }
|
77
|
-
|
78
|
-
.ff-field-before { padding-right: 8px; }
|
79
|
-
.ff-field-after { padding-left: 8px; }
|
80
|
-
.ff-complex-field {
|
81
|
-
.ff-complex-part { display: inline-block; padding-right: 8px; }
|
82
|
-
.ff-field { display: inline-block; border: none; padding-right: 8px; }
|
79
|
+
&.ff-value-no-label { display: block; }
|
83
80
|
}
|
84
81
|
.ff-select-field {
|
85
|
-
|
82
|
+
display: inline-block;
|
83
|
+
.ff-select-link { margin-left: 4px; }
|
84
|
+
.ff-select-label { display: inline-block; padding: 0 4px; }
|
85
|
+
}
|
86
|
+
.ff-array-field {
|
87
|
+
display: inline;
|
88
|
+
.ff-array-part {
|
89
|
+
.rounded-corners; display: inline-block; margin: 0 4px 4px 0;
|
90
|
+
padding: 2px 8px; border: 1px solid #ddd;
|
91
|
+
background: #fafafa;
|
92
|
+
.ff-action { margin-left: 4px; }
|
93
|
+
}
|
86
94
|
}
|
87
95
|
}
|
88
96
|
}
|
@@ -91,6 +99,7 @@
|
|
91
99
|
input { padding: 4px; margin: 0; font-size: @base-font-size; }
|
92
100
|
select { padding: 4px; margin: 0; font-size: @base-font-size; width: auto; }
|
93
101
|
.ff-error input { border: 1px solid red; color: red; background: #fff8f8; }
|
102
|
+
.ff-inline-hint { padding: 4px 2px; color: #88f; font-size: 12px; }
|
94
103
|
}
|
95
104
|
.ff-form-errors { margin: 8px; padding: 8px; border: 1px solid red; background: #fee; color: red;}
|
96
105
|
ul.ff-form-errors { li { margin-left: 16px; } }
|
@@ -102,16 +111,40 @@
|
|
102
111
|
border-top: 1px solid @blue-theme-border;
|
103
112
|
border-bottom: 1px solid @blue-theme-border;
|
104
113
|
background: @label-background;
|
105
|
-
th { font-weight: normal; padding: 4px 8px; }
|
114
|
+
th { font-size: 13px; font-weight: normal; padding: 4px 8px; }
|
106
115
|
.ff-field-hint { display: inline-block; height: 16px; width: 16px; background-position: -96px -96px; }
|
107
116
|
}
|
108
117
|
tbody {
|
109
|
-
td {
|
118
|
+
td {
|
119
|
+
font-size: 13px;
|
120
|
+
padding: 4px 8px; border-bottom: 1px solid @blue-theme-border;
|
121
|
+
background: white;
|
122
|
+
}
|
110
123
|
}
|
111
124
|
}
|
125
|
+
.ff-paginate {
|
126
|
+
.ff-totals {
|
127
|
+
padding: 4px;
|
128
|
+
span { padding-left: 4px; }
|
129
|
+
}
|
130
|
+
}
|
131
|
+
.ff-field-before { padding-right: 8px; }
|
132
|
+
.ff-field-after { padding-left: 8px; }
|
133
|
+
.ff-complex-field {
|
134
|
+
.ff-complex-part { display: inline-block; padding-right: 8px; }
|
135
|
+
.ff-field { display: inline-block; border: none; padding-right: 8px; }
|
136
|
+
}
|
137
|
+
.ff-select-field {
|
138
|
+
.rounded-corners;
|
139
|
+
border: 1px solid #ddd;
|
140
|
+
padding: 3px 3px 2px 3px;
|
141
|
+
background: @selected-tab-color;
|
142
|
+
.ff-select-label { min-width: 100px; }
|
143
|
+
}
|
112
144
|
}
|
113
145
|
.ff-empty { color: #a0a0a0; }
|
114
146
|
.ff-table-empty { padding: 32px; text-align: center; background-color: #f6f6f6; border: 1px solid #a0a0a0; border-top: none; }
|
147
|
+
//.ff-table-body { background: white; }
|
115
148
|
|
116
149
|
.ff-map {
|
117
150
|
width:100%; height:100%; overflow:hidden; position: absolute;
|
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: forma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Dimitri Kurashvili
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-01-04 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: bundler
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,23 +27,20 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rspec
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
45
|
- - ~>
|
52
46
|
- !ruby/object:Gem::Version
|
@@ -54,7 +48,6 @@ dependencies:
|
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
52
|
- - ~>
|
60
53
|
- !ruby/object:Gem::Version
|
@@ -62,7 +55,6 @@ dependencies:
|
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: therubyracer
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
59
|
- - ~>
|
68
60
|
- !ruby/object:Gem::Version
|
@@ -70,7 +62,6 @@ dependencies:
|
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
66
|
- - ~>
|
76
67
|
- !ruby/object:Gem::Version
|
@@ -78,7 +69,6 @@ dependencies:
|
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: less
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
73
|
- - ~>
|
84
74
|
- !ruby/object:Gem::Version
|
@@ -86,7 +76,6 @@ dependencies:
|
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
80
|
- - ~>
|
92
81
|
- !ruby/object:Gem::Version
|
@@ -94,33 +83,29 @@ dependencies:
|
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: railties
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
|
-
- -
|
87
|
+
- - '>='
|
100
88
|
- !ruby/object:Gem::Version
|
101
89
|
version: '3.1'
|
102
90
|
type: :runtime
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
|
-
- -
|
94
|
+
- - '>='
|
108
95
|
- !ruby/object:Gem::Version
|
109
96
|
version: '3.1'
|
110
97
|
- !ruby/object:Gem::Dependency
|
111
98
|
name: activesupport
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
100
|
requirements:
|
115
|
-
- -
|
101
|
+
- - '>='
|
116
102
|
- !ruby/object:Gem::Version
|
117
103
|
version: '0'
|
118
104
|
type: :runtime
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
107
|
requirements:
|
123
|
-
- -
|
108
|
+
- - '>='
|
124
109
|
- !ruby/object:Gem::Version
|
125
110
|
version: '0'
|
126
111
|
description: rich forms for ruby
|
@@ -157,6 +142,7 @@ files:
|
|
157
142
|
- test/field_test.rb
|
158
143
|
- test/form_test.rb
|
159
144
|
- test/test_helper.rb
|
145
|
+
- test/utils_test.rb
|
160
146
|
- vendor/assets/images/ff-icons.png
|
161
147
|
- vendor/assets/javascripts/forma.js
|
162
148
|
- vendor/assets/stylesheets/forma-min.css
|
@@ -165,27 +151,26 @@ files:
|
|
165
151
|
homepage: http://github.com/dimakura/forma
|
166
152
|
licenses:
|
167
153
|
- MIT
|
154
|
+
metadata: {}
|
168
155
|
post_install_message:
|
169
156
|
rdoc_options: []
|
170
157
|
require_paths:
|
171
158
|
- lib
|
172
159
|
required_ruby_version: !ruby/object:Gem::Requirement
|
173
|
-
none: false
|
174
160
|
requirements:
|
175
|
-
- -
|
161
|
+
- - '>='
|
176
162
|
- !ruby/object:Gem::Version
|
177
163
|
version: '0'
|
178
164
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
|
-
none: false
|
180
165
|
requirements:
|
181
|
-
- -
|
166
|
+
- - '>='
|
182
167
|
- !ruby/object:Gem::Version
|
183
168
|
version: '0'
|
184
169
|
requirements: []
|
185
170
|
rubyforge_project:
|
186
|
-
rubygems_version:
|
171
|
+
rubygems_version: 2.0.3
|
187
172
|
signing_key:
|
188
|
-
specification_version:
|
173
|
+
specification_version: 4
|
189
174
|
summary: rich forms for ruby
|
190
175
|
test_files:
|
191
176
|
- spec/config_spec.rb
|
@@ -197,3 +182,4 @@ test_files:
|
|
197
182
|
- test/field_test.rb
|
198
183
|
- test/form_test.rb
|
199
184
|
- test/test_helper.rb
|
185
|
+
- test/utils_test.rb
|