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, #initWithCoder

Constructor Details

#initialize(params = {}) ⇒ Form

Returns a new instance of Form.



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

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}))
  }
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



49
50
51
52
53
# File 'lib/formotion/form/form.rb', line 49

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

.persist(params = {}) ⇒ Object



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

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

Instance Method Details

#build_section(&block) ⇒ Object

Use this as a DSL for adding sections EX end



61
62
63
64
65
# File 'lib/formotion/form/form.rb', line 61

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’)



70
71
72
73
74
75
76
# File 'lib/formotion/form/form.rb', line 70

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



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/formotion/form/form.rb', line 240

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

#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



119
120
121
# File 'lib/formotion/form/form.rb', line 119

def on_submit(&block)
  @on_submit_callback = block
end

#openObject



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/formotion/form/form.rb', line 258

def open
  @form_observer ||= lambda { |form, 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 row.subform?
          @form_observer.call(row.subform.to_form, saved_row_value)
        elsif row.type == :template
          row.value = saved_row_value
          row.object.update_template_rows
        else
          row.value = saved_row_value
        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]



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/formotion/form/form.rb', line 169

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



290
291
292
293
# File 'lib/formotion/form/form.rb', line 290

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

#row(key) ⇒ Object



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

def row(key)
  each_row do |row|
    return row if row.key == key
  end
  nil
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))



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

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



285
286
287
288
# File 'lib/formotion/form/form.rb', line 285

def save
  App::Persistence[persist_key] = render
  App::Persistence[original_persist_key] ||= render
end

#sectionsObject

attributes



81
82
83
# File 'lib/formotion/form/form.rb', line 81

def sections
  @sections ||= []
end

#sections=(sections) ⇒ Object



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

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

#sub_renderObject



196
197
198
199
200
201
202
203
204
# File 'lib/formotion/form/form.rb', line 196

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.



126
127
128
129
130
131
132
133
134
135
136
# File 'lib/formotion/form/form.rb', line 126

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’



147
148
149
150
151
152
153
154
155
# File 'lib/formotion/form/form.rb', line 147

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



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/formotion/form/form.rb', line 206

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