ProMotion-form 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +90 -6
- data/lib/ProMotion-form.rb +1 -0
- data/lib/ProMotion/form/form.rb +65 -13
- data/lib/ProMotion/form/form_screen.rb +23 -2
- data/lib/ProMotion/form/form_view_controller.rb +54 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 249ed0437919e6d2e6009b22b9fd5d8f0308e90d
|
4
|
+
data.tar.gz: 7aab1a9d1f85b7fbc1915991ac961700f6701778
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24382d8bfb44a856369711a19655f931d0fe09b6d49fba189e585eb17faee13d1d449c3900a8de2625643e5b35b02280ee92026735b1c4465ddff6cfb268ac73
|
7
|
+
data.tar.gz: f8ec1bf1e37cd5305be0fa663be32d8dd3fa428e7cda04d205ea8dd610b80eed030600479b633d148abcfcc5f2f4a1aeb9a35ff8c1f38422bf1d9b1c87661d00
|
data/README.md
CHANGED
@@ -5,6 +5,8 @@
|
|
5
5
|
ProMotion-form provides a PM::FormScreen for the
|
6
6
|
popular RubyMotion gem [ProMotion](https://github.com/clearsightstudio/ProMotion).
|
7
7
|
|
8
|
+
![form](http://clrsight.co/jh/Screen_Shot_2014-08-29_at_4.03.13_PM.png?+)
|
9
|
+
|
8
10
|
## Installation
|
9
11
|
|
10
12
|
```ruby
|
@@ -29,7 +31,20 @@ class MyFormScreen < PM::FormScreen
|
|
29
31
|
title "My Form"
|
30
32
|
|
31
33
|
def form_data
|
32
|
-
[
|
34
|
+
[{
|
35
|
+
title: "Account Information",
|
36
|
+
cells: [{
|
37
|
+
name: "email",
|
38
|
+
title: "ID",
|
39
|
+
type: :email,
|
40
|
+
value: current_user.email,
|
41
|
+
}, {
|
42
|
+
name: "password",
|
43
|
+
title: "Password",
|
44
|
+
type: :password,
|
45
|
+
value: ""
|
46
|
+
}]
|
47
|
+
}]
|
33
48
|
end
|
34
49
|
|
35
50
|
end
|
@@ -48,8 +63,34 @@ We've used and like Formotion for some form-heavy apps, but it's a rather bulky
|
|
48
63
|
Method that is called to build the form.
|
49
64
|
|
50
65
|
```ruby
|
51
|
-
|
52
|
-
|
66
|
+
class AccountScreen < PM::FormScreen
|
67
|
+
title "Account Info"
|
68
|
+
|
69
|
+
def form_data
|
70
|
+
[{
|
71
|
+
title: "Account Information",
|
72
|
+
cells: [{
|
73
|
+
name: "email",
|
74
|
+
title: "ID",
|
75
|
+
type: :email,
|
76
|
+
value: current_user.email,
|
77
|
+
}, {
|
78
|
+
name: "password",
|
79
|
+
title: "Password",
|
80
|
+
type: :password,
|
81
|
+
value: ""
|
82
|
+
}, {
|
83
|
+
name: :submit,
|
84
|
+
title: "Submit",
|
85
|
+
action: "my_action:"
|
86
|
+
}]
|
87
|
+
}]
|
88
|
+
end
|
89
|
+
|
90
|
+
def my_action(cell)
|
91
|
+
# cell is the calling cell, in this case the Submit cell
|
92
|
+
render_form # use to save the data
|
93
|
+
end
|
53
94
|
end
|
54
95
|
```
|
55
96
|
|
@@ -57,15 +98,56 @@ All possible properties:
|
|
57
98
|
|
58
99
|
```ruby
|
59
100
|
{
|
60
|
-
label: "Name",
|
61
|
-
|
101
|
+
label: "Name", # or title:
|
102
|
+
name: :name, # required
|
103
|
+
type: :string, # :default is default...
|
104
|
+
options: [ "Water", "Fire", "Wind" ], # for :option type
|
105
|
+
placeholder: "Your name",
|
106
|
+
default: "Jamon",
|
107
|
+
value: "Jamon Holmgren",
|
108
|
+
action: :"my_action:" # use symbol literal with trailing colon
|
62
109
|
}
|
63
110
|
```
|
64
111
|
|
112
|
+
##### Types of fields:
|
113
|
+
|
114
|
+
* `:default`
|
115
|
+
* `:label`
|
116
|
+
* `:text`
|
117
|
+
* `:longtext`
|
118
|
+
* `:url`
|
119
|
+
* `:email`
|
120
|
+
* `:phone`
|
121
|
+
* `:password`
|
122
|
+
* `:number`
|
123
|
+
* `:integer`
|
124
|
+
* `:unsigned`
|
125
|
+
* `:float`
|
126
|
+
* `:bitfield`
|
127
|
+
* `:boolean`
|
128
|
+
* `:option`
|
129
|
+
* `:date`
|
130
|
+
* `:time`
|
131
|
+
* `:datetime`
|
132
|
+
* `:image`
|
133
|
+
|
134
|
+
|
65
135
|
#### update_form_data
|
66
136
|
|
67
137
|
Forces a reload of the form.
|
68
138
|
|
139
|
+
#### render_form
|
140
|
+
|
141
|
+
Returns a hash of the fields and values.
|
142
|
+
|
143
|
+
```ruby
|
144
|
+
render_form # => {:email=>"jkdflsljkdsfad", :password=>"asdfadsfadsf", :submit=>""}
|
145
|
+
```
|
146
|
+
|
147
|
+
#### dismiss_keyboard
|
148
|
+
|
149
|
+
Dismisses the keyboard. Note that you may need to call this before `render_form` to ensure that you capture the input from the currently focused form element.
|
150
|
+
|
69
151
|
---
|
70
152
|
|
71
153
|
### Class Methods
|
@@ -76,7 +158,9 @@ None yet.
|
|
76
158
|
|
77
159
|
### Accessors
|
78
160
|
|
79
|
-
|
161
|
+
#### form_object (read only)
|
162
|
+
|
163
|
+
This is a Struct with a `#fields` method (what is used to build the form in FXForms) and writeable properties for each field.
|
80
164
|
|
81
165
|
## Contributing
|
82
166
|
|
data/lib/ProMotion-form.rb
CHANGED
@@ -5,6 +5,7 @@ end
|
|
5
5
|
|
6
6
|
Motion::Project::App.setup do |app|
|
7
7
|
lib_dir_path = File.dirname(File.expand_path(__FILE__))
|
8
|
+
app.files << File.join(lib_dir_path, "ProMotion/form/form_view_controller.rb")
|
8
9
|
app.files << File.join(lib_dir_path, "ProMotion/form/form.rb")
|
9
10
|
app.files << File.join(lib_dir_path, "ProMotion/form/form_screen.rb")
|
10
11
|
|
data/lib/ProMotion/form/form.rb
CHANGED
@@ -1,27 +1,80 @@
|
|
1
1
|
module ProMotion
|
2
2
|
class Form
|
3
|
-
|
3
|
+
attr_reader :form_data
|
4
4
|
|
5
5
|
def initialize(form_data)
|
6
6
|
@form_data = form_data
|
7
7
|
end
|
8
8
|
|
9
|
+
# Smartly creates a "dumb" FXForms-compatible form object.
|
10
|
+
# It contains the values for every field and also has the
|
11
|
+
# instructions on how to build the form.
|
12
|
+
def build
|
13
|
+
props = properties
|
14
|
+
form_struct = Struct.new(:fields, *props) do
|
15
|
+
props.each do |p|
|
16
|
+
alias_method "set#{p.capitalize}:", "#{p}="
|
17
|
+
end
|
18
|
+
end
|
19
|
+
form_struct.new(form_fields, *values)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
9
24
|
def fields
|
10
|
-
|
25
|
+
@fields ||= begin
|
26
|
+
header = nil
|
27
|
+
form_data.map do |section|
|
28
|
+
header = section[:title]
|
29
|
+
Array(section[:cells]).map do |input|
|
30
|
+
input_data(input, header).tap{|i| header = nil }
|
31
|
+
end
|
32
|
+
end.flatten
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def properties
|
37
|
+
fields.map{ |f| f[:key] }
|
38
|
+
end
|
39
|
+
|
40
|
+
def values
|
41
|
+
fields.map{ |f| f[:value].to_s }
|
42
|
+
end
|
43
|
+
|
44
|
+
def form_fields
|
45
|
+
fields.map{ |f| f.dup.tap{|f2| f2.delete(:value) } }
|
46
|
+
end
|
47
|
+
|
48
|
+
def input_data(input, header)
|
49
|
+
data = {}
|
50
|
+
data[:header] = header if header
|
51
|
+
data[:key] = input.fetch(:name)
|
52
|
+
data[:type] = input[:type] if input[:type]
|
53
|
+
data[:title] = input[:label] || input[:title] || input[:name].to_s
|
54
|
+
data[:options] = input[:options] if input[:options]
|
55
|
+
data[:placeholder] = input[:placeholder] if input[:placeholder]
|
56
|
+
data[:default] = input[:default] if input[:default]
|
57
|
+
data[:value] = input[:value] if input[:value]
|
58
|
+
data[:action] = input[:action] if input[:action]
|
59
|
+
data
|
11
60
|
end
|
12
61
|
|
13
62
|
def example_fields
|
14
63
|
[
|
15
64
|
{
|
16
65
|
key: "email",
|
17
|
-
header: "Account"
|
66
|
+
header: "Account",
|
67
|
+
type: :email
|
68
|
+
},
|
69
|
+
{
|
70
|
+
key: "password",
|
71
|
+
type: :password
|
18
72
|
},
|
19
|
-
"password",
|
20
73
|
"repeatPassword",
|
21
74
|
{
|
22
75
|
key: "name",
|
23
76
|
header: "Details",
|
24
|
-
"textField.autocapitalizationType" => UITextAutocapitalizationTypeWords
|
77
|
+
# "textField.autocapitalizationType" => UITextAutocapitalizationTypeWords
|
25
78
|
},
|
26
79
|
{
|
27
80
|
key: "gender",
|
@@ -33,24 +86,24 @@ module ProMotion
|
|
33
86
|
{
|
34
87
|
key: "country",
|
35
88
|
options: [ "us", "ca", "gb", "sa", "be"],
|
36
|
-
default: "us",
|
37
|
-
valueTransformer: ISO3166CountryValueTransformer.alloc.init
|
89
|
+
# default: "us",
|
90
|
+
# valueTransformer: ISO3166CountryValueTransformer.alloc.init
|
38
91
|
},
|
39
92
|
{
|
40
93
|
key: "language",
|
41
94
|
options: [ "English", "Spanish", "French", "Dutch" ],
|
42
|
-
default: "English",
|
43
|
-
cell: FXFormOptionPickerCell
|
95
|
+
# default: "English",
|
96
|
+
# cell: FXFormOptionPickerCell
|
44
97
|
},
|
45
98
|
{
|
46
99
|
key: "interests",
|
47
|
-
default: "Videogames",
|
100
|
+
# default: "Videogames",
|
48
101
|
options: [ "Videogames", "Animals", "Cooking" ]
|
49
102
|
},
|
50
103
|
{
|
51
104
|
key: "otherInterests",
|
52
105
|
type: :bitfield,
|
53
|
-
default: "InterestComputers",
|
106
|
+
# default: "InterestComputers",
|
54
107
|
options: [ "Computers", "Socializing", "Sports" ]
|
55
108
|
},
|
56
109
|
{
|
@@ -64,7 +117,7 @@ module ProMotion
|
|
64
117
|
title: "",
|
65
118
|
placeholder: "Free",
|
66
119
|
options: [ "Micro", "Normal", "Maxi" ],
|
67
|
-
cell: FXFormOptionSegmentsCell
|
120
|
+
# cell: FXFormOptionSegmentsCell
|
68
121
|
},
|
69
122
|
{
|
70
123
|
key: "termsAndConditions",
|
@@ -83,7 +136,6 @@ module ProMotion
|
|
83
136
|
},
|
84
137
|
]
|
85
138
|
end
|
86
|
-
|
87
139
|
end
|
88
140
|
end
|
89
141
|
|
@@ -1,9 +1,30 @@
|
|
1
1
|
module ProMotion
|
2
|
-
class FormScreen <
|
2
|
+
class FormScreen < PM::FormViewController
|
3
3
|
include ProMotion::ScreenModule
|
4
4
|
|
5
|
+
attr_reader :form_object
|
6
|
+
|
5
7
|
def screen_setup
|
6
|
-
|
8
|
+
update_form_data
|
9
|
+
end
|
10
|
+
|
11
|
+
def form_data
|
12
|
+
PM.logger.info "You need to implement a `form_data` method in #{self.class.to_s}."
|
13
|
+
[]
|
14
|
+
end
|
15
|
+
|
16
|
+
def update_form_data
|
17
|
+
@form_object = PM::Form.new(self.form_data).build
|
18
|
+
self.formController.form = @form_object
|
19
|
+
self.formController.delegate = self
|
20
|
+
end
|
21
|
+
|
22
|
+
def dismiss_keyboard
|
23
|
+
self.view.endEditing true
|
24
|
+
end
|
25
|
+
|
26
|
+
def render_form
|
27
|
+
Hash[form_object.each_pair.to_a].tap{|h| h.delete(:fields) }
|
7
28
|
end
|
8
29
|
|
9
30
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module ProMotion
|
2
|
+
class FormViewController < FXFormViewController
|
3
|
+
def self.new(args = {})
|
4
|
+
s = self.alloc.init
|
5
|
+
s.screen_init(args) if s.respond_to?(:screen_init)
|
6
|
+
s
|
7
|
+
end
|
8
|
+
|
9
|
+
def loadView
|
10
|
+
self.respond_to?(:load_view) ? self.load_view : super
|
11
|
+
end
|
12
|
+
|
13
|
+
def viewDidLoad
|
14
|
+
super
|
15
|
+
self.view_did_load if self.respond_to?(:view_did_load)
|
16
|
+
end
|
17
|
+
|
18
|
+
def viewWillAppear(animated)
|
19
|
+
super
|
20
|
+
self.view_will_appear(animated) if self.respond_to?("view_will_appear:")
|
21
|
+
end
|
22
|
+
|
23
|
+
def viewDidAppear(animated)
|
24
|
+
super
|
25
|
+
self.view_did_appear(animated) if self.respond_to?("view_did_appear:")
|
26
|
+
end
|
27
|
+
|
28
|
+
def viewWillDisappear(animated)
|
29
|
+
self.view_will_disappear(animated) if self.respond_to?("view_will_disappear:")
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
def viewDidDisappear(animated)
|
34
|
+
self.view_did_disappear(animated) if self.respond_to?("view_did_disappear:")
|
35
|
+
super
|
36
|
+
end
|
37
|
+
|
38
|
+
def shouldAutorotateToInterfaceOrientation(orientation)
|
39
|
+
self.should_rotate(orientation)
|
40
|
+
end
|
41
|
+
|
42
|
+
def shouldAutorotate
|
43
|
+
self.should_autorotate
|
44
|
+
end
|
45
|
+
|
46
|
+
def willRotateToInterfaceOrientation(orientation, duration:duration)
|
47
|
+
self.will_rotate(orientation, duration)
|
48
|
+
end
|
49
|
+
|
50
|
+
def didRotateFromInterfaceOrientation(orientation)
|
51
|
+
self.on_rotate
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ProMotion-form
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jamon Holmgren
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ProMotion
|
@@ -77,6 +77,7 @@ files:
|
|
77
77
|
- lib/ProMotion-form.rb
|
78
78
|
- lib/ProMotion/form/form.rb
|
79
79
|
- lib/ProMotion/form/form_screen.rb
|
80
|
+
- lib/ProMotion/form/form_view_controller.rb
|
80
81
|
homepage: https://github.com/clearsightstudio/ProMotion-form
|
81
82
|
licenses:
|
82
83
|
- MIT
|