class Formotion::Form

Constants

PROPERTIES
SERIALIZE_PROPERTIES

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

Attributes

active_row[R]
controller[R]
table[R]

Public Class Methods

build(&block) click to toggle source
# File lib/formotion/form/form.rb, line 56
def build(&block)
  form = new
  block.call(form)
  form
end
new(params = {}) click to toggle source
Calls superclass method Formotion::Base::new
# 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
persist(params = {}) click to toggle source
# File lib/formotion/form/form.rb, line 25
def self.persist(params = {})
  form = new(params)
  form
end

Public Instance Methods

active_row=(row) click to toggle source
# File lib/formotion/form/form_delegate.rb, line 9
def active_row=(row)
  @active_row = row

  if @active_row && @table
    index_path = NSIndexPath.indexPathForRow(@active_row.index, inSection:@active_row.section.index)
    @table.scrollToRowAtIndexPath(index_path, atScrollPosition:UITableViewScrollPositionMiddle,  animated:true)
  end
end
build_section(&block) click to toggle source

Use this as a DSL for adding sections EX @form.build_section do |section|

section.title = 'Section Title'

end

# File lib/formotion/form/form.rb, line 68
def build_section(&block)
  section = create_section
  block.call(section)
  section
end
controller=(controller) click to toggle source

Table Methods

# File lib/formotion/form/form_delegate.rb, line 20
def controller=(controller)
  @controller = controller
  @controller.title = self.title
  self.table = @controller.tableView
end
create_section(hash = {}) click to toggle source

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

# 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
fill_out(data)
Alias for: values=
init_observer_for_save() click to toggle source

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

# 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_persist() click to toggle source
# File lib/formotion/form/form.rb, line 43
def initialize_persist
  self.open
  self.init_observer_for_save
  self
end
numberOfSectionsInTableView(tableView) click to toggle source

UITableViewDataSource Methods

# File lib/formotion/form/form_delegate.rb, line 46
def numberOfSectionsInTableView(tableView)
  self.sections.count
end
on_submit(&block) click to toggle source

Stores the callback block when you do submit. EX @form.on_submit do

do_something(@form.render)

end

EX @form.on_submit do |form|

pass_to_server(form.render)

end

# File lib/formotion/form/form.rb, line 130
def on_submit(&block)
  @on_submit_callback = block
end
open() click to toggle source
# 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_data() click to toggle source
# 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
render() click to toggle source

A hashification with the user's inputted values and row keys. EX @form = Formotion::Form.new(sections: [{

rows: [{
  key: 'Email',
  editable: true,
  title: 'Email'
}]}])

…user plays with the Form… @form.render

> {email: 'something@email.com'}

# 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
reset() click to toggle source
# File lib/formotion/form/form.rb, line 310
def reset
  App::Persistence[persist_key] = App::Persistence[original_persist_key]
  open
end
row(key) click to toggle source
# 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) click to toggle source

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

# 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
save() click to toggle source

places hash of values into application persistance

# 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
sections() click to toggle source

attributes

# File lib/formotion/form/form.rb, line 88
def sections
  @sections ||= []
end
sections=(sections) click to toggle source
# 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_render() click to toggle source
# 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
submit() click to toggle source

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

# 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
table=(table_view) click to toggle source
# File lib/formotion/form/form_delegate.rb, line 26
def table=(table_view)
  @table = table_view

  @table.delegate = self
  @table.dataSource = self
  reload_data
end
tableView(tableView, numberOfRowsInSection: section) click to toggle source
# File lib/formotion/form/form_delegate.rb, line 50
def tableView(tableView, numberOfRowsInSection: section)
  self.sections[section].rows.count
end
to_hash() click to toggle source

A complete hashification of the Form EX @form = Formotion::Form.new(title: 'My Title') @form.id = 'anything' @form.to_hash

> {title: 'My Title', id: 'anything'}

Calls superclass method Formotion::Base#to_hash
# 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) click to toggle source
# 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
Also aliased as: fill_out

Private Instance Methods

each_row(&block) click to toggle source
# File lib/formotion/form/form.rb, line 338
def each_row(&block)
  self.sections.each_with_index do |section, s_index|
    section.rows.each_with_index do |row, index|
      case block.arity
      when 1
        block.call(row)
      when 2
        block.call(row, index)
      end
    end
  end
end
load_state() click to toggle source
# File lib/formotion/form/form.rb, line 325
def load_state
  state = App::Persistence[persist_key]
  # support old archived format
  if state.respond_to? :unarchive
    begin
      form = Formotion::Form.new(state.unarchive)
      state = form.render
      p "Old archived data found: #{state}"
    end
  end
  state
end
original_persist_key() click to toggle source
# File lib/formotion/form/form.rb, line 321
def original_persist_key
  "#{persist_key}_ORIGINAL"
end
persist_key() click to toggle source
# File lib/formotion/form/form.rb, line 317
def persist_key
  "FORMOTION_#{self.persist_as}"
end
recursive_delete_nil(h) click to toggle source
# File lib/formotion/form/form.rb, line 351
def recursive_delete_nil(h)
  delete_empty = Proc.new { |k, v|
    v.delete_if(&delete_empty) if v.kind_of?(Hash)
    v.nil?
  }
  h.delete_if &delete_empty
end