formotion 1.1.5 → 1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +18 -0
- data/README.md +1 -1
- data/app/app_delegate.rb +2 -1
- data/examples/Persistence/app/app_delegate.rb +4 -179
- data/examples/Persistence/app/controller.rb +53 -0
- data/lib/formotion/form/form.rb +24 -21
- data/lib/formotion/patch/ui_text_view.rb +1 -1
- data/lib/formotion/row/row.rb +43 -3
- data/lib/formotion/row_type/base.rb +7 -1
- data/lib/formotion/row_type/button.rb +2 -2
- data/lib/formotion/row_type/check_row.rb +3 -0
- data/lib/formotion/row_type/date_row.rb +62 -8
- data/lib/formotion/row_type/image_row.rb +6 -3
- data/lib/formotion/row_type/options_row.rb +1 -0
- data/lib/formotion/row_type/picker_row.rb +14 -9
- data/lib/formotion/row_type/slider_row.rb +4 -3
- data/lib/formotion/row_type/string_row.rb +7 -3
- data/lib/formotion/row_type/switch_row.rb +1 -0
- data/lib/formotion/row_type/text_row.rb +7 -3
- data/lib/formotion/version.rb +1 -1
- data/spec/form/persist_spec.rb +12 -4
- data/spec/functional/slider_row_spec.rb +1 -1
- data/spec/row_type/date_spec.rb +21 -1
- data/spec/support/ui_control_wrap_extension.rb +0 -1
- metadata +5 -4
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
## 1.2 - January 3, 2013
|
2
|
+
|
3
|
+
### Features
|
4
|
+
|
5
|
+
- Added `:picker_mode` row property which lets you choose what type of date picker you're using (i.e. `:date`, `:time`, `:date_time`, or `:countdown`)
|
6
|
+
|
7
|
+
- Added `:text_alignment` row property which controls how a row's input field's text is aligned (i.e. `:right` (default), `:left`, or `:center`).
|
8
|
+
|
9
|
+
- Added `:editable` row property which controls if a user can interact with the row's control (a text input, slider, etc)
|
10
|
+
|
11
|
+
### Bug Fixes
|
12
|
+
|
13
|
+
- Fixed size issue with iPhone apps running @2x on an iPad (see `row_type/base.rb#field_buffer`)
|
14
|
+
|
15
|
+
- Fixed bug in `PickerRow` where KVOing `:value` changes woulnd't reflect in the picker UI.
|
16
|
+
|
17
|
+
- Fixed bug in a `UITextView` patch that removed copy and paste by default for all `UITextView`s.
|
18
|
+
|
1
19
|
## 1.1.5 - November 9, 2012
|
2
20
|
|
3
21
|
### Features
|
data/README.md
CHANGED
@@ -116,7 +116,7 @@ To add your own, check [the guide to adding new row types](https://github.com/cl
|
|
116
116
|
|
117
117
|
`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).
|
118
118
|
|
119
|
-
###
|
119
|
+
### Retrieve
|
120
120
|
|
121
121
|
You have `form#submit`, `form#on_submit`, and `form#render` at your disposal. Here's an example:
|
122
122
|
|
data/app/app_delegate.rb
CHANGED
@@ -2,184 +2,9 @@ class AppDelegate
|
|
2
2
|
def application(application, didFinishLaunchingWithOptions:launchOptions)
|
3
3
|
@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
|
4
4
|
|
5
|
-
@
|
6
|
-
title: "Persist Example",
|
7
|
-
persist_as: "example",
|
8
|
-
sections: [{
|
9
|
-
title: "Section Title",
|
10
|
-
footer: "This is the footer for the section. It's good for displaying detailed data about the section.",
|
11
|
-
rows: [{
|
12
|
-
title: "Static",
|
13
|
-
type: :static,
|
14
|
-
}, {
|
15
|
-
title: "Email",
|
16
|
-
key: :email,
|
17
|
-
placeholder: "me@mail.com",
|
18
|
-
type: :email,
|
19
|
-
auto_correction: :no,
|
20
|
-
auto_capitalization: :none
|
21
|
-
}, {
|
22
|
-
title: "Gender",
|
23
|
-
key: :gender,
|
24
|
-
type: :options,
|
25
|
-
items: ['Female', 'Male']
|
26
|
-
}, {
|
27
|
-
title: "Password",
|
28
|
-
key: :password,
|
29
|
-
placeholder: "required",
|
30
|
-
type: :string,
|
31
|
-
secure: true
|
32
|
-
}, {
|
33
|
-
title: "Phone",
|
34
|
-
key: :phone,
|
35
|
-
placeholder: "555-555-5555",
|
36
|
-
type: :phone,
|
37
|
-
auto_correction: :no,
|
38
|
-
auto_capitalization: :none
|
39
|
-
}, {
|
40
|
-
title: "Number",
|
41
|
-
key: :number,
|
42
|
-
placeholder: "12345",
|
43
|
-
type: :number,
|
44
|
-
auto_correction: :no,
|
45
|
-
auto_capitalization: :none
|
46
|
-
}, {
|
47
|
-
title: "Subtitle",
|
48
|
-
subtitle: "Confirmation",
|
49
|
-
key: :confirm,
|
50
|
-
placeholder: "required",
|
51
|
-
type: :string,
|
52
|
-
secure: true
|
53
|
-
}, {
|
54
|
-
title: "Row Height",
|
55
|
-
key: :row_height,
|
56
|
-
placeholder: "60px",
|
57
|
-
type: :string,
|
58
|
-
row_height: 60
|
59
|
-
}, {
|
60
|
-
title: "Text",
|
61
|
-
key: :text,
|
62
|
-
type: :text,
|
63
|
-
placeholder: "Enter your text here",
|
64
|
-
row_height: 100
|
65
|
-
}, {
|
66
|
-
title: "Check",
|
67
|
-
key: :check,
|
68
|
-
type: :check,
|
69
|
-
value: true
|
70
|
-
}, {
|
71
|
-
title: "Remember?",
|
72
|
-
key: :remember,
|
73
|
-
type: :switch,
|
74
|
-
}, {
|
75
|
-
title: "Date Full",
|
76
|
-
subtitle: "w/ :value",
|
77
|
-
value: 326937600,
|
78
|
-
key: :date_long,
|
79
|
-
type: :date,
|
80
|
-
format: :full
|
81
|
-
}, {
|
82
|
-
title: "Date Medium",
|
83
|
-
subtitle: "w/ :value",
|
84
|
-
value: 1341273600,
|
85
|
-
key: :date_medium,
|
86
|
-
type: :date,
|
87
|
-
format: :medium
|
88
|
-
}, {
|
89
|
-
title: "Date Short",
|
90
|
-
subtitle: "w/ :placeholder",
|
91
|
-
placeholder: "DOB",
|
92
|
-
key: :date_short,
|
93
|
-
type: :date,
|
94
|
-
format: :short
|
95
|
-
}, {
|
96
|
-
title: "Slider",
|
97
|
-
key: :slider,
|
98
|
-
type: :slider,
|
99
|
-
range: (1..100),
|
100
|
-
value: 25
|
101
|
-
}]
|
102
|
-
}, {
|
103
|
-
title: "Subforms",
|
104
|
-
rows: [{
|
105
|
-
title: "Subform",
|
106
|
-
subtitle: "With display_key",
|
107
|
-
type: :subform,
|
108
|
-
key: :subform,
|
109
|
-
display_key: :type,
|
110
|
-
subform: {
|
111
|
-
title: "Account Type",
|
112
|
-
sections: [{
|
113
|
-
key: :type,
|
114
|
-
select_one: true,
|
115
|
-
rows: [{
|
116
|
-
title: "Free",
|
117
|
-
key: :Free,
|
118
|
-
type: :check,
|
119
|
-
}, {
|
120
|
-
title: "Basic",
|
121
|
-
value: true,
|
122
|
-
key: :Basic,
|
123
|
-
type: :check,
|
124
|
-
}, {
|
125
|
-
title: "Pro",
|
126
|
-
key: :Pro,
|
127
|
-
type: :check,
|
128
|
-
}]
|
129
|
-
}, {
|
130
|
-
rows: [{
|
131
|
-
title: "Advanced",
|
132
|
-
type: :subform,
|
133
|
-
key: :advanced,
|
134
|
-
subform: {
|
135
|
-
title: "Advanced",
|
136
|
-
sections: [{
|
137
|
-
key: :currency,
|
138
|
-
select_one: true,
|
139
|
-
rows: [{
|
140
|
-
title: "USD",
|
141
|
-
value: true,
|
142
|
-
key: :usd,
|
143
|
-
type: :check,
|
144
|
-
}, {
|
145
|
-
title: "EUR",
|
146
|
-
key: :eur,
|
147
|
-
type: :check,
|
148
|
-
}, {
|
149
|
-
title: "CHF",
|
150
|
-
key: :chf,
|
151
|
-
type: :check,
|
152
|
-
}]
|
153
|
-
}, {
|
154
|
-
rows: [{
|
155
|
-
title: 'Back',
|
156
|
-
type: :back
|
157
|
-
}]
|
158
|
-
}]
|
159
|
-
}
|
160
|
-
}]
|
161
|
-
}, {
|
162
|
-
rows: [{
|
163
|
-
title: 'Back',
|
164
|
-
type: :back
|
165
|
-
}]
|
166
|
-
}]
|
167
|
-
}
|
168
|
-
}]
|
169
|
-
}]
|
170
|
-
})
|
5
|
+
@view_controller =AccountSettingsController.alloc.initController
|
171
6
|
|
172
|
-
@view_controller =
|
173
|
-
@view_controller.form.on_submit do |form|
|
174
|
-
form.active_row && form.active_row.text_field.resignFirstResponder
|
175
|
-
alert = UIAlertView.alloc.init
|
176
|
-
alert.title = "@form.render"
|
177
|
-
alert.message = @form.render.to_s
|
178
|
-
alert.addButtonWithTitle("OK")
|
179
|
-
alert.show
|
180
|
-
end
|
181
|
-
|
182
|
-
@view_controller.navigationItem.leftBarButtonItem = UIBarButtonItem.alloc.initWithTitle("Reset", style: UIBarButtonItemStyleBordered, target:self, action:'reset_form')
|
7
|
+
@view_controller.navigationItem.leftBarButtonItem = UIBarButtonItem.alloc.initWithTitle("Render", style: UIBarButtonItemStyleBordered, target:self, action:'reset_form')
|
183
8
|
|
184
9
|
@navigation_controller = UINavigationController.alloc.initWithRootViewController(@view_controller)
|
185
10
|
|
@@ -190,10 +15,10 @@ class AppDelegate
|
|
190
15
|
end
|
191
16
|
|
192
17
|
def submit
|
193
|
-
@form.submit
|
18
|
+
@view_controller.form.submit
|
194
19
|
end
|
195
20
|
|
196
21
|
def reset_form
|
197
|
-
|
22
|
+
AccountSettingsController.set_api_url_and_key_from_saved_settings
|
198
23
|
end
|
199
24
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class AccountSettingsController < Formotion::FormController
|
2
|
+
PERSIST_AS = :account_settings
|
3
|
+
|
4
|
+
API_SERVER = "hello_world"
|
5
|
+
API_KEY = "123123secret"
|
6
|
+
|
7
|
+
SETTINGS_HASH = {
|
8
|
+
title: "Application",
|
9
|
+
persist_as: PERSIST_AS,
|
10
|
+
sections: [{
|
11
|
+
rows: [{
|
12
|
+
title: "Server",
|
13
|
+
type: :string,
|
14
|
+
key: :server,
|
15
|
+
value: API_SERVER,
|
16
|
+
auto_correction: :no,
|
17
|
+
auto_capitalization: :none
|
18
|
+
}, {
|
19
|
+
title: "API Key",
|
20
|
+
value: API_KEY,
|
21
|
+
type: :string,
|
22
|
+
key: :api_key,
|
23
|
+
secure: false,
|
24
|
+
auto_correction: :no,
|
25
|
+
auto_capitalization: :none
|
26
|
+
}]
|
27
|
+
}]
|
28
|
+
}
|
29
|
+
|
30
|
+
def self.set_api_url_and_key_from_saved_settings
|
31
|
+
form = Formotion::Form.new(SETTINGS_HASH)
|
32
|
+
form.open
|
33
|
+
server_url_str = form.render[:server]
|
34
|
+
server_api_key = form.render[:api_key]
|
35
|
+
p "server_url_str #{server_url_str}"
|
36
|
+
p "server_api_key #{server_api_key}"
|
37
|
+
if server_url_str && server_api_key
|
38
|
+
if NSURLConnection.canHandleRequest(NSURLRequest.requestWithURL(NSURL.URLWithString(server_url_str)))
|
39
|
+
#Tillless::ApiHelper.set_api_url(server_url_str)
|
40
|
+
#Tillless::ApiHelper.set_api_key(server_api_key)
|
41
|
+
else
|
42
|
+
NSLog "Unable to set url from saved config in app_delegate: #{server_url_str}"
|
43
|
+
end
|
44
|
+
else
|
45
|
+
NSLog "No configuration found"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def initController
|
50
|
+
f = Formotion::Form.persist(SETTINGS_HASH)
|
51
|
+
initWithForm(f)
|
52
|
+
end
|
53
|
+
end
|
data/lib/formotion/form/form.rb
CHANGED
@@ -229,18 +229,20 @@ module Formotion
|
|
229
229
|
# places observers to save on changes
|
230
230
|
def open
|
231
231
|
@form_observer ||= lambda { |form, saved_form|
|
232
|
-
form.
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
232
|
+
form.sections.each_with_index do |section, s_index|
|
233
|
+
section.rows.each_with_index do |row, index|
|
234
|
+
temp_row = saved_form.sections[s_index].rows[index]
|
235
|
+
|
236
|
+
if row.subform?
|
237
|
+
@saved_subform = temp_row.subform.to_form
|
238
|
+
@form_observer.call(row.subform.to_form, @saved_subform)
|
239
|
+
@saved_subform = nil
|
240
|
+
else
|
241
|
+
row.value = temp_row.value
|
242
|
+
|
243
|
+
observe(row, "value") do |old_value, new_value|
|
244
|
+
self.save
|
245
|
+
end
|
244
246
|
end
|
245
247
|
end
|
246
248
|
end
|
@@ -260,15 +262,16 @@ module Formotion
|
|
260
262
|
App::Persistence[persist_key] = nil
|
261
263
|
|
262
264
|
@form_resetter ||= lambda { |form, original_form|
|
263
|
-
form.
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
265
|
+
form.sections.each_with_index do |section, s_index|
|
266
|
+
section.rows.each_with_index do |row, index|
|
267
|
+
temp_row = original_form.sections[s_index].rows[index]
|
268
|
+
|
269
|
+
if row.subform?
|
270
|
+
original_subform = temp_row.subform.to_form
|
271
|
+
@form_resetter.call(row.subform.to_form, original_subform)
|
272
|
+
else
|
273
|
+
row.value = temp_row.value
|
274
|
+
end
|
272
275
|
end
|
273
276
|
end
|
274
277
|
}
|
@@ -18,7 +18,7 @@ class UITextView
|
|
18
18
|
attr_accessor :menu_options_enabled
|
19
19
|
|
20
20
|
def canPerformAction(action, withSender:sender)
|
21
|
-
self.menu_options_enabled
|
21
|
+
self.menu_options_enabled.nil? ? true : self.menu_options_enabled
|
22
22
|
end
|
23
23
|
|
24
24
|
# block takes argument textView; should return true/false
|
data/lib/formotion/row/row.rb
CHANGED
@@ -13,14 +13,26 @@ module Formotion
|
|
13
13
|
# either Formotion::RowType or a string/symbol representation of one
|
14
14
|
# see row_type.rb
|
15
15
|
:type,
|
16
|
+
# Stores possible date pickers mode; corresponds to UIDatePickerMode______
|
17
|
+
# OPTIONS: :time, :date, :date_time, :countdown
|
18
|
+
# DEFAULT is :date
|
19
|
+
:picker_mode,
|
16
20
|
# Stores possible formatting information (used by date pickers, etc)
|
17
21
|
# if :type == :date, accepts values in [:short, :medium, :long, :full]
|
18
22
|
:format,
|
19
23
|
# alternative title for row (only used in EditRow for now)
|
20
24
|
:alt_title,
|
25
|
+
# determines if the user can edit the row
|
26
|
+
# OPTIONS: true, false
|
27
|
+
# DEFAULT: true
|
28
|
+
:editable,
|
21
29
|
|
22
30
|
# The following apply only to text-input fields
|
23
31
|
|
32
|
+
# text alignment of the input field
|
33
|
+
# OPTIONS: :left, :right, :center
|
34
|
+
# DEFAULT is :right
|
35
|
+
:text_alignment,
|
24
36
|
# placeholder text
|
25
37
|
:placeholder,
|
26
38
|
# whether or not the entry field is secure (like a password)
|
@@ -169,7 +181,7 @@ module Formotion
|
|
169
181
|
end
|
170
182
|
|
171
183
|
def subform?
|
172
|
-
self.type ==
|
184
|
+
self.type.to_s == "subform"
|
173
185
|
end
|
174
186
|
|
175
187
|
#########################
|
@@ -218,6 +230,33 @@ module Formotion
|
|
218
230
|
@clear_button = const_int_get("UITextFieldViewMode", value)
|
219
231
|
end
|
220
232
|
|
233
|
+
def text_alignment=(alignment)
|
234
|
+
@text_alignment = const_int_get("UITextAlignment", alignment)
|
235
|
+
end
|
236
|
+
|
237
|
+
def editable=(editable)
|
238
|
+
case editable
|
239
|
+
when TrueClass
|
240
|
+
when FalseClass
|
241
|
+
when NSNull
|
242
|
+
editable = false
|
243
|
+
when NilClass
|
244
|
+
editable = false
|
245
|
+
when NSString
|
246
|
+
editable = (editable == "true")
|
247
|
+
else
|
248
|
+
raise Formotion::InvalidClassError, "Invalid class for `Row#editable`: #{editable.inspect}; should be TrueClass, FalseCLass, or NSString"
|
249
|
+
end
|
250
|
+
@editable = editable
|
251
|
+
end
|
252
|
+
|
253
|
+
def editable?
|
254
|
+
if !self.editable.nil?
|
255
|
+
return self.editable
|
256
|
+
end
|
257
|
+
true
|
258
|
+
end
|
259
|
+
|
221
260
|
#########################
|
222
261
|
# setters for callbacks
|
223
262
|
|
@@ -305,8 +344,9 @@ module Formotion
|
|
305
344
|
UIReturnKeyYahoo, UIReturnKeyDone, UIReturnKeyEmergencyCall,
|
306
345
|
UITextFieldViewModeNever, UITextFieldViewModeAlways, UITextFieldViewModeWhileEditing,
|
307
346
|
UITextFieldViewModeUnlessEditing, NSDateFormatterShortStyle, NSDateFormatterMediumStyle,
|
308
|
-
NSDateFormatterLongStyle, NSDateFormatterFullStyle
|
347
|
+
NSDateFormatterLongStyle, NSDateFormatterFullStyle,
|
348
|
+
UITextAlignmentRight, UITextAlignmentCenter, UITextAlignmentLeft
|
309
349
|
]
|
310
350
|
end
|
311
351
|
end
|
312
|
-
end
|
352
|
+
end
|
@@ -3,7 +3,13 @@ module Formotion
|
|
3
3
|
class Base
|
4
4
|
attr_accessor :row, :tableView
|
5
5
|
|
6
|
-
|
6
|
+
def self.field_buffer
|
7
|
+
if Device.iphone? or App.window.size.width <= 320
|
8
|
+
20
|
9
|
+
else
|
10
|
+
64
|
11
|
+
end
|
12
|
+
end
|
7
13
|
|
8
14
|
def tableView
|
9
15
|
@tableView ||= self.row.form.table
|
@@ -17,8 +17,8 @@ module Formotion
|
|
17
17
|
((self.frame.size.send(dimen) - frame.size.send(dimen)) / 2.0)
|
18
18
|
}
|
19
19
|
|
20
|
-
self.textLabel.center = CGPointMake(self.frame.size.width / 2 - (
|
21
|
-
self.detailTextLabel.center = CGPointMake(self.frame.size.width / 2 - (
|
20
|
+
self.textLabel.center = CGPointMake(self.frame.size.width / 2 - (Formotion::RowType::Base.field_buffer / 2), self.textLabel.center.y)
|
21
|
+
self.detailTextLabel.center = CGPointMake(self.frame.size.width / 2 - (Formotion::RowType::Base.field_buffer / 2), self.detailTextLabel.center.y)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
nil
|
@@ -26,16 +26,13 @@ module Formotion
|
|
26
26
|
if date_style && date_style.to_s[-5..-1] != "style"
|
27
27
|
date_style = (date_style.to_s + "_style").to_sym
|
28
28
|
end
|
29
|
+
|
29
30
|
formatter.dateStyle = self.row.send(:const_int_get, "NSDateFormatter", date_style || NSDateFormatterShortStyle)
|
31
|
+
formatter.timeStyle = NSDateFormatterNoStyle
|
30
32
|
formatter
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
34
|
-
def formatted_value
|
35
|
-
return formatter.stringFromDate(self.date_value) if self.date_value
|
36
|
-
self.row.value
|
37
|
-
end
|
38
|
-
|
39
36
|
def after_build(cell)
|
40
37
|
self.row.text_field.inputView = self.picker
|
41
38
|
update
|
@@ -44,12 +41,16 @@ module Formotion
|
|
44
41
|
def picker
|
45
42
|
@picker ||= begin
|
46
43
|
picker = UIDatePicker.alloc.initWithFrame(CGRectZero)
|
47
|
-
picker.datePickerMode =
|
44
|
+
picker.datePickerMode = self.picker_mode
|
48
45
|
picker.hidden = false
|
49
46
|
picker.date = self.date_value || NSDate.date
|
50
47
|
|
51
48
|
picker.when(UIControlEventValueChanged) do
|
52
|
-
self.row.
|
49
|
+
if self.row.picker_mode == :countdown
|
50
|
+
self.row.value = @picker.countDownDuration
|
51
|
+
else
|
52
|
+
self.row.value = @picker.date.timeIntervalSince1970.to_i
|
53
|
+
end
|
53
54
|
update
|
54
55
|
end
|
55
56
|
|
@@ -57,10 +58,63 @@ module Formotion
|
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
61
|
+
def picker_mode
|
62
|
+
case self.row.picker_mode
|
63
|
+
when :time
|
64
|
+
UIDatePickerModeTime
|
65
|
+
when :date_time
|
66
|
+
UIDatePickerModeDateAndTime
|
67
|
+
when :countdown
|
68
|
+
UIDatePickerModeCountDownTimer
|
69
|
+
else
|
70
|
+
UIDatePickerModeDate
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def formatted_value
|
75
|
+
if self.date_value
|
76
|
+
return case self.row.picker_mode
|
77
|
+
when :time
|
78
|
+
old_date_style = formatter.dateStyle
|
79
|
+
formatter.dateStyle = NSDateFormatterNoStyle
|
80
|
+
formatter.timeStyle = NSDateFormatterShortStyle
|
81
|
+
formatted = formatter.stringFromDate(self.date_value)
|
82
|
+
formatter.dateStyle = old_date_style
|
83
|
+
formatter.timeStyle = NSDateFormatterNoStyle
|
84
|
+
formatted
|
85
|
+
when :date_time
|
86
|
+
old_date_style = formatter.dateStyle
|
87
|
+
formatter.dateStyle = NSDateFormatterShortStyle
|
88
|
+
formatter.timeStyle = NSDateFormatterShortStyle
|
89
|
+
formatted = formatter.stringFromDate(self.date_value)
|
90
|
+
formatter.dateStyle = old_date_style
|
91
|
+
formatter.timeStyle = NSDateFormatterNoStyle
|
92
|
+
formatted
|
93
|
+
when :countdown
|
94
|
+
time = self.row.value
|
95
|
+
date = NSDate.dateWithTimeIntervalSinceReferenceDate(time)
|
96
|
+
old_date_style = formatter.dateStyle
|
97
|
+
old_time_zone = formatter.timeZone
|
98
|
+
|
99
|
+
formatter.dateFormat = "HH:mm"
|
100
|
+
formatter.timeZone = NSTimeZone.timeZoneForSecondsFromGMT(0)
|
101
|
+
formatted = formatter.stringFromDate(date)
|
102
|
+
|
103
|
+
formatter.dateStyle = old_date_style
|
104
|
+
formatter.timeZone = old_time_zone
|
105
|
+
formatter.dateFormat = nil
|
106
|
+
formatted
|
107
|
+
else
|
108
|
+
formatter.stringFromDate(self.date_value)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
self.row.value
|
112
|
+
end
|
113
|
+
|
60
114
|
# Used when row.value changes
|
61
115
|
def update_text_field(new_value)
|
62
116
|
self.row.text_field.text = self.formatted_value
|
63
117
|
end
|
64
118
|
end
|
65
119
|
end
|
66
|
-
end
|
120
|
+
end
|
@@ -36,15 +36,18 @@ module Formotion
|
|
36
36
|
|
37
37
|
field_frame = formotion_field.frame
|
38
38
|
field_frame.origin.y = 10
|
39
|
-
field_frame.origin.x = self.textLabel.frame.origin.x + self.textLabel.frame.size.width +
|
40
|
-
field_frame.size.width = self.frame.size.width - field_frame.origin.x -
|
41
|
-
field_frame.size.height = self.frame.size.height -
|
39
|
+
field_frame.origin.x = self.textLabel.frame.origin.x + self.textLabel.frame.size.width + Formotion::RowType::Base.field_buffer
|
40
|
+
field_frame.size.width = self.frame.size.width - field_frame.origin.x - Formotion::RowType::Base.field_buffer
|
41
|
+
field_frame.size.height = self.frame.size.height - Formotion::RowType::Base.field_buffer
|
42
42
|
formotion_field.frame = field_frame
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
47
|
def on_select(tableView, tableViewDelegate)
|
48
|
+
if !row.editable?
|
49
|
+
return
|
50
|
+
end
|
48
51
|
@action_sheet = UIActionSheet.alloc.init
|
49
52
|
@action_sheet.delegate = self
|
50
53
|
|
@@ -10,6 +10,7 @@ module Formotion
|
|
10
10
|
segmentedControl = UISegmentedControl.alloc.initWithItems(item_names || [])
|
11
11
|
segmentedControl.selectedSegmentIndex = name_index_of_value(row.value) if row.value
|
12
12
|
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar
|
13
|
+
segmentedControl.userInteractionEnabled = row.editable?
|
13
14
|
cell.accessoryView = cell.editingAccessoryView = segmentedControl
|
14
15
|
|
15
16
|
segmentedControl.when(UIControlEventValueChanged) do
|
@@ -18,17 +18,12 @@ module Formotion
|
|
18
18
|
picker.dataSource = self
|
19
19
|
picker.delegate = self
|
20
20
|
|
21
|
-
if self.row.value
|
22
|
-
picker_row = name_index_of_value(row.value)
|
23
|
-
if picker_row != nil
|
24
|
-
picker.selectRow(picker_row, inComponent:0, animated:false)
|
25
|
-
else
|
26
|
-
warn "Picker item '#{row.value}' not found in #{row.items.inspect} for '#{row.key}'"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
21
|
picker
|
31
22
|
end
|
23
|
+
|
24
|
+
select_picker_value(row.value) if self.row.value
|
25
|
+
|
26
|
+
@picker
|
32
27
|
end
|
33
28
|
|
34
29
|
def numberOfComponentsInPickerView(pickerView)
|
@@ -55,6 +50,16 @@ module Formotion
|
|
55
50
|
|
56
51
|
def update_text_field(new_value)
|
57
52
|
self.row.text_field.text = name_for_value(new_value)
|
53
|
+
select_picker_value(new_value)
|
54
|
+
end
|
55
|
+
|
56
|
+
def select_picker_value(new_value)
|
57
|
+
picker_row = name_index_of_value(new_value)
|
58
|
+
if picker_row != nil
|
59
|
+
@picker.selectRow(picker_row, inComponent:0, animated:false)
|
60
|
+
else
|
61
|
+
warn "Picker item '#{row.value}' not found in #{row.items.inspect} for '#{row.key}'"
|
62
|
+
end
|
58
63
|
end
|
59
64
|
|
60
65
|
def row_value
|
@@ -15,6 +15,7 @@ module Formotion
|
|
15
15
|
slideView.tag = SLIDER_VIEW_TAG
|
16
16
|
slideView.setValue(row.value, animated:true) if row.value
|
17
17
|
slideView.accessibilityLabel = (row.title || "") + " Slider"
|
18
|
+
slideView.userInteractionEnabled = row.editable?
|
18
19
|
|
19
20
|
slideView.when(UIControlEventValueChanged) do
|
20
21
|
break_with_semaphore do
|
@@ -38,9 +39,9 @@ module Formotion
|
|
38
39
|
|
39
40
|
field_frame = formotion_field.frame
|
40
41
|
field_frame.origin.y = 10
|
41
|
-
field_frame.origin.x = self.textLabel.frame.origin.x + self.textLabel.frame.size.width +
|
42
|
-
field_frame.size.width = self.frame.size.width - field_frame.origin.x -
|
43
|
-
field_frame.size.height = self.frame.size.height -
|
42
|
+
field_frame.origin.x = self.textLabel.frame.origin.x + self.textLabel.frame.size.width + Formotion::RowType::Base.field_buffer
|
43
|
+
field_frame.size.width = self.frame.size.width - field_frame.origin.x - Formotion::RowType::Base.field_buffer
|
44
|
+
field_frame.size.height = self.frame.size.height - Formotion::RowType::Base.field_buffer
|
44
45
|
formotion_field.frame = field_frame
|
45
46
|
end
|
46
47
|
end
|
@@ -30,7 +30,7 @@ module Formotion
|
|
30
30
|
|
31
31
|
field.clearButtonMode = UITextFieldViewModeWhileEditing
|
32
32
|
field.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter
|
33
|
-
field.textAlignment = UITextAlignmentRight
|
33
|
+
field.textAlignment = row.text_alignment || UITextAlignmentRight
|
34
34
|
|
35
35
|
field.keyboardType = keyboardType
|
36
36
|
|
@@ -39,6 +39,7 @@ module Formotion
|
|
39
39
|
field.autocapitalizationType = row.auto_capitalization if row.auto_capitalization
|
40
40
|
field.autocorrectionType = row.auto_correction if row.auto_correction
|
41
41
|
field.clearButtonMode = row.clear_button || UITextFieldViewModeWhileEditing
|
42
|
+
field.enabled = row.editable?
|
42
43
|
|
43
44
|
add_callbacks(field)
|
44
45
|
|
@@ -51,9 +52,9 @@ module Formotion
|
|
51
52
|
formotion_field.sizeToFit
|
52
53
|
|
53
54
|
field_frame = formotion_field.frame
|
54
|
-
field_frame.origin.x = self.textLabel.frame.origin.x + self.textLabel.frame.size.width +
|
55
|
+
field_frame.origin.x = self.textLabel.frame.origin.x + self.textLabel.frame.size.width + Formotion::RowType::Base.field_buffer
|
55
56
|
field_frame.origin.y = ((self.frame.size.height - field_frame.size.height) / 2.0).round
|
56
|
-
field_frame.size.width = self.frame.size.width - field_frame.origin.x -
|
57
|
+
field_frame.size.width = self.frame.size.width - field_frame.origin.x - Formotion::RowType::Base.field_buffer
|
57
58
|
formotion_field.frame = field_frame
|
58
59
|
end
|
59
60
|
end
|
@@ -127,6 +128,9 @@ module Formotion
|
|
127
128
|
end
|
128
129
|
|
129
130
|
def on_select(tableView, tableViewDelegate)
|
131
|
+
if !row.editable?
|
132
|
+
return
|
133
|
+
end
|
130
134
|
row.text_field.becomeFirstResponder
|
131
135
|
end
|
132
136
|
|
@@ -20,6 +20,7 @@ module Formotion
|
|
20
20
|
field.autocapitalizationType = row.auto_capitalization if row.auto_capitalization
|
21
21
|
field.autocorrectionType = row.auto_correction if row.auto_correction
|
22
22
|
field.placeholder = row.placeholder
|
23
|
+
field.enabled = row.editable?
|
23
24
|
|
24
25
|
field.on_begin do |text_field|
|
25
26
|
row.on_begin_callback && row.on_begin_callback.call
|
@@ -60,9 +61,9 @@ module Formotion
|
|
60
61
|
|
61
62
|
field_frame = formotion_field.frame
|
62
63
|
field_frame.origin.y = 10
|
63
|
-
field_frame.origin.x = self.textLabel.frame.origin.x + self.textLabel.frame.size.width +
|
64
|
-
field_frame.size.width = self.frame.size.width - field_frame.origin.x -
|
65
|
-
field_frame.size.height = self.frame.size.height -
|
64
|
+
field_frame.origin.x = self.textLabel.frame.origin.x + self.textLabel.frame.size.width + Formotion::RowType::Base.field_buffer
|
65
|
+
field_frame.size.width = self.frame.size.width - field_frame.origin.x - Formotion::RowType::Base.field_buffer
|
66
|
+
field_frame.size.height = self.frame.size.height - Formotion::RowType::Base.field_buffer
|
66
67
|
formotion_field.frame = field_frame
|
67
68
|
end
|
68
69
|
end
|
@@ -72,6 +73,9 @@ module Formotion
|
|
72
73
|
end
|
73
74
|
|
74
75
|
def on_select(tableView, tableViewDelegate)
|
76
|
+
if !row.editable?
|
77
|
+
return
|
78
|
+
end
|
75
79
|
field.becomeFirstResponder
|
76
80
|
end
|
77
81
|
|
data/lib/formotion/version.rb
CHANGED
data/spec/form/persist_spec.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
describe "Form Persisting" do
|
2
2
|
|
3
3
|
it "works" do
|
4
|
+
key = "test_#{rand(255)}"
|
5
|
+
App::Persistence["FORMOTION_#{key}"] = nil
|
6
|
+
App::Persistence["FORMOTION_#{key}_ORIGINAL"] = nil
|
4
7
|
f = Formotion::Form.persist({
|
5
|
-
persist_as:
|
8
|
+
persist_as: key,
|
6
9
|
sections: [
|
7
10
|
rows: [ {
|
8
11
|
key: "first",
|
@@ -24,8 +27,11 @@ describe "Form Persisting" do
|
|
24
27
|
end
|
25
28
|
|
26
29
|
it "works with subforms" do
|
27
|
-
|
28
|
-
|
30
|
+
key = "test_#{rand(255)}"
|
31
|
+
App::Persistence["FORMOTION_#{key}"] = nil
|
32
|
+
App::Persistence["FORMOTION_#{key}_ORIGINAL"] = nil
|
33
|
+
hash = {
|
34
|
+
persist_as: key,
|
29
35
|
sections: [
|
30
36
|
rows: [ {
|
31
37
|
key: :subform,
|
@@ -44,7 +50,9 @@ describe "Form Persisting" do
|
|
44
50
|
}
|
45
51
|
]
|
46
52
|
]
|
47
|
-
}
|
53
|
+
}
|
54
|
+
f = Formotion::Form.persist(hash)
|
55
|
+
f.to_hash.should == hash
|
48
56
|
|
49
57
|
r = f.sections[0].rows[0].subform.to_form.sections[0].rows[0]
|
50
58
|
r.value = "new value"
|
data/spec/row_type/date_spec.rb
CHANGED
@@ -59,4 +59,24 @@ describe "Date Row" do
|
|
59
59
|
@row.text_field.text.should == expected_output
|
60
60
|
end
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
|
+
# Modes
|
64
|
+
{
|
65
|
+
:date => '1/1/00',
|
66
|
+
:time => '12:57 AM',
|
67
|
+
:date_time => '1/1/00, 12:57 AM',
|
68
|
+
:countdown => '00:57'
|
69
|
+
}.each do |mode, expected_output|
|
70
|
+
|
71
|
+
it "should display chosen mode #{mode} date/time format #{expected_output}" do
|
72
|
+
@row.format = :short
|
73
|
+
@row.picker_mode = mode
|
74
|
+
cell = @row.make_cell
|
75
|
+
@row.object.picker.date = NSDate.dateWithTimeIntervalSince1970(MILLENIUM)
|
76
|
+
@row.object.picker.trigger UIControlEventValueChanged
|
77
|
+
|
78
|
+
@row.text_field.text.should == expected_output
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: formotion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: '1.2'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bubble-wrap
|
@@ -81,6 +81,7 @@ files:
|
|
81
81
|
- examples/Persistence/README.md
|
82
82
|
- examples/Persistence/Rakefile
|
83
83
|
- examples/Persistence/app/app_delegate.rb
|
84
|
+
- examples/Persistence/app/controller.rb
|
84
85
|
- examples/Persistence/spec/main_spec.rb
|
85
86
|
- gh-pages/assets/css/bootstrap-responsive.css
|
86
87
|
- gh-pages/assets/css/bootstrap-responsive.min.css
|
@@ -197,7 +198,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
197
198
|
version: '0'
|
198
199
|
segments:
|
199
200
|
- 0
|
200
|
-
hash:
|
201
|
+
hash: 3006402350062917066
|
201
202
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
202
203
|
none: false
|
203
204
|
requirements:
|
@@ -206,7 +207,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
206
207
|
version: '0'
|
207
208
|
segments:
|
208
209
|
- 0
|
209
|
-
hash:
|
210
|
+
hash: 3006402350062917066
|
210
211
|
requirements: []
|
211
212
|
rubyforge_project:
|
212
213
|
rubygems_version: 1.8.23
|