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 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
- ### Retreive
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
@@ -140,7 +140,8 @@ class AppDelegate
140
140
  type: :string,
141
141
  placeholder: 'Enter here',
142
142
  indented: true,
143
- deletable: true
143
+ deletable: true,
144
+ text_alignment: :left
144
145
  }
145
146
  }]
146
147
  }, {
@@ -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
- @form = Formotion::Form.persist({
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 = Formotion::FormController.alloc.initWithForm(@form)
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
- @form.reset
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
@@ -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.send(:each_row) do |row, index|
233
- s_index = row.section.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
- else
240
- row.value = temp_row.value
241
-
242
- observe(row, "value") do |old_value, new_value|
243
- self.save
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.send(:each_row) do |row, index|
264
- s_index = row.section.index
265
- temp_row = original_form.sections[s_index].rows[index]
266
-
267
- if row.subform?
268
- original_subform = temp_row.subform.to_form
269
- @form_resetter.call(row.subform.to_form, original_subform)
270
- else
271
- row.value = temp_row.value
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
@@ -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 == :subform
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
- FIELD_BUFFER = Device.iphone? ? 20 : 64
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 - (FIELD_BUFFER / 2), self.textLabel.center.y)
21
- self.detailTextLabel.center = CGPointMake(self.frame.size.width / 2 - (FIELD_BUFFER / 2), self.detailTextLabel.center.y)
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
@@ -20,6 +20,9 @@ module Formotion
20
20
  end
21
21
 
22
22
  def on_select(tableView, tableViewDelegate)
23
+ if !row.editable?
24
+ return
25
+ end
23
26
  if row.section.select_one and !row.value
24
27
  row.section.rows.each do |other_row|
25
28
  other_row.value = (other_row == row)
@@ -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 = UIDatePickerModeDate
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.value = @picker.date.timeIntervalSince1970.to_i
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 + FIELD_BUFFER
40
- field_frame.size.width = self.frame.size.width - field_frame.origin.x - FIELD_BUFFER
41
- field_frame.size.height = self.frame.size.height - FIELD_BUFFER
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 + FIELD_BUFFER
42
- field_frame.size.width = self.frame.size.width - field_frame.origin.x - FIELD_BUFFER
43
- field_frame.size.height = self.frame.size.height - FIELD_BUFFER
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 + FIELD_BUFFER
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 - FIELD_BUFFER
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
 
@@ -14,6 +14,7 @@ module Formotion
14
14
  row.value = switchView.isOn
15
15
  end
16
16
  end
17
+ switchView.userInteractionEnabled = row.editable?
17
18
  observe(self.row, "value") do |old_value, new_value|
18
19
  break_with_semaphore do
19
20
  switchView.setOn(row.value || false, animated: false)
@@ -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 + FIELD_BUFFER
64
- field_frame.size.width = self.frame.size.width - field_frame.origin.x - FIELD_BUFFER
65
- field_frame.size.height = self.frame.size.height - FIELD_BUFFER
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
 
@@ -1,3 +1,3 @@
1
1
  module Formotion
2
- VERSION = "1.1.5"
2
+ VERSION = "1.2"
3
3
  end
@@ -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: "test_#{rand(255)}",
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
- f = Formotion::Form.persist({
28
- persist_as: "test_#{rand(255)}",
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"
@@ -24,4 +24,4 @@ describe "FormController/SliderRow" do
24
24
  drag("Slider Slider", :from => :left)
25
25
  @form.sections[0].rows[0].value.should == 100
26
26
  end
27
- end
27
+ end
@@ -59,4 +59,24 @@ describe "Date Row" do
59
59
  @row.text_field.text.should == expected_output
60
60
  end
61
61
  end
62
- end
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
@@ -3,7 +3,6 @@ module UIControlWrap
3
3
  # that was previously defined by #when
4
4
  def trigger(events)
5
5
  @callback ||= {}
6
- p "Callback #{@callback}"
7
6
  @callback[events].map(&:call) if @callback.has_key? events
8
7
  end
9
8
  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.1.5
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: 2012-11-10 00:00:00.000000000 Z
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: 1737578013626732185
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: 1737578013626732185
210
+ hash: 3006402350062917066
210
211
  requirements: []
211
212
  rubyforge_project:
212
213
  rubygems_version: 1.8.23