ProMotion-XLForm 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +46 -1
- data/lib/ProMotion-XLForm.rb +4 -0
- data/lib/ProMotion/XLForm/cells/xl_form_cell.rb +12 -0
- data/lib/ProMotion/XLForm/cells/xl_form_color_selector_cell.rb +17 -17
- data/lib/ProMotion/XLForm/cells/xl_form_image_selector_cell.rb +80 -78
- data/lib/ProMotion/XLForm/validators/regex_validator.rb +1 -1
- data/lib/ProMotion/XLForm/xl_form.rb +54 -311
- data/lib/ProMotion/XLForm/xl_form_cell_builder.rb +182 -0
- data/lib/ProMotion/XLForm/xl_form_helper.rb +65 -0
- data/lib/ProMotion/XLForm/xl_form_patch.rb +78 -10
- data/lib/ProMotion/XLForm/xl_form_screen.rb +88 -40
- data/lib/ProMotion/XLForm/xl_form_section_builder.rb +48 -0
- data/lib/ProMotion/XLForm/xl_form_view_controller.rb +1 -1
- data/lib/ProMotion/XLForm/xl_sub_form_screen.rb +21 -21
- metadata +20 -2
@@ -0,0 +1,65 @@
|
|
1
|
+
module ProMotion
|
2
|
+
module XLFormHelper
|
3
|
+
|
4
|
+
def configure_hidden(cell_or_section, predicate)
|
5
|
+
tag = operand = value = nil
|
6
|
+
if predicate.is_a?(Hash)
|
7
|
+
tag = predicate[:name]
|
8
|
+
operand = case predicate[:is]
|
9
|
+
when :equal
|
10
|
+
'=='
|
11
|
+
when :not_equal
|
12
|
+
'!='
|
13
|
+
when :contains
|
14
|
+
'contains'
|
15
|
+
when :not_contains
|
16
|
+
'not contains'
|
17
|
+
else
|
18
|
+
predicate[:is]
|
19
|
+
end
|
20
|
+
value = predicate[:value]
|
21
|
+
else
|
22
|
+
match = /(:?[a-zA-Z_]+)\s+(==|!=|contains|not contains)\s+(.*)/.match(predicate)
|
23
|
+
if match && match.length == 4
|
24
|
+
# todo better than ignore ?
|
25
|
+
tag = match[1]
|
26
|
+
operand = match[2]
|
27
|
+
value = match[3]
|
28
|
+
if value =~ /"(.*)"/
|
29
|
+
value = value[1, value.length - 2]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
if tag && operand
|
35
|
+
if tag.is_a?(Symbol)
|
36
|
+
tag = tag.to_s
|
37
|
+
elsif tag.start_with?(':')
|
38
|
+
tag[0] = ''
|
39
|
+
end
|
40
|
+
value = case value
|
41
|
+
when nil
|
42
|
+
'nil'
|
43
|
+
when 'true', :true, true
|
44
|
+
0
|
45
|
+
when 'false', :false, false
|
46
|
+
1
|
47
|
+
when String
|
48
|
+
"\"#{value}\""
|
49
|
+
else
|
50
|
+
value
|
51
|
+
end
|
52
|
+
|
53
|
+
if operand == 'contains'
|
54
|
+
cell_or_section.hidden = "$#{tag} contains[c] #{value}"
|
55
|
+
elsif operand == 'not contains'
|
56
|
+
cell_or_section.hidden = "not($#{tag} contains[c] #{value})"
|
57
|
+
else
|
58
|
+
cell_or_section.hidden = "$#{tag} #{operand} #{value}"
|
59
|
+
end
|
60
|
+
else
|
61
|
+
mp predicate: predicate.inspect, message: "predicate can not be parsed", force_color: :red
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -9,7 +9,7 @@ class XLFormAction
|
|
9
9
|
def copyWithZone(zone)
|
10
10
|
action_copy = old_copyWithZone(zone)
|
11
11
|
|
12
|
-
action_copy.cells
|
12
|
+
action_copy.cells = self.cells.copy
|
13
13
|
action_copy.required = self.required
|
14
14
|
action_copy
|
15
15
|
end
|
@@ -17,20 +17,88 @@ end
|
|
17
17
|
|
18
18
|
class XLFormRowDescriptor
|
19
19
|
|
20
|
+
attr_accessor :cell_data
|
21
|
+
|
22
|
+
alias :old_copyWithZone :copyWithZone
|
23
|
+
|
24
|
+
def copyWithZone(zone)
|
25
|
+
row_copy = old_copyWithZone(zone)
|
26
|
+
row_copy.cell_data = cell_data
|
27
|
+
row_copy
|
28
|
+
end
|
29
|
+
|
20
30
|
def options=(options)
|
21
31
|
self.selectorOptions = parse_options(options)
|
22
32
|
end
|
23
33
|
|
24
34
|
def parse_options(options)
|
25
|
-
|
35
|
+
return nil if options.nil? || options.empty?
|
36
|
+
|
37
|
+
options.map do |key, text|
|
38
|
+
val = key
|
39
|
+
if val.is_a? Symbol
|
40
|
+
val = val.to_s
|
41
|
+
end
|
42
|
+
XLFormOptionsObject.formOptionsObjectWithValue(val, displayText: text)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class XLFormSectionDescriptor
|
48
|
+
attr_accessor :section_data, :options
|
49
|
+
|
50
|
+
def self.section(section_data)
|
51
|
+
title = section_data[:title]
|
52
|
+
|
53
|
+
options = section_data.fetch(:options, :none)
|
54
|
+
options = parse_section_options(options)
|
55
|
+
insert_mode = section_insert_mode(section_data[:insert_mode])
|
56
|
+
|
57
|
+
section = XLFormSectionDescriptor.formSectionWithTitle(title, sectionOptions: options, sectionInsertMode: insert_mode)
|
58
|
+
section.section_data = section_data
|
59
|
+
section.options = options
|
60
|
+
section
|
61
|
+
end
|
62
|
+
|
63
|
+
def options=(value)
|
64
|
+
@options = self.class.parse_section_options(value)
|
65
|
+
end
|
66
|
+
|
67
|
+
def options
|
68
|
+
@options
|
69
|
+
end
|
70
|
+
|
71
|
+
def sectionOptions
|
72
|
+
options
|
73
|
+
end
|
26
74
|
|
27
|
-
|
28
|
-
|
29
|
-
if val.is_a? Symbol
|
30
|
-
val = val.to_s
|
31
|
-
end
|
32
|
-
XLFormOptionsObject.formOptionsObjectWithValue(val, displayText: text)
|
33
|
-
end
|
34
|
-
end
|
75
|
+
def self.parse_section_options(options)
|
76
|
+
return section_options(:none) if options.nil?
|
35
77
|
|
78
|
+
opts = section_options(:none)
|
79
|
+
unless options.is_a?(Array)
|
80
|
+
options = [options]
|
81
|
+
end
|
82
|
+
options.each do |opt|
|
83
|
+
opts |= section_options(opt)
|
84
|
+
end
|
85
|
+
|
86
|
+
opts
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.section_insert_mode(symbol)
|
90
|
+
{
|
91
|
+
last_row: XLFormSectionInsertModeLastRow,
|
92
|
+
button: XLFormSectionInsertModeButton
|
93
|
+
}[symbol] || symbol || XLFormSectionInsertModeLastRow
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.section_options(symbol)
|
97
|
+
{
|
98
|
+
none: XLFormSectionOptionNone,
|
99
|
+
insert: XLFormSectionOptionCanInsert,
|
100
|
+
delete: XLFormSectionOptionCanDelete,
|
101
|
+
reorder: XLFormSectionOptionCanReorder
|
102
|
+
}[symbol] || symbol || XLFormSectionOptionNone
|
103
|
+
end
|
36
104
|
end
|
@@ -13,33 +13,33 @@ module ProMotion
|
|
13
13
|
|
14
14
|
if form_options[:on_cancel]
|
15
15
|
on_cancel = form_options[:on_cancel]
|
16
|
-
title
|
17
|
-
item
|
16
|
+
title = NSLocalizedString('Cancel', nil)
|
17
|
+
item = :cancel
|
18
18
|
if on_cancel.is_a? Hash
|
19
19
|
title = on_cancel[:title] if on_cancel[:title]
|
20
|
-
item
|
20
|
+
item = on_cancel[:item] if on_cancel[:item]
|
21
21
|
end
|
22
22
|
|
23
23
|
set_nav_bar_button :left, {
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
system_item: item,
|
25
|
+
title: title,
|
26
|
+
action: 'on_cancel:'
|
27
27
|
}
|
28
28
|
end
|
29
29
|
|
30
30
|
if form_options[:on_save]
|
31
31
|
on_cancel = form_options[:on_save]
|
32
|
-
title
|
33
|
-
item
|
32
|
+
title = NSLocalizedString('Save', nil)
|
33
|
+
item = :save
|
34
34
|
if on_cancel.is_a? Hash
|
35
35
|
title = on_cancel[:title] if on_cancel[:title]
|
36
|
-
item
|
36
|
+
item = on_cancel[:item] if on_cancel[:item]
|
37
37
|
end
|
38
38
|
|
39
39
|
set_nav_bar_button :right, {
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
system_item: item,
|
41
|
+
title: title,
|
42
|
+
action: 'on_save:'
|
43
43
|
}
|
44
44
|
end
|
45
45
|
|
@@ -53,30 +53,34 @@ module ProMotion
|
|
53
53
|
|
54
54
|
def update_form_data
|
55
55
|
form_options = self.class.get_form_options
|
56
|
-
title
|
57
|
-
required
|
56
|
+
title = self.class.title
|
57
|
+
required = form_options[:required]
|
58
58
|
|
59
59
|
@form_builder = PM::XLForm.new(self.form_data,
|
60
60
|
{
|
61
|
-
|
62
|
-
|
61
|
+
title: title,
|
62
|
+
required: required
|
63
63
|
})
|
64
|
-
@form_object
|
65
|
-
self.form
|
64
|
+
@form_object = @form_builder.build
|
65
|
+
self.form = @form_object
|
66
66
|
end
|
67
67
|
|
68
68
|
def values
|
69
69
|
values = {}
|
70
70
|
formValues.each do |key, value|
|
71
|
-
|
72
|
-
value = value.formValue
|
73
|
-
end
|
74
|
-
values[key] = value
|
71
|
+
values[key] = clean_value(value)
|
75
72
|
end
|
76
73
|
|
77
74
|
values
|
78
75
|
end
|
79
76
|
|
77
|
+
def value_for_cell(tag)
|
78
|
+
if tag.respond_to?(:to_s)
|
79
|
+
tag = tag.to_s
|
80
|
+
end
|
81
|
+
values.has_key?(tag) ? values[tag] : nil
|
82
|
+
end
|
83
|
+
|
80
84
|
def valid?
|
81
85
|
validation_errors.empty?
|
82
86
|
end
|
@@ -91,23 +95,31 @@ module ProMotion
|
|
91
95
|
end
|
92
96
|
|
93
97
|
if NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1
|
94
|
-
alert
|
95
|
-
|
96
|
-
|
98
|
+
alert = UIAlertController.alertControllerWithTitle(NSLocalizedString('Error', nil),
|
99
|
+
message: errors.join(', '),
|
100
|
+
preferredStyle: UIAlertControllerStyleAlert)
|
97
101
|
action = UIAlertAction.actionWithTitle(NSLocalizedString('OK', nil),
|
98
|
-
style:
|
102
|
+
style: UIAlertActionStyleDefault,
|
99
103
|
handler: nil)
|
100
104
|
alert.addAction(action)
|
101
105
|
presentViewController(alert, animated: true, completion: nil)
|
102
106
|
else
|
103
|
-
alert
|
104
|
-
alert.title
|
107
|
+
alert = UIAlertView.new
|
108
|
+
alert.title = NSLocalizedString('Error', nil)
|
105
109
|
alert.message = errors.join(', ')
|
106
110
|
alert.addButtonWithTitle(NSLocalizedString('OK', nil))
|
107
111
|
alert.show
|
108
112
|
end
|
109
113
|
end
|
110
114
|
|
115
|
+
def section_with_tag(tag)
|
116
|
+
if tag.respond_to? :to_s
|
117
|
+
tag = tag.to_s
|
118
|
+
end
|
119
|
+
self.form.formSections.select { |section| section.multivaluedTag && section.multivaluedTag == tag }
|
120
|
+
.first
|
121
|
+
end
|
122
|
+
|
111
123
|
def cell_with_tag(tag)
|
112
124
|
if tag.respond_to? :to_s
|
113
125
|
tag = tag.to_s
|
@@ -202,28 +214,32 @@ module ProMotion
|
|
202
214
|
end
|
203
215
|
|
204
216
|
## XLFormDescriptorDelegate
|
205
|
-
def formSectionHasBeenAdded(section, atIndex:
|
217
|
+
def formSectionHasBeenAdded(section, atIndex: index)
|
206
218
|
super
|
207
|
-
|
208
|
-
|
219
|
+
action = @form_builder.get_callback(section, :on_add)
|
220
|
+
return if action.nil?
|
221
|
+
trigger_action(action, row, index_path)
|
209
222
|
end
|
210
223
|
|
211
|
-
def formSectionHasBeenRemoved(section, atIndex:
|
224
|
+
def formSectionHasBeenRemoved(section, atIndex: index)
|
212
225
|
super
|
213
|
-
|
214
|
-
|
226
|
+
action = @form_builder.get_callback(section, :on_remove)
|
227
|
+
return if action.nil?
|
228
|
+
trigger_action(action, section, index)
|
215
229
|
end
|
216
230
|
|
217
|
-
def formRowHasBeenAdded(row, atIndexPath:
|
231
|
+
def formRowHasBeenAdded(row, atIndexPath: index_path)
|
218
232
|
super
|
219
|
-
|
220
|
-
|
233
|
+
action = @form_builder.get_callback(row, :on_add)
|
234
|
+
return if action.nil?
|
235
|
+
trigger_action(action, row, index_path)
|
221
236
|
end
|
222
237
|
|
223
|
-
def formRowHasBeenRemoved(row, atIndexPath:
|
238
|
+
def formRowHasBeenRemoved(row, atIndexPath: index_path)
|
224
239
|
super
|
225
|
-
|
226
|
-
|
240
|
+
action = @form_builder.get_callback(row, :on_remove)
|
241
|
+
return if action.nil?
|
242
|
+
trigger_action(action, row, index_path)
|
227
243
|
end
|
228
244
|
|
229
245
|
def formRowDescriptorValueHasChanged(row, oldValue: old_value, newValue: new_value)
|
@@ -241,5 +257,37 @@ module ProMotion
|
|
241
257
|
end
|
242
258
|
end
|
243
259
|
|
260
|
+
def formRowFormMultivaluedFormSection(section)
|
261
|
+
if section.multivaluedRowTemplate
|
262
|
+
cell_data = section.multivaluedRowTemplate.cell_data
|
263
|
+
else
|
264
|
+
cell_data = section.section_data[:cells].first
|
265
|
+
end
|
266
|
+
|
267
|
+
@form_builder.create_cell(cell_data)
|
268
|
+
end
|
269
|
+
|
270
|
+
private
|
271
|
+
def trigger_action(action, section_or_row, index_path)
|
272
|
+
case arity = action.arity
|
273
|
+
when 0 then
|
274
|
+
action.call # Just call the proc or the method
|
275
|
+
when 2 then
|
276
|
+
action.call(section_or_row, index_path) # Send arguments and index path
|
277
|
+
else
|
278
|
+
mp("Action should not have optional parameters: #{action.to_s}", force_color: :yellow) if arity < 0
|
279
|
+
action.call(section_or_row)
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
def clean_value(value)
|
284
|
+
if value.is_a? XLFormOptionsObject
|
285
|
+
value = value.formValue
|
286
|
+
elsif value.is_a? Array
|
287
|
+
value = value.map { |v| clean_value(v) }
|
288
|
+
end
|
289
|
+
|
290
|
+
value
|
291
|
+
end
|
244
292
|
end
|
245
293
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module ProMotion
|
2
|
+
module XLFormSectionBuilder
|
3
|
+
|
4
|
+
def create_section(section_data)
|
5
|
+
section = XLFormSectionDescriptor.section(section_data)
|
6
|
+
|
7
|
+
tag = section_data[:name]
|
8
|
+
if tag.respond_to? :to_s
|
9
|
+
tag = tag.to_s
|
10
|
+
end
|
11
|
+
unless section.options.nil?
|
12
|
+
mp("MutliValued section with no :name option", force_color: :red) unless tag
|
13
|
+
end
|
14
|
+
|
15
|
+
# force a tag for procs
|
16
|
+
if tag.nil?
|
17
|
+
@section_index ||= 0
|
18
|
+
tag = "section_#{@section_index}"
|
19
|
+
end
|
20
|
+
section.multivaluedTag = tag
|
21
|
+
|
22
|
+
section.footerTitle = section_data[:footer] if section_data[:footer]
|
23
|
+
|
24
|
+
add_proc tag, :on_add, section_data[:on_add] if section_data[:on_add]
|
25
|
+
add_proc tag, :on_remove, section_data[:on_remove] if section_data[:on_remove]
|
26
|
+
|
27
|
+
# section visible
|
28
|
+
if section_data[:hidden]
|
29
|
+
configure_hidden(section, section_data[:hidden])
|
30
|
+
end
|
31
|
+
|
32
|
+
section_data[:cells].each do |cell_data|
|
33
|
+
cell = create_cell(cell_data)
|
34
|
+
|
35
|
+
section.addFormRow(cell)
|
36
|
+
|
37
|
+
# multi sections
|
38
|
+
if section.multivaluedTag
|
39
|
+
cell.action.required = @required
|
40
|
+
section.multivaluedRowTemplate = cell.copy
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
section
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -4,34 +4,34 @@ module ProMotion
|
|
4
4
|
|
5
5
|
def form_data
|
6
6
|
[
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
7
|
+
{
|
8
|
+
title: rowDescriptor.title,
|
9
|
+
cells: rowDescriptor.action.cells.map do |cell|
|
10
|
+
tag = cell[:name]
|
11
|
+
if tag.respond_to? :to_s
|
12
|
+
tag = tag.to_s
|
13
|
+
end
|
14
|
+
if rowDescriptor && rowDescriptor.value && rowDescriptor.value[tag]
|
15
|
+
cell.merge({ value: rowDescriptor.value[tag] })
|
16
|
+
else
|
17
|
+
cell
|
18
|
+
end
|
19
|
+
end
|
20
|
+
}
|
21
21
|
]
|
22
22
|
end
|
23
23
|
|
24
24
|
def update_form_data
|
25
|
-
title
|
26
|
-
required
|
25
|
+
title = rowDescriptor.title
|
26
|
+
required = rowDescriptor.action.required
|
27
27
|
|
28
28
|
@form_builder = PM::XLForm.new(self.form_data,
|
29
29
|
{
|
30
|
-
|
31
|
-
|
30
|
+
title: title,
|
31
|
+
required: required
|
32
32
|
})
|
33
|
-
@form_object
|
34
|
-
self.form
|
33
|
+
@form_object = @form_builder.build
|
34
|
+
self.form = @form_object
|
35
35
|
end
|
36
36
|
|
37
37
|
## XLFormDescriptorDelegate
|
@@ -40,4 +40,4 @@ module ProMotion
|
|
40
40
|
rowDescriptor.value = values
|
41
41
|
end
|
42
42
|
end
|
43
|
-
end
|
43
|
+
end
|