forma 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|