ProMotion-XLForm 0.0.7 → 0.0.8

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.
@@ -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 = self.cells.copy
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
- return nil if options.nil? or options.empty?
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
- options.map do |key, text|
28
- val = key
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 = NSLocalizedString('Cancel', nil)
17
- item = :cancel
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 = on_cancel[:item] if on_cancel[:item]
20
+ item = on_cancel[:item] if on_cancel[:item]
21
21
  end
22
22
 
23
23
  set_nav_bar_button :left, {
24
- system_item: item,
25
- title: title,
26
- action: 'on_cancel:'
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 = NSLocalizedString('Save', nil)
33
- item = :save
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 = on_cancel[:item] if on_cancel[:item]
36
+ item = on_cancel[:item] if on_cancel[:item]
37
37
  end
38
38
 
39
39
  set_nav_bar_button :right, {
40
- system_item: item,
41
- title: title,
42
- action: 'on_save:'
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 = self.class.title
57
- required = form_options[: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
- title: title,
62
- required: required
61
+ title: title,
62
+ required: required
63
63
  })
64
- @form_object = @form_builder.build
65
- self.form = @form_object
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
- if value.is_a? XLFormOptionsObject
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 = UIAlertController.alertControllerWithTitle(NSLocalizedString('Error', nil),
95
- message: errors.join(', '),
96
- preferredStyle: UIAlertControllerStyleAlert)
98
+ alert = UIAlertController.alertControllerWithTitle(NSLocalizedString('Error', nil),
99
+ message: errors.join(', '),
100
+ preferredStyle: UIAlertControllerStyleAlert)
97
101
  action = UIAlertAction.actionWithTitle(NSLocalizedString('OK', nil),
98
- style: UIAlertActionStyleDefault,
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 = UIAlertView.new
104
- alert.title = NSLocalizedString('Error', nil)
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
- callback = @form_builder.get_callback(section, :on_add)
208
- callback.call if callback
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
- callback = @form_builder.get_callback(section, :on_remove)
214
- callback.call if callback
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
- callback = @form_builder.get_callback(row, :on_add)
220
- callback.call if callback
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
- callback = @form_builder.get_callback(row, :on_remove)
226
- callback.call if callback
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
@@ -43,7 +43,7 @@ module ProMotion
43
43
  self.should_autorotate
44
44
  end
45
45
 
46
- def willRotateToInterfaceOrientation(orientation, duration:duration)
46
+ def willRotateToInterfaceOrientation(orientation, duration: duration)
47
47
  self.will_rotate(orientation, duration)
48
48
  end
49
49
 
@@ -4,34 +4,34 @@ module ProMotion
4
4
 
5
5
  def form_data
6
6
  [
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 and rowDescriptor.value and rowDescriptor.value[tag]
15
- cell.merge({ value: rowDescriptor.value[tag] })
16
- else
17
- cell
18
- end
19
- end
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 = rowDescriptor.title
26
- required = rowDescriptor.action.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
- title: title,
31
- required: required
30
+ title: title,
31
+ required: required
32
32
  })
33
- @form_object = @form_builder.build
34
- self.form = @form_object
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