formotion 1.1.5 → 1.2

Sign up to get free protection for your applications and to get access to all the features.
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