Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Fetching contributors…
Cannot retrieve contributors at this time
188 lines (143 sloc) 4.52 KB


Make this:

Complex data form

using this:

@form ={
  sections: [{
    title: "Register",
    rows: [{
      title: "Email",
      key: :email,
      placeholder: "",
      type: :email,
      auto_correction: :no,
      auto_capitalization: :none
    }, {
      title: "Password",
      key: :password,
      placeholder: "required",
      type: :string,
      secure: true
    }, {
      title: "Password",
      subtitle: "Confirmation",
      key: :confirm,
      placeholder: "required",
      type: :string,
      secure: true
    }, {
      title: "Remember?",
      key: :remember,
      type: :switch,
  }, {
    title: "Account Type",
    key: :account_type,
    select_one: true,
    rows: [{
      title: "Free",
      key: :free,
      type: :check,
    }, {
      title: "Basic",
      value: true,
      key: :basic,
      type: :check,
    }, {
      title: "Pro",
      key: :pro,
      type: :check,
  }, {
    rows: [{
      title: "Sign Up",
      type: :submit,

@form_controller = Formotion::FormController.alloc.initWithForm(@form)
@window.rootViewController = @form_controller

And after the user enters some data, do this:

=> {:email=>"", :password=>"password", 
    :confirm=>"password", :remember=>true, :account_type=>:pro}


gem install formotion

In your Rakefile:

require 'formotion'



You can initialize a Formotion::Form using either a hash (as above) or the DSL:

form =

form.build_section do |section|
  section.title = "Title"

  section.build_row do |row|
    row.title = "Label"
    row.subtitle = "Placeholder"
    row.type = :string

Then attach it to a Formotion::FormController and you're ready to rock and roll:

@controller = Formotion::FormController.alloc.initWithForm(form)
self.navigationController.pushViewController(@controller, animated: true)

Data Types

See the visual list of support row types.

To add your own, check the guide to adding new row types.

Formotion::Form, Formotion::Section, and Formotion::Row all respond to a ::PROPERTIES attribute. These are settable as an attribute (ie section.title = 'title') or in the initialization hash (ie {sections: [{title: 'title', ...}]}). Check the comments in the 3 main files (form.rb, section.rb, and row.rb for details on what these do).


You have form#submit, form#on_submit, and form#render at your disposal. Here's an example:

class PeopleController < Formotion::FormController
  def viewDidLoad

    self.navigationItem.rightBarButtonItem = UIBarButtonItem.alloc.initWithBarButtonSystemItem(UIBarButtonSystemItemSave, target:self, action:'submit')

  def submit
    data = self.form.render = data[:name]
    person.address = data[:address]

Why would you use form#on_submit? In case you want to use type: :submit. Ex:

@form ={
  sections: [{
  }, {
    rows: [{
      title: "Save",
      type: :submit

@form.on_submit do |form|
  # do something with form.render

form#submit just triggers form#on_submit.


You can easily synchronize a Form's state to disk using the persist_as key in conjunction with the persist method. When your user edits the form, any changes will be immediately saved. For example:

@form = Formotion::Form.persist({
  persist_as: :settings,
  sections: ...

This will load the form if it exists, or create it if necessary. If you use, then the form will not be loaded and any changes you make will override existing saved forms.

Your form values and state are automatically persisted across application loads, no save buttons needed.

To reset the form, persist it and call reset, which restores it to the original state.

View the Persistence Example to see it in action.


Feel free to fork and submit pull requests! And if you end up using Formotion in your app, I'd love to hear about your experience.


  • Not very efficient right now (creates a unique reuse idenitifer for each cell)
  • Styling/overriding the form for custom UITableViewDelegate/Data Source behaviors.
Jump to Line
Something went wrong with that request. Please try again.