formotion 0.0.3 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/CHANGELOG.md +10 -0
- data/Gemfile +6 -0
- data/LIST_OF_ROW_TYPES.md +163 -0
- data/NEW_ROW_TYPES.md +73 -0
- data/README.md +11 -14
- data/Rakefile +6 -0
- data/app/app_delegate.rb +22 -0
- data/examples/KitchenSink/Rakefile +1 -1
- data/examples/KitchenSink/app/app_delegate.rb +50 -2
- data/examples/Login/.gitignore +5 -0
- data/examples/Login/Rakefile +9 -0
- data/examples/Login/app/app_delegate.rb +16 -0
- data/examples/Login/app/login_controller.rb +47 -0
- data/examples/Login/app/user_controller.rb +38 -0
- data/examples/Login/spec/main_spec.rb +9 -0
- data/lib/formotion.rb +7 -1
- data/lib/formotion/{form.rb → form/form.rb} +0 -0
- data/lib/formotion/{form_delegate.rb → form/form_delegate.rb} +10 -15
- data/lib/formotion/patch/object.rb +9 -0
- data/lib/formotion/patch/ui_action_sheet.rb +27 -0
- data/lib/formotion/patch/ui_text_view.rb +122 -0
- data/lib/formotion/patch/ui_text_view_placeholder.rb +65 -0
- data/lib/formotion/{row.rb → row/row.rb} +37 -27
- data/lib/formotion/row/row_cell_builder.rb +28 -0
- data/lib/formotion/row_type/base.rb +41 -0
- data/lib/formotion/row_type/check_row.rb +30 -0
- data/lib/formotion/row_type/date_row.rb +61 -0
- data/lib/formotion/row_type/email_row.rb +11 -0
- data/lib/formotion/row_type/image_row.rb +99 -0
- data/lib/formotion/row_type/number_row.rb +11 -0
- data/lib/formotion/row_type/options_row.rb +24 -0
- data/lib/formotion/row_type/phone_row.rb +11 -0
- data/lib/formotion/row_type/row_type.rb +21 -0
- data/lib/formotion/row_type/slider_row.rb +43 -0
- data/lib/formotion/row_type/static_row.rb +6 -0
- data/lib/formotion/row_type/string_row.rb +112 -0
- data/lib/formotion/row_type/submit_row.rb +34 -0
- data/lib/formotion/row_type/switch_row.rb +19 -0
- data/lib/formotion/row_type/text_row.rb +76 -0
- data/lib/formotion/{section.rb → section/section.rb} +3 -0
- data/lib/formotion/version.rb +1 -1
- data/spec/form_spec.rb +5 -4
- data/spec/functional/character_spec.rb +70 -0
- data/spec/functional/check_row_spec.rb +42 -0
- data/spec/functional/date_row_spec.rb +63 -0
- data/spec/functional/image_row_spec.rb +82 -0
- data/spec/functional/options_row_spec.rb +27 -0
- data/spec/functional/slider_row_spec.rb +27 -0
- data/spec/functional/submit_row_spec.rb +30 -0
- data/spec/functional/switch_row_spec.rb +28 -0
- data/spec/functional/text_row_spec.rb +60 -0
- data/spec/row_type/check_spec.rb +27 -0
- data/spec/row_type/date_spec.rb +69 -0
- data/spec/row_type/email_spec.rb +22 -0
- data/spec/row_type/image_spec.rb +43 -0
- data/spec/row_type/number_spec.rb +22 -0
- data/spec/row_type/options_spec.rb +37 -0
- data/spec/row_type/phone_spec.rb +22 -0
- data/spec/row_type/slider_spec.rb +47 -0
- data/spec/row_type/static_spec.rb +15 -0
- data/spec/row_type/string_spec.rb +52 -0
- data/spec/row_type/submit_spec.rb +28 -0
- data/spec/row_type/switch_spec.rb +27 -0
- data/spec/row_type/text_spec.rb +41 -0
- data/spec/support/ui_control_wrap_extension.rb +7 -0
- metadata +88 -9
- data/lib/formotion/row_cell_builder.rb +0 -168
- data/lib/formotion/row_type.rb +0 -33
data/.gitignore
CHANGED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
**Character based**<br/>
|
2
|
+
[String](#string)<br/>
|
3
|
+
[Text](#text)<br/>
|
4
|
+
[Email](#email)<br/>
|
5
|
+
[Number](#number)<br/>
|
6
|
+
[Date](#date)
|
7
|
+
|
8
|
+
**Other**<br/>
|
9
|
+
[Static](#static)<br/>
|
10
|
+
[Switch](#switch)<br/>
|
11
|
+
[Check](#check)<br/>
|
12
|
+
[Slider](#slider)<br/>
|
13
|
+
[Image](#image)<br/>
|
14
|
+
[Options](#options)
|
15
|
+
|
16
|
+
**Buttons**<br/>
|
17
|
+
[Submit](#submit)
|
18
|
+
|
19
|
+
## Character based
|
20
|
+
|
21
|
+
### <a name="string"></a> String row
|
22
|
+
![String row](https://github.com/clayallsopp/formotion/wiki/row-types/string.png)
|
23
|
+
```ruby
|
24
|
+
{
|
25
|
+
title: "Name",
|
26
|
+
key: :name,
|
27
|
+
type: :string,
|
28
|
+
placeholder: 'James Bond',
|
29
|
+
auto_correction: :no,
|
30
|
+
auto_capitalization: :none
|
31
|
+
}
|
32
|
+
```
|
33
|
+
|
34
|
+
### <a name="text"></a> Text row
|
35
|
+
![Text Row](https://github.com/clayallsopp/formotion/wiki/row-types/text.png)
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
{
|
39
|
+
title: "Text",
|
40
|
+
key: :text,
|
41
|
+
type: :text,
|
42
|
+
placeholder: "Enter your text here",
|
43
|
+
rowHeight: 100
|
44
|
+
}
|
45
|
+
```
|
46
|
+
|
47
|
+
### <a name="email"></a> Email row
|
48
|
+
![Email row](https://github.com/clayallsopp/formotion/wiki/row-types/email.png)
|
49
|
+
```ruby
|
50
|
+
{
|
51
|
+
title: "Email",
|
52
|
+
key: :email,
|
53
|
+
type: :email,
|
54
|
+
placeholder: 'me@mail.com'
|
55
|
+
}
|
56
|
+
```
|
57
|
+
|
58
|
+
### <a name="number"></a> Number row
|
59
|
+
![Number row](https://github.com/clayallsopp/formotion/wiki/row-types/number.png)
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
{
|
63
|
+
title: "Number",
|
64
|
+
key: :number,
|
65
|
+
placeholder: "12345",
|
66
|
+
type: :number
|
67
|
+
}
|
68
|
+
```
|
69
|
+
|
70
|
+
### <a name="date"></a> Date row
|
71
|
+
![Date row](https://github.com/clayallsopp/formotion/wiki/row-types/date.png)
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
{
|
75
|
+
title: "Date",
|
76
|
+
value: 326937600,
|
77
|
+
key: :date_long,
|
78
|
+
type: :date,
|
79
|
+
format: :full
|
80
|
+
}
|
81
|
+
```
|
82
|
+
|
83
|
+
## Other
|
84
|
+
|
85
|
+
### <a name="static"></a> Static row
|
86
|
+
![Static row](https://github.com/clayallsopp/formotion/wiki/row-types/static.png)
|
87
|
+
```ruby
|
88
|
+
{
|
89
|
+
title: "Static",
|
90
|
+
type: :static,
|
91
|
+
}
|
92
|
+
```
|
93
|
+
|
94
|
+
### <a name="switch"></a> Switch row
|
95
|
+
![Switch row](https://github.com/clayallsopp/formotion/wiki/row-types/switch.png)
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
{
|
99
|
+
title: "Remember?",
|
100
|
+
key: :remember,
|
101
|
+
type: :switch,
|
102
|
+
}
|
103
|
+
```
|
104
|
+
|
105
|
+
### <a name="check"></a> Check row
|
106
|
+
![Check row](https://github.com/clayallsopp/formotion/wiki/row-types/check.png)
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
{
|
110
|
+
title: "Check",
|
111
|
+
key: :check,
|
112
|
+
type: :check,
|
113
|
+
value: true
|
114
|
+
}
|
115
|
+
```
|
116
|
+
|
117
|
+
### <a name="slider"></a> Slider row
|
118
|
+
![Slider row](https://github.com/clayallsopp/formotion/wiki/row-types/slider.png)
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
{
|
122
|
+
title: "Slider",
|
123
|
+
key: :slider,
|
124
|
+
type: :slider,
|
125
|
+
range: (1..100),
|
126
|
+
value: 25
|
127
|
+
}
|
128
|
+
```
|
129
|
+
|
130
|
+
### <a name="image"></a> Image row
|
131
|
+
![Image row](https://github.com/clayallsopp/formotion/wiki/row-types/image.png)
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
{
|
135
|
+
title: "Image",
|
136
|
+
key: :image,
|
137
|
+
type: :image
|
138
|
+
}
|
139
|
+
```
|
140
|
+
|
141
|
+
### <a name="options"></a> Options row
|
142
|
+
![Options row](https://github.com/clayallsopp/formotion/wiki/row-types/options.png)
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
{
|
146
|
+
title: "options",
|
147
|
+
key: :options,
|
148
|
+
type: :options,
|
149
|
+
items: ['One', 'Two']
|
150
|
+
}
|
151
|
+
```
|
152
|
+
|
153
|
+
## Buttons
|
154
|
+
|
155
|
+
### <a name="submit"></a> Submit row
|
156
|
+
![Submit row](https://github.com/clayallsopp/formotion/wiki/row-types/submit.png)
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
{
|
160
|
+
title: "Submit",
|
161
|
+
type: :submit,
|
162
|
+
}
|
163
|
+
```
|
data/NEW_ROW_TYPES.md
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# Creating New Row Types
|
2
|
+
|
3
|
+
We've tried to make Formotion as extensible as possible so you can create new row types. If you think others could use it, feel free to submit a [pull request](https://github.com/clayallsopp/formotion/pulls).
|
4
|
+
|
5
|
+
## Steps
|
6
|
+
|
7
|
+
### 1 - Subclass
|
8
|
+
|
9
|
+
Add a subclass of `RowType::Base` to the `Formotion::RowType` module and conform your class name to the form `____Row`.
|
10
|
+
|
11
|
+
Example:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
module Formotion
|
15
|
+
module RowType
|
16
|
+
class MyNewRow < Base
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
```
|
21
|
+
|
22
|
+
`RowType.for` looks for classes inside the module with match that name form (see `row_type.rb`). This allows you to refer to your new type in the Formotion hashes as an underscored version of your class name:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
Formotion::Form.new({
|
26
|
+
sections: [{
|
27
|
+
rows: [{
|
28
|
+
title: "MyNewRow Example",
|
29
|
+
type: :my_new
|
30
|
+
}]
|
31
|
+
}]
|
32
|
+
})
|
33
|
+
```
|
34
|
+
|
35
|
+
### 2 - Override
|
36
|
+
|
37
|
+
The flow of using `RowType` is:
|
38
|
+
|
39
|
+
1. `row.make_cell` is called, which calls...
|
40
|
+
2. `Formotion::RowCellBuilder.make_cell(row)`, which calls...
|
41
|
+
3. `row.object.build_cell(cell)` **This is where you come in**
|
42
|
+
4. `YourRowType#build_cell(<#UITableViewCell>)` should setup the cell however you need to.
|
43
|
+
5. `build_cell` should return an instance of UITextField if necessary. See `StringRow#build_cell` for an example.
|
44
|
+
6. Lastly, `YourRowType#after_build(#<UITableViewCell>)` is called when the `row` object is entirely setup and right before it's passed back to the table view for drawing.
|
45
|
+
|
46
|
+
So the meat of your overrides should happen in **build_cell**.
|
47
|
+
|
48
|
+
Ex:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
module Formotion
|
52
|
+
module RowType
|
53
|
+
class MyNewRow < Base
|
54
|
+
def build_cell(cell)
|
55
|
+
blue_box = UIView.alloc.initWithFrame [[10, 10], [30, 30]]
|
56
|
+
blux_box.backgroundColor = UIColor.blueColor
|
57
|
+
cell.addSubview = blue_box
|
58
|
+
|
59
|
+
# return nil because no UITextField added.
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
### 3 - Callbacks And Defaults
|
68
|
+
|
69
|
+
Your subclass can override these methods:
|
70
|
+
|
71
|
+
`#on_select(tableView, tableViewDelegate)` - Called when the row is tapped by the user.
|
72
|
+
|
73
|
+
`#cell_style` - The `UITableViewCellStyle` for the row type. By default is `UITableViewCellStyleSubtitle`
|
data/README.md
CHANGED
@@ -107,6 +107,14 @@ Then attach it to a `Formotion::FormController` and you're ready to rock and rol
|
|
107
107
|
self.navigationController.pushViewController(@controller, animated: true)
|
108
108
|
```
|
109
109
|
|
110
|
+
### Data Types
|
111
|
+
|
112
|
+
See [the visual list of support row types](https://github.com/clayallsopp/formotion/blob/master/LIST_OF_ROW_TYPES.md).
|
113
|
+
|
114
|
+
To add your own, check [the guide to adding new row types](https://github.com/clayallsopp/formotion/blob/master/NEW_ROW_TYPES.md).
|
115
|
+
|
116
|
+
`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).
|
117
|
+
|
110
118
|
### Retreive
|
111
119
|
|
112
120
|
You have `form#submit`, `form#on_submit`, and `form#render` at your disposal. Here's an example:
|
@@ -126,7 +134,7 @@ class PeopleController < Formotion::FormController
|
|
126
134
|
end
|
127
135
|
```
|
128
136
|
|
129
|
-
Why would you use `form#on_submit`? In case you want to use `
|
137
|
+
Why would you use `form#on_submit`? In case you want to use `type: :submit`. Ex:
|
130
138
|
|
131
139
|
```ruby
|
132
140
|
@form = Formotion::Form.new({
|
@@ -135,7 +143,7 @@ Why would you use `form#on_submit`? In case you want to use `Formotion::RowType:
|
|
135
143
|
}, {
|
136
144
|
rows: [{
|
137
145
|
title: "Save",
|
138
|
-
type:
|
146
|
+
type: :submit
|
139
147
|
}]
|
140
148
|
}]
|
141
149
|
})
|
@@ -147,14 +155,6 @@ end
|
|
147
155
|
|
148
156
|
`form#submit` just triggers `form#on_submit`.
|
149
157
|
|
150
|
-
### Data Types
|
151
|
-
|
152
|
-
Formotion current supports static and editable text, switches, and checkboxes.
|
153
|
-
|
154
|
-
`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).
|
155
|
-
|
156
|
-
See the [KitchenSink example](https://github.com/clayallsopp/formotion/tree/master/examples/KitchenSink) for a bunch of options in action.
|
157
|
-
|
158
158
|
## Forking
|
159
159
|
|
160
160
|
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.
|
@@ -162,7 +162,4 @@ Feel free to fork and submit pull requests! And if you end up using Formotion in
|
|
162
162
|
## Todo
|
163
163
|
|
164
164
|
- Not very efficient right now (creates a unique reuse idenitifer for each cell)
|
165
|
-
-
|
166
|
-
- More tests
|
167
|
-
- Styling/overriding the form for custom UITableViewDelegate/Data Source behaviors.
|
168
|
-
- Custom cell text field alignments
|
165
|
+
- Styling/overriding the form for custom UITableViewDelegate/Data Source behaviors.
|
data/Rakefile
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
$:.unshift("/Library/RubyMotion/lib")
|
2
2
|
require 'motion/project'
|
3
3
|
require "bundler/gem_tasks"
|
4
|
+
require "bundler/setup"
|
4
5
|
|
5
6
|
$:.unshift("./lib/")
|
6
7
|
require './lib/formotion'
|
@@ -8,4 +9,9 @@ require './lib/formotion'
|
|
8
9
|
Motion::Project::App.setup do |app|
|
9
10
|
# Use `rake config' to see complete project settings.
|
10
11
|
app.name = 'Formotion'
|
12
|
+
|
13
|
+
# Temporary, until RubyMotion patches its test loader
|
14
|
+
spec_files = app.spec_files + Dir.glob(File.join(app.specs_dir, '**/*.rb'))
|
15
|
+
spec_files.uniq!
|
16
|
+
app.instance_variable_set(:@spec_files, spec_files)
|
11
17
|
end
|
data/app/app_delegate.rb
CHANGED
@@ -6,6 +6,10 @@ class AppDelegate
|
|
6
6
|
sections: [{
|
7
7
|
title: "Register",
|
8
8
|
rows: [{
|
9
|
+
title: "Photo",
|
10
|
+
key: :photo,
|
11
|
+
type: :image
|
12
|
+
},{
|
9
13
|
title: "Email",
|
10
14
|
key: :email,
|
11
15
|
placeholder: "me@mail.com",
|
@@ -29,6 +33,24 @@ class AppDelegate
|
|
29
33
|
title: "Switch",
|
30
34
|
key: :switch,
|
31
35
|
type: :switch,
|
36
|
+
}, {
|
37
|
+
title: "Bio",
|
38
|
+
key: :bio,
|
39
|
+
type: :text,
|
40
|
+
placeholder: "Enter your Bio here...",
|
41
|
+
rowHeight: 100
|
42
|
+
}, {
|
43
|
+
title: "Date Full",
|
44
|
+
value: 326937600,
|
45
|
+
key: :date_full,
|
46
|
+
type: :date,
|
47
|
+
format: :full
|
48
|
+
}, {
|
49
|
+
title: "Date Short",
|
50
|
+
placeholder: "03/26/92",
|
51
|
+
key: :date_short,
|
52
|
+
type: :date,
|
53
|
+
format: :short
|
32
54
|
}]
|
33
55
|
}, {
|
34
56
|
title: "Account Type",
|
@@ -6,6 +6,7 @@ class AppDelegate
|
|
6
6
|
title: "Kitchen Sink",
|
7
7
|
sections: [{
|
8
8
|
title: "Section Title",
|
9
|
+
footer: "This is the footer for the section. It's good for displaying detailed data about the section.",
|
9
10
|
rows: [{
|
10
11
|
title: "Static",
|
11
12
|
type: :static,
|
@@ -16,6 +17,11 @@ class AppDelegate
|
|
16
17
|
type: :email,
|
17
18
|
auto_correction: :no,
|
18
19
|
auto_capitalization: :none
|
20
|
+
}, {
|
21
|
+
title: "Gender",
|
22
|
+
key: :gender,
|
23
|
+
type: :options,
|
24
|
+
items: ['Female', 'Male']
|
19
25
|
}, {
|
20
26
|
title: "Password",
|
21
27
|
key: :password,
|
@@ -43,10 +49,54 @@ class AppDelegate
|
|
43
49
|
placeholder: "required",
|
44
50
|
type: :string,
|
45
51
|
secure: true
|
52
|
+
}, {
|
53
|
+
title: "Row Height",
|
54
|
+
key: :row_height,
|
55
|
+
placeholder: "60px",
|
56
|
+
type: :string,
|
57
|
+
rowHeight: 60
|
58
|
+
}, {
|
59
|
+
title: "Text",
|
60
|
+
key: :text,
|
61
|
+
type: :text,
|
62
|
+
placeholder: "Enter your text here",
|
63
|
+
rowHeight: 100
|
64
|
+
}, {
|
65
|
+
title: "Check",
|
66
|
+
key: :check,
|
67
|
+
type: :check,
|
68
|
+
value: true
|
46
69
|
}, {
|
47
70
|
title: "Remember?",
|
48
71
|
key: :remember,
|
49
72
|
type: :switch,
|
73
|
+
}, {
|
74
|
+
title: "Date Full",
|
75
|
+
subtitle: "w/ :value",
|
76
|
+
value: 326937600,
|
77
|
+
key: :date_long,
|
78
|
+
type: :date,
|
79
|
+
format: :full
|
80
|
+
}, {
|
81
|
+
title: "Date Medium",
|
82
|
+
subtitle: "w/ :value",
|
83
|
+
value: 1341273600,
|
84
|
+
key: :date_medium,
|
85
|
+
type: :date,
|
86
|
+
format: :medium
|
87
|
+
}, {
|
88
|
+
title: "Date Short",
|
89
|
+
subtitle: "w/ :placeholder",
|
90
|
+
placeholder: "DOB",
|
91
|
+
key: :date_short,
|
92
|
+
type: :date,
|
93
|
+
format: :short
|
94
|
+
}, {
|
95
|
+
title: "Slider",
|
96
|
+
key: :slider,
|
97
|
+
type: :slider,
|
98
|
+
range: (1..100),
|
99
|
+
value: 25
|
50
100
|
}]
|
51
101
|
}, {
|
52
102
|
title: "Select One",
|
@@ -74,8 +124,6 @@ class AppDelegate
|
|
74
124
|
}]
|
75
125
|
})
|
76
126
|
|
77
|
-
@navigation_controller = UINavigationController.alloc.init
|
78
|
-
|
79
127
|
@view_controller = Formotion::FormController.alloc.initWithForm(@form)
|
80
128
|
@view_controller.form.on_submit do |form|
|
81
129
|
form.active_row && form.active_row.text_field.resignFirstResponder
|