The most flexible and powerful way to build a form on iOS.
Form came out from our need to have a form that could share logic between our iOS apps and our web clients. We found that JSON was the best way to achieve this.
Form includes the following features:
- Multiple groups: For example, you can have a group for personal details and another one for shipping information
- Field validations: We support
required
,max_length
,min_length
,min_value
,max_value
andformat
(regex). We also support many field types, liketext
,number
,phone_number
,email
,date
,name
,count
and more - Custom sizes: Total
width
is handled as 100% whileheight
is handled in chunks of 85 px - Custom fields: You can register your custom fields, and it's pretty simple (our basic example includes how to make an
image
field) - Formulas or computed values: We support fields that contain generated values from other fields
- Targets:
hide
,show
,update
,enable
,disable
orclear
a field using a target. It's pretty powerful, and you can even set a condition for your target to run - Dropdowns: Generating dropdowns is as easy as adding values to your field, values support
default
flags, targets (in case you want to trigger hiding a field based on a selection), string and numeric values or showing additional info (in case you want to hint the consequences of your selection).
Form works both on the iPhone and the iPad.
You can try one of our demos by running this command in your Terminal:
pod try Form
This are the required steps to create a basic form with a first name field.
[
{
"id":"group-id",
"title":"Group title",
"sections":[
{
"id":"section-0",
"fields":[
{
"id":"first_name",
"title":"First name",
"type":"name",
"size":{
"width":30,
"height":1
}
}
]
}
]
}
]
AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Don't forget to set your style, or use the default one if you want
[FORMDefaultStyle applyStyle];
//...
}
Subclass
Make sure that your UICollectionViewController
is a subclass of FORMViewController
.
Targets are one of the most powerful features of form, and we support to hide
, show
, update
, enable
, disable
or clear
a field using a target. You can even set a condition for your target to run!
In the following example we show how to hide or show a field based on a dropdown selection.
[
{
"id":"group-id",
"title":"Group title",
"sections":[
{
"id":"section-0",
"fields":[
{
"id":"employment_type",
"title":"Employment type",
"type":"select",
"size":{
"width":30,
"height":1
},
"values":[
{
"id":0,
"title":"Part time",
"default":true,
"targets":[
{
"id":"bonus",
"type":"field",
"action":"hide"
}
]
},
{
"id":1,
"title":"Full time",
"targets":[
{
"id":"bonus",
"type":"field",
"action":"show"
}
]
}
]
},
{
"id":"bonus",
"title":"Bonus",
"type":"number",
"size":{
"width":30,
"height":1
}
}
]
}
]
}
]
Form allows global and per-field styling. The table below shows the per-field styling options.
Target | Description | JSON Key | Value Type | Example (Default) |
---|---|---|---|---|
Groups | Background Color | background_color |
Hex |
"background_color":"#FFFFFF" |
Header Text Color | text_color |
Hex |
"text_color":"#455C73" |
|
Font | font |
String |
"font":"AvenirNext-Medium" |
|
Font Size | font_size |
Float |
"font_size":"17.0" |
|
--- | ||||
Sections | Separator Color | separator_color |
Hex |
"separator_color":"#C6C6C6" |
--- | ||||
Buttons | Background Color | background_color |
Hex |
"background_color":"#3DAFEB" |
Highlighted Background Color | highlighted_background_color |
Hex |
"highlighted_background_color":"#FFFFFF" |
|
Title Color | title_color |
Hex |
"title_color":"#FFFFFF" |
|
Highlighted Title Color | highlighted_title_color |
Hex |
"highlighted_title_color":"#3DAFEB" |
|
Border Color | border_color |
Hex |
"border_color":"#3DAFEB" |
|
Corner Radius | corner_radius |
Float |
"corner_radius":"5.0" |
|
Border Width | border_width |
Float |
"border_width":"1.0" |
|
Font | font |
String |
"font":"AvenirNext-DemiBold" |
|
Font Size | font_size |
Float |
"font_size":"16.0" |
|
--- | ||||
Text Fields | Font | font |
String |
"font":"AvenirNext-Regular" |
Font Size | font_size |
Float |
"font_size":"15.0" |
|
Corner Radius | corner_radius |
Float |
"corner_radius":"5.0" |
|
Border Width | border_width |
Float |
"border_width":"1.0" |
|
Active Background Color | active_background_color |
Hex |
"active_background_color":"#C0EAFF" |
|
Active Border Color | active_border_color |
Hex |
"active_border_color":"#3DAFEB" |
|
Inactive Background Color | inactive_background_color |
Hex |
"inactive_background_color":"#E1F5FF" |
|
Inactive Border Color | inactive_border_color |
Hex |
"inactive_border_color":"#3DAFEB" |
|
Enabled Background Color | enabled_background_color |
Hex |
"enabled_background_color":"#E1F5FF" |
|
Enabled Border Color | enabled_border_color |
Hex |
"enabled_border_color":"#3DAFEB" |
|
Enabled Text Color | enabled_text_color |
Hex |
"enabled_text_color":"#455C73" |
|
Disabled Background Color | disabled_background_color |
Hex |
"disabled_background_color":"#F5F5F8" |
|
Disabled Border Color | disabled_border_color |
Hex |
"disabled_border_color":"#DEDEDE" |
|
Disabled Text Color | disabled_text_color |
Hex |
"disabled_text_color":"#808080" |
|
Valid Background Color | valid_background_color |
Hex |
"valid_background_color":"#E1F5FF" |
|
Valid Border Color | valid_border_color |
Hex |
"valid_border_color":"#3DAFEB" |
|
Invalid Background Color | invalid_background_color |
Hex |
"invalid_background_color":"#FFD7D7" |
|
Invalid Border Color | invalid_border_color |
Hex |
"invalid_border_color":"#EC3031" |
|
Tooltip Font | tooltip_font |
String |
"tooltip_font":"AvenirNext-Medium" |
|
Tooltip Font Size | tooltip_font_size |
Float |
"tooltip_font_size":"14.0" |
|
Tooltip Label Text Color | tooltip_label_text_color |
Hex |
"tooltip_label_text_color":"#97591D" |
|
(not functional) | Tooltip Background Color | tooltip_background_color |
Hex |
"tooltip_background_color":"#FDFD54" |
Clear Button Color | clear_button_color |
Hex |
"clear_button_color":"#3DAFEB" |
|
Minus Button Color | minus_button_color |
Hex |
"minus_button_color":"#3DAFEB" |
|
Plus Button Color | plus_button_color |
Hex |
"plus_button_color":"#3DAFEB" |
|
Field Labels | Heading Label Font | heading_label_font |
String |
"heading_label_font":"AvenirNext-Medium" |
Heading Label Font Size | heading_label_font_size |
Float |
"heading_label_font_size":"17.0" |
|
Heading Label Text Color | heading_label_text_color |
Hex |
"heading_label_text_color":"#455C73" |
[
{
"id":"group-id",
"title":"Group title",
"styles":{
"background_color":"#FFFFFF",
"text_color":"#455C73",
"font":"AvenirNext-Medium",
"font_size":"17.0"
},
"sections":[
{
"id":"section-0",
"styles":{
"separator_color":"#60B044"
},
"fields":[
{
"id":"first_name",
"title":"First name",
"info":"This field is optional",
"type":"name",
"styles":{
"font":"AvenirNext-Regular",
"font_size":"15.0",
"corner_radius":"5.0",
"border_width":"2.0",
"active_background_color":"#60B044",
"active_border_color":"#418F26",
"inactive_background_color":"#B2B2E0",
"inactive_border_color":"#000099",
"enabled_background_color":"#CBEDBF",
"enabled_border_color":"#418F26",
"enabled_text_color":"#163F07",
"disabled_background_color":"#EEEEEE",
"disabled_border_color":"#CCCCCC",
"disabled_text_color":"#777777",
"valid_background_color":"#FFC2FF",
"valid_border_color":"#662966",
"invalid_background_color":"#FFD7D7",
"invalid_border_color":"#EC3031",
"tooltip_font":"AvenirNext",
"tooltip_font_size":"14.0",
"tooltip_label_text_color":"#163F07",
"clear_button_color":"#163F07",
"heading_label_font":"AvenirNext-DemiBold",
"heading_label_font_size":"18.0",
"heading_label_text_color":"#60B044",
},
"size":{
"width":50,
"height":1
}
},
{
"id":"last_name",
"title":"Last name",
"info":"This field is required",
"type":"name",
"styles":{
"font":"AvenirNext-Regular",
"font_size":"15.0",
"corner_radius":"5.0",
"border_width":"2.0",
"active_background_color":"#FF0000",
"active_border_color":"#660000",
"inactive_background_color":"#FFFFC2",
"inactive_border_color":"#E6E65C",
"enabled_background_color":"#D1B2D1",
"enabled_border_color":"#660066",
"enabled_text_color":"#455C73",
"disabled_background_color":"#F5F5F8",
"disabled_border_color":"#DEDEDE",
"disabled_text_color":"#808080",
"valid_background_color":"#CCE0CC",
"valid_border_color":"#003D00",
"invalid_background_color":"#D1C2B2",
"invalid_border_color":"#3D1F00",
"tooltip_font":"AvenirNext-Medium",
"tooltip_font_size":"14.0",
"tooltip_label_text_color":"#000000",
"clear_button_color":"#3DAFEB",
"heading_label_font":"AvenirNext-DemiBold",
"heading_label_font_size":"18.0",
"heading_label_text_color":"#FF0000",
},
"size":{
"width":50,
"height":1
},
"validations":{
"required":true,
"min_length":2
}
}
]
},
{
"id":"section-1",
"fields":[
{
"id":"button",
"title":"Submit",
"type":"button",
"styles":{
"background_color":"#60B044",
"highlighted_background_color":"#CBEDBF",
"title_color":"#FFFFFF",
"highlighted_title_color":"#60B044",
"border_color":"#418F26",
"corner_radius":"10.0",
"border_width":"2.0",
"font":"AvenirNext-Heavy",
"font_size":"18.0"
},
"size":{
"width":100,
"height":1
}
}
]
}
]
}
]
Groups have two JSON based collapsibility options: collapsed
and collapsible
The collapsed
option accepts true
or false
and defines the default state for the group it is added to. The default is false
.
The collapsible
option also accepts true
or false
but defines whether or not a group can be collapsed at all. Defining this option as false
, prevents a group from being collapsed on click or with collapseAllGroupsForCollectionView
. The default is true
.
In your application code, you can also call collapseAllGroupsForCollectionView
on the data source to collapse all groups in a collection view.
To make quick and easy integer adjustments without popping up a keyboard, you can use the count
field. It works just like a number
field but provides a minus button in the UITextField's leftView and a plus button in the rightView. A tap on either will decrease or increase, respectively, the number by a value of one.
{
"groups":[
{
"id":"counter",
"title":"Counter Example",
"sections":[
{
"id":"counter-example",
"fields":[
{
"id":"guests",
"title":"Present Guests",
"info":"Press minus to decrease, plus to increase",
"type":"count",
"value":0,
"size":{
"width":25,
"height":1
},
"validations":{
"required":true,
"min_value":0,
"max_value":100
}
}
]
}
]
}
]
}
Form is available through CocoaPods. To install it, simply add the following line to your Podfile:
use_frameworks!
pod 'Form'
Please check our playbook for guidelines on contributing.
Hyper made this. We’re a digital communications agency with a passion for good code and delightful user experiences. If you’re using this library we probably want to hire you (we consider remote employees too, the only requirement is that you’re awesome).
Form is available under the MIT license. See the LICENSE.