Class: Formotion::Form

Inherits:
Base show all
Extended by:
BubbleWrap::KVO
Includes:
BubbleWrap::KVO
Defined in:
lib/formotion/form/form.rb,
lib/formotion/form/form_delegate.rb

Constant Summary collapse

PROPERTIES =
[
  # By default, Formotion::Controller will set it's title to this
  # (so navigation bars will reflect it).
  :title,
  # If you want to have some internal id to track the form.
  :id,
  # [STRING/SYMBOL] used to store your form's state on disk
  :persist_as
]
SERIALIZE_PROPERTIES =

Sections are create specially using #create_section, so we don’t allow them to be pased in the hash

PROPERTIES + [:sections]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#copyWithZone, #encodeWithCoder, #hash, #initWithCoder, #isEqual

Constructor Details

#initialize(params = {}) ⇒ Form

Returns a new instance of Form.



30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/formotion/form/form.rb', line 30

def initialize(params = {})
  # super takes care of initializing the ::PROPERTIES in params
  super

  sections = params[:sections] || params["sections"]
  sections && sections.each_with_index {|section_hash, index|
    section = create_section(section_hash.merge({index: index}))
  }

  initialize_persist unless self.persist_as.nil?

end

Instance Attribute Details

#active_rowObject

Returns the value of attribute active_row.



7
8
9
# File 'lib/formotion/form/form_delegate.rb', line 7

def active_row
  @active_row
end

#controllerObject

Returns the value of attribute controller.



6
7
8
# File 'lib/formotion/form/form_delegate.rb', line 6

def controller
  @controller
end

#tableObject

Returns the value of attribute table.



5
6
7
# File 'lib/formotion/form/form_delegate.rb', line 5

def table
  @table
end

Class Method Details

.build(&block) ⇒ Object



56
57
58
59
60
# File 'lib/formotion/form/form.rb', line 56

def build(&block)
  form = new
  block.call(form)
  form
end

.persist(params = {}) ⇒ Object



25
26
27
28
# File 'lib/formotion/form/form.rb', line 25

def self.persist(params = {})
  form = new(params)
  form
end

Instance Method Details

#build_section(&block) ⇒ Object

Use this as a DSL for adding sections EX end



68
69
70
71
72
# File 'lib/formotion/form/form.rb', line 68

def build_section(&block)
  section = create_section
  block.call(section)
  section
end

#create_section(hash = {}) ⇒ Object

Use this to add sections via a hash EX @form.create_section(:title => ‘Section Title’)



77
78
79
80
81
82
83
# File 'lib/formotion/form/form.rb', line 77

def create_section(hash = {})
  hash = hash.merge({:form => self})
  section = Formotion::Section.new(hash)
  section.index = self.sections.count
  self.sections << section
  section
end

#init_observer_for_saveObject

loads the given settings into the the form, and places observers to save on changes



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/formotion/form/form.rb', line 251

def init_observer_for_save
  @form_save_observer ||= lambda { |form|
    form.sections.each_with_index do |section, s_index|
      section.rows.each_with_index do |row, index|
        if row.subform?
          @form_save_observer.call(row.subform.to_form)
        elsif !row.templated?
          observe(row, "value") do |old_value, new_value|
            self.save
          end
        end
      end
    end
  }

  @form_save_observer.call(self)
end

#initialize_persistObject



43
44
45
46
47
# File 'lib/formotion/form/form.rb', line 43

def initialize_persist
  self.open
  self.init_observer_for_save
  self
end

#numberOfSectionsInTableView(tableView) ⇒ Object

UITableViewDataSource Methods



46
47
48
# File 'lib/formotion/form/form_delegate.rb', line 46

def numberOfSectionsInTableView(tableView)
  self.sections.count
end

#on_submit(&block) ⇒ Object

Stores the callback block when you do #submit. EX end

EX end



130
131
132
# File 'lib/formotion/form/form.rb', line 130

def on_submit(&block)
  @on_submit_callback = block
end

#openObject



269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/formotion/form/form.rb', line 269

def open
  @form_observer ||= ->(form, saved_render, uses_display_key = false) {
    no_saved_render = saved_render.nil?
    saved_render ||= {}

    form.sections.each_with_index do |section, s_index|
      section.rows.each_with_index do |row, index|
        next if row.templated?
        saved_row_value = saved_render[row.key]

        if uses_display_key && section.select_one && saved_render.include?(section.key.to_s)
          saved_row_value = row.key.to_s == saved_render[section.key.to_s].to_s
        end

        if row.subform?
          @form_observer.call(row.subform.to_form, saved_row_value, !!row.display_key)
        elsif row.type == :template
          row.value = saved_row_value
          row.object.update_template_rows
        else
          row.value = saved_row_value if !no_saved_render
        end
      end
    end
  }
  rendered_data = load_state
  if rendered_data
    @form_observer.call(self, rendered_data)
  else
    save
  end
end

#reload_dataObject



34
35
36
37
38
39
40
41
42
43
# File 'lib/formotion/form/form_delegate.rb', line 34

def reload_data
  previous_row, next_row = nil

  last_row = self.sections[-1] && self.sections[-1].rows[-1]
  if last_row && last_row.type != :text
    last_row.return_key ||= UIReturnKeyDone
  end

  @table.reloadData
end

#renderObject

A hashification with the user’s inputted values and row keys. EX …user plays with the Form…

> ‘[email protected]



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/formotion/form/form.rb', line 180

def render
  kv = {}
  self.sections.each {|section|
    if section.select_one?
      section.rows.each {|row|
        if row.value
          kv[section.key] = row.key
        end
      }
    else
      section.rows.each {|row|
        next if row.button?
        if row.templated?
          # If this row is part of a template
          # use the parent's key
          kv[row.template_parent.key] = row.template_parent.value
        else
          kv[row.key] ||= row.value_for_save_hash
        end
      }
    end
  }
  kv.merge! sub_render
  kv.delete_if {|k, v| k.nil? }
  kv
end

#resetObject



310
311
312
313
# File 'lib/formotion/form/form.rb', line 310

def reset
  App::Persistence[persist_key] = App::Persistence[original_persist_key]
  open
end

#row(key) ⇒ Object



106
107
108
109
110
111
112
113
114
115
# File 'lib/formotion/form/form.rb', line 106

def row(key)
  found = nil
  each_row do |row|
    if row.key == key
      found = row
      break
    end
  end
  found
end

#row_for_index_path(index_path) ⇒ Object

Accepts an NSIndexPath and gives back a Formotion::Row EX row = @form.row_for_index_path(NSIndexPath.indexPathForRow(0, inSection: 0))



102
103
104
# File 'lib/formotion/form/form.rb', line 102

def row_for_index_path(index_path)
  self.sections[index_path.section].rows[index_path.row]
end

#saveObject

places hash of values into application persistance



303
304
305
306
307
308
# File 'lib/formotion/form/form.rb', line 303

def save
  rendered = render
  recursive_delete_nil(rendered)
  App::Persistence[persist_key] = rendered
  App::Persistence[original_persist_key] ||= rendered
end

#sectionsObject

attributes



88
89
90
# File 'lib/formotion/form/form.rb', line 88

def sections
  @sections ||= []
end

#sections=(sections) ⇒ Object



92
93
94
95
96
97
# File 'lib/formotion/form/form.rb', line 92

def sections=(sections)
  sections.each {|section|
    Formotion::Conditions.assert_class(section, Formotion::Section)
  }
  @sections = sections
end

#sub_renderObject



207
208
209
210
211
212
213
214
215
# File 'lib/formotion/form/form.rb', line 207

def sub_render
  kv = {}
  rows = sections.map(&:rows).flatten
  subform_rows = rows.select{ |row| row.subform != nil }
  subform_rows.each do |subform_row|
    kv[subform_row.key] = subform_row.subform.to_form.render
  end
  kv
end

#submitObject

Triggers the #on_submit block Handles either zero or one arguments, as shown above.



137
138
139
140
141
142
143
144
145
146
147
# File 'lib/formotion/form/form.rb', line 137

def submit
  if @on_submit_callback.nil?
    return
  end

  if @on_submit_callback.arity == 0
    @on_submit_callback.call
  elsif @on_submit_callback.arity == 1
    @on_submit_callback.call(self)
  end
end

#tableView(tableView, shouldIndentWhileEditingRowAtIndexPath: indexPath) ⇒ Object

UITableViewDelegate Methods



92
93
94
# File 'lib/formotion/form/form_delegate.rb', line 92

def tableView(tableView, numberOfRowsInSection: section)
  self.sections[section].rows.count
end

#to_hashObject

A complete hashification of the Form EX

> ‘My Title’, id: ‘anything’



158
159
160
161
162
163
164
165
166
# File 'lib/formotion/form/form.rb', line 158

def to_hash
  # super handles all of the ::PROPERTIES
  h = super
  h[:sections] = self.sections.collect { |section|
    section.to_hash
  }
  recursive_delete_nil(h)
  h
end

#values=(data) ⇒ Object Also known as: fill_out



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/formotion/form/form.rb', line 217

def values=(data)
  self.sections.each {|section|
    if section.select_one?
      # see if one of the select one value is used
      unless (section.rows.map{ |r| r.key } & data.keys).empty?
        section.rows.each { |row|
          row.value = data.has_key?(row.key) ? true : nil
        }
      end
    else
      section.rows.each {|row|
        next if row.button?
        if row.template_parent
          # If this row is part of a template
          # use the parent's key
          row.value = data[row.template_parent_key] if data.has_key?(row.template_parent_key)
        elsif row.subform
          row.subform.to_form.values = data
        else
          row.value = data[row.key] if data.has_key?(row.key)
        end
      }
    end
  }
end