sproutcore 0.9.1 → 0.9.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.
Files changed (208) hide show
  1. data/History.txt +233 -0
  2. data/Manifest.txt +67 -34
  3. data/bin/sc-build +12 -1
  4. data/bin/sc-gen +1 -1
  5. data/bin/sproutcore +14 -0
  6. data/clients/sc_docs/controllers/docs.js +38 -8
  7. data/clients/sc_docs/english.lproj/body.css +80 -127
  8. data/clients/sc_docs/english.lproj/body.rhtml +43 -23
  9. data/clients/sc_docs/english.lproj/no_docs.rhtml +2 -1
  10. data/clients/sc_docs/english.lproj/tabs.rhtml +16 -0
  11. data/clients/sc_docs/main.js +14 -9
  12. data/clients/sc_docs/models/doc.js +1 -1
  13. data/clients/sc_docs/tests/controllers/docs.rhtml +1 -2
  14. data/clients/sc_docs/tests/models/doc.rhtml +1 -2
  15. data/clients/sc_docs/tests/views/doc_frame.rhtml +1 -2
  16. data/clients/sc_docs/tests/views/doc_label_view.rhtml +1 -2
  17. data/clients/sc_docs/views/doc_frame.js +1 -1
  18. data/clients/sc_test_runner/controllers/runner.js +31 -8
  19. data/clients/sc_test_runner/english.lproj/body.css +62 -122
  20. data/clients/sc_test_runner/english.lproj/body.rhtml +62 -26
  21. data/clients/sc_test_runner/main.js +1 -6
  22. data/clients/sc_test_runner/models/test.js +14 -1
  23. data/clients/sc_test_runner/views/runner_frame.js +4 -2
  24. data/clients/view_builder/builders/builder.js +339 -0
  25. data/clients/view_builder/builders/button.js +81 -0
  26. data/clients/view_builder/controllers/document.js +21 -0
  27. data/clients/view_builder/core.js +19 -0
  28. data/clients/view_builder/english.lproj/body.css +77 -0
  29. data/clients/view_builder/english.lproj/body.rhtml +41 -0
  30. data/clients/{sc_docs → view_builder}/english.lproj/controls.css +0 -0
  31. data/clients/view_builder/english.lproj/strings.js +14 -0
  32. data/clients/view_builder/main.js +38 -0
  33. data/clients/view_builder/tests/controllers/document.rhtml +20 -0
  34. data/clients/view_builder/tests/views/builder.rhtml +20 -0
  35. data/clients/view_builder/views/builder.js +23 -0
  36. data/frameworks/prototype/prototype.js +1 -1
  37. data/frameworks/sproutcore/Core.js +32 -7
  38. data/frameworks/sproutcore/README +1 -1
  39. data/frameworks/sproutcore/animation/animation.js +411 -0
  40. data/frameworks/sproutcore/controllers/array.js +17 -9
  41. data/frameworks/sproutcore/controllers/collection.js +9 -110
  42. data/frameworks/sproutcore/controllers/controller.js +1 -1
  43. data/frameworks/sproutcore/controllers/object.js +2 -1
  44. data/frameworks/sproutcore/drag/drag.js +267 -56
  45. data/frameworks/sproutcore/drag/drag_data_source.js +24 -16
  46. data/frameworks/sproutcore/drag/drag_source.js +53 -42
  47. data/frameworks/sproutcore/drag/drop_target.js +2 -2
  48. data/frameworks/sproutcore/english.lproj/buttons.css +337 -236
  49. data/frameworks/sproutcore/english.lproj/core.css +115 -0
  50. data/frameworks/sproutcore/english.lproj/icons.css +227 -0
  51. data/{clients/sc_docs → frameworks/sproutcore}/english.lproj/images/indicator.gif +0 -0
  52. data/frameworks/sproutcore/english.lproj/images/sc-theme-sprite.png +0 -0
  53. data/frameworks/sproutcore/english.lproj/images/sc-theme-ysprite.png +0 -0
  54. data/frameworks/sproutcore/english.lproj/images/shared-icons.png +0 -0
  55. data/frameworks/sproutcore/english.lproj/menu.css +1 -1
  56. data/frameworks/sproutcore/english.lproj/strings.js +1 -1
  57. data/frameworks/sproutcore/english.lproj/theme.css +405 -31
  58. data/frameworks/sproutcore/foundation/application.js +15 -11
  59. data/frameworks/sproutcore/foundation/benchmark.js +1 -1
  60. data/frameworks/sproutcore/foundation/binding.js +2 -2
  61. data/frameworks/sproutcore/foundation/date.js +1 -1
  62. data/frameworks/sproutcore/foundation/error.js +1 -1
  63. data/frameworks/sproutcore/foundation/input_manager.js +32 -21
  64. data/frameworks/sproutcore/foundation/mock.js +1 -1
  65. data/frameworks/sproutcore/foundation/node_descriptor.js +9 -6
  66. data/frameworks/sproutcore/foundation/object.js +249 -177
  67. data/frameworks/sproutcore/foundation/page.js +5 -2
  68. data/frameworks/sproutcore/foundation/path_module.js +11 -10
  69. data/frameworks/sproutcore/foundation/responder.js +5 -2
  70. data/frameworks/sproutcore/foundation/routes.js +17 -13
  71. data/frameworks/sproutcore/foundation/run_loop.js +249 -11
  72. data/frameworks/sproutcore/foundation/server.js +1 -1
  73. data/frameworks/sproutcore/foundation/set.js +3 -3
  74. data/frameworks/sproutcore/foundation/string.js +5 -3
  75. data/frameworks/sproutcore/foundation/timer.js +371 -0
  76. data/frameworks/sproutcore/foundation/undo_manager.js +1 -1
  77. data/frameworks/sproutcore/foundation/unittest.js +3 -3
  78. data/frameworks/sproutcore/foundation/utils.js +161 -2
  79. data/frameworks/sproutcore/globals/panels.js +1 -1
  80. data/frameworks/sproutcore/globals/popups.js +4 -3
  81. data/frameworks/sproutcore/globals/window.js +44 -4
  82. data/frameworks/sproutcore/lib/button_views.rb +328 -0
  83. data/frameworks/sproutcore/lib/collection_view.rb +80 -0
  84. data/frameworks/sproutcore/lib/core_views.rb +281 -0
  85. data/frameworks/sproutcore/lib/form_views.rb +253 -0
  86. data/frameworks/sproutcore/lib/index.rhtml +2 -0
  87. data/frameworks/sproutcore/lib/menu_views.rb +88 -0
  88. data/frameworks/sproutcore/{foundation → mixins}/array.js +60 -29
  89. data/frameworks/sproutcore/mixins/control.js +265 -0
  90. data/frameworks/sproutcore/mixins/delegate_support.js +66 -0
  91. data/frameworks/sproutcore/{foundation → mixins}/observable.js +176 -6
  92. data/frameworks/sproutcore/mixins/scrollable.js +245 -0
  93. data/frameworks/sproutcore/mixins/selection_support.js +148 -0
  94. data/frameworks/sproutcore/mixins/validatable.js +152 -0
  95. data/frameworks/sproutcore/models/collection.js +5 -5
  96. data/frameworks/sproutcore/models/record.js +1 -1
  97. data/frameworks/sproutcore/models/store.js +1 -1
  98. data/frameworks/sproutcore/panes/dialog.js +1 -1
  99. data/frameworks/sproutcore/panes/manager.js +1 -1
  100. data/frameworks/sproutcore/panes/menu.js +1 -1
  101. data/frameworks/sproutcore/panes/overlay.js +2 -2
  102. data/frameworks/sproutcore/panes/panel.js +1 -1
  103. data/frameworks/sproutcore/panes/picker.js +1 -1
  104. data/frameworks/sproutcore/tests/controllers/array.rhtml +44 -4
  105. data/frameworks/sproutcore/tests/foundation/timer/invalidate.rhtml +33 -0
  106. data/frameworks/sproutcore/tests/foundation/timer/invokeLater.rhtml +145 -0
  107. data/frameworks/sproutcore/tests/foundation/timer/isPaused.rhtml +70 -0
  108. data/frameworks/sproutcore/tests/foundation/timer/schedule.rhtml +145 -0
  109. data/frameworks/sproutcore/tests/views/{scroll.rhtml → checkbox.rhtml} +3 -3
  110. data/frameworks/sproutcore/tests/views/{collection.rhtml → collection/base.rhtml} +33 -32
  111. data/frameworks/sproutcore/tests/views/collection/incremental_rendering.rhtml +260 -0
  112. data/frameworks/sproutcore/tests/views/image_cell.rhtml +19 -0
  113. data/frameworks/sproutcore/tests/views/label_item.rhtml +2 -4
  114. data/frameworks/sproutcore/tests/views/list.rhtml +2 -3
  115. data/frameworks/sproutcore/tests/views/list_item.rhtml +20 -0
  116. data/frameworks/sproutcore/tests/views/slider.rhtml +20 -0
  117. data/frameworks/sproutcore/tests/views/text_cell.rhtml +19 -0
  118. data/frameworks/sproutcore/tests/views/view/clippingFrame.rhtml +395 -0
  119. data/frameworks/sproutcore/tests/views/view/frame.rhtml +353 -0
  120. data/frameworks/sproutcore/tests/views/view/innerFrame.rhtml +347 -0
  121. data/frameworks/sproutcore/tests/views/view/isVisibleInWindow.rhtml +148 -0
  122. data/frameworks/sproutcore/tests/views/view/scrollFrame.rhtml +468 -0
  123. data/frameworks/sproutcore/validators/credit_card.js +33 -13
  124. data/frameworks/sproutcore/validators/date.js +26 -6
  125. data/frameworks/sproutcore/validators/email.js +21 -3
  126. data/frameworks/sproutcore/validators/not_empty.js +11 -1
  127. data/frameworks/sproutcore/validators/number.js +18 -4
  128. data/frameworks/sproutcore/validators/password.js +12 -1
  129. data/frameworks/sproutcore/validators/validator.js +204 -194
  130. data/frameworks/sproutcore/views/{button.js → button/button.js} +96 -94
  131. data/frameworks/sproutcore/views/button/checkbox.js +29 -0
  132. data/frameworks/sproutcore/views/button/disclosure.js +42 -0
  133. data/frameworks/sproutcore/views/button/radio.js +29 -0
  134. data/frameworks/sproutcore/views/{collection.js → collection/collection.js} +1373 -1024
  135. data/frameworks/sproutcore/views/collection/grid.js +124 -46
  136. data/frameworks/sproutcore/views/collection/image_cell.js +17 -46
  137. data/frameworks/sproutcore/views/collection/list.js +45 -35
  138. data/frameworks/sproutcore/views/collection/source_list.js +386 -0
  139. data/frameworks/sproutcore/views/collection/table.js +118 -0
  140. data/frameworks/sproutcore/views/container.js +7 -2
  141. data/frameworks/sproutcore/views/error_explanation.js +23 -10
  142. data/frameworks/sproutcore/views/{checkbox_field.js → field/checkbox_field.js} +16 -6
  143. data/frameworks/sproutcore/views/field/field.js +219 -0
  144. data/frameworks/sproutcore/views/{radio_field.js → field/radio_field.js} +27 -12
  145. data/frameworks/sproutcore/views/{select_field.js → field/select_field.js} +116 -90
  146. data/frameworks/sproutcore/views/{text_field.js → field/text_field.js} +57 -8
  147. data/frameworks/sproutcore/views/{textarea_field.js → field/textarea_field.js} +13 -3
  148. data/frameworks/sproutcore/views/filter_button.js +2 -2
  149. data/frameworks/sproutcore/views/form.js +3 -3
  150. data/frameworks/sproutcore/views/image.js +128 -21
  151. data/frameworks/sproutcore/views/inline_text_editor.js +1 -1
  152. data/frameworks/sproutcore/views/label.js +149 -92
  153. data/frameworks/sproutcore/views/list_item.js +225 -0
  154. data/frameworks/sproutcore/views/menu_item.js +10 -4
  155. data/frameworks/sproutcore/views/pagination.js +11 -4
  156. data/frameworks/sproutcore/views/popup_button.js +25 -21
  157. data/frameworks/sproutcore/views/popup_menu.js +10 -4
  158. data/frameworks/sproutcore/views/progress.js +29 -16
  159. data/frameworks/sproutcore/views/radio_group.js +1 -1
  160. data/frameworks/sproutcore/views/scroll.js +60 -20
  161. data/frameworks/sproutcore/views/segmented.js +1 -1
  162. data/frameworks/sproutcore/views/slider.js +132 -0
  163. data/frameworks/sproutcore/views/source_list_group.js +130 -0
  164. data/frameworks/sproutcore/views/spinner.js +1 -1
  165. data/frameworks/sproutcore/views/split.js +292 -0
  166. data/frameworks/sproutcore/views/split_divider.js +109 -0
  167. data/frameworks/sproutcore/views/tab.js +1 -1
  168. data/frameworks/sproutcore/views/toolbar.js +1 -1
  169. data/frameworks/sproutcore/views/view.js +1272 -591
  170. data/generators/client/templates/english.lproj/body.css +1 -1
  171. data/generators/controller/controller_generator.rb +1 -1
  172. data/generators/controller/templates/test.rhtml +2 -1
  173. data/generators/model/templates/test.rhtml +1 -1
  174. data/generators/test/templates/test.rhtml +1 -1
  175. data/generators/view/templates/test.rhtml +1 -1
  176. data/jsdoc/templates/sproutcore/class.tmpl +241 -338
  177. data/jsdoc/templates/sproutcore/default.css +105 -155
  178. data/jsdoc/templates/sproutcore/index.tmpl +43 -8
  179. data/jsdoc/templates/sproutcore/publish.js +9 -4
  180. data/lib/sproutcore/build_tools/html_builder.rb +29 -13
  181. data/lib/sproutcore/build_tools/resource_builder.rb +1 -1
  182. data/lib/sproutcore/bundle.rb +86 -25
  183. data/lib/sproutcore/jsdoc.rb +2 -0
  184. data/lib/sproutcore/version.rb +1 -1
  185. data/lib/sproutcore/view_helpers.rb +36 -3
  186. data/tasks/deployment.rake +1 -1
  187. metadata +69 -36
  188. data/clients/sc_docs/english.lproj/icons/small/next.png +0 -0
  189. data/clients/sc_docs/english.lproj/icons/small/reset.png +0 -0
  190. data/clients/sc_docs/english.lproj/images/gradients.png +0 -0
  191. data/clients/sc_docs/english.lproj/images/toolbar.png +0 -0
  192. data/clients/sc_docs/english.lproj/warning.rhtml +0 -6
  193. data/clients/sc_test_runner/english.lproj/warning.rhtml +0 -6
  194. data/frameworks/sproutcore/english.lproj/buttons.png +0 -0
  195. data/frameworks/sproutcore/english.lproj/collections.css +0 -82
  196. data/frameworks/sproutcore/english.lproj/images/buttons-sprite.png +0 -0
  197. data/frameworks/sproutcore/views/collection/collection_item.js +0 -36
  198. data/frameworks/sproutcore/views/collection/text_cell.js +0 -128
  199. data/frameworks/sproutcore/views/field.js +0 -214
  200. data/frameworks/sproutcore/views/workspace.js +0 -170
  201. data/generators/client/templates/english.lproj/controls.css +0 -0
  202. data/generators/framework/templates/english.lproj/body.css +0 -0
  203. data/generators/framework/templates/english.lproj/body.rhtml +0 -3
  204. data/generators/framework/templates/english.lproj/controls.css +0 -0
  205. data/lib/sproutcore/view_helpers/button_views.rb +0 -302
  206. data/lib/sproutcore/view_helpers/core_views.rb +0 -292
  207. data/lib/sproutcore/view_helpers/form_views.rb +0 -258
  208. data/lib/sproutcore/view_helpers/menu_views.rb +0 -94
@@ -1,6 +1,6 @@
1
1
  // ========================================================================
2
2
  // SproutCore
3
- // copyright 2006-2007 Sprout Systems, Inc.
3
+ // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
6
  require('views/view') ;
@@ -52,7 +52,12 @@ SC.ContainerView = SC.View.extend(
52
52
  var containerView = this.get('rootView') || this ;
53
53
  containerView.clear() ;
54
54
  var newView = newContent ;
55
- if (newView) containerView.appendChild(newView) ;
55
+
56
+ if (newView) {
57
+ newView.viewFrameWillChange() ;
58
+ containerView.appendChild(newView) ;
59
+ newView.viewFrameDidChange() ;
60
+ }
56
61
  },
57
62
 
58
63
  _contentObserver: function() {
@@ -1,14 +1,23 @@
1
1
  // ========================================================================
2
2
  // SproutCore
3
- // copyright 2006-2007 Sprout Systems, Inc.
3
+ // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
6
  require('views/label');
7
7
 
8
- // The ErrorExplanation view is a special type of label view that can display
9
- // one or more errors related to a form or field. This view will set itself
10
- // to visible only if it has errors.
11
- SC.ErrorExplanationView = SC.LabelView.extend({
8
+ /**
9
+ @class
10
+
11
+ The ErrorExplanation view is a special type of label view that can display
12
+ one or more errors related to a form or field. This view will set itself
13
+ to visible only if it has errors.
14
+
15
+ @extends SC.View
16
+ @extends SC.Control
17
+
18
+ */
19
+ SC.ErrorExplanationView = SC.View.extend(SC.Control,
20
+ /** @scope SC.ErrorExplanationView.prototype */ {
12
21
 
13
22
  emptyElement: '<ul class="errors"></ul>',
14
23
  explanationTemplate: '<li>%@</li>',
@@ -20,7 +29,8 @@ SC.ErrorExplanationView = SC.LabelView.extend({
20
29
  }).compact() ;
21
30
  },
22
31
 
23
- contentBindingDefault: SC.Binding.Multiple,
32
+ valueBindingDefault: SC.Binding.Multiple,
33
+
24
34
  formatter: function(errors, view) {
25
35
  errors = view._errorsFor(errors) ;
26
36
  if (!errors || errors.length == 0) return '' ;
@@ -30,16 +40,19 @@ SC.ErrorExplanationView = SC.LabelView.extend({
30
40
  return view.explanationTemplate.fmt(er);
31
41
  }).join("") ;
32
42
  },
43
+
33
44
  escapeHTML: false,
34
45
 
35
- _contentVisibleObserver: function() {
36
- var errors = this._errorsFor(this.get('content')) ;
46
+ _valueObserver: function() {
47
+ var errors = this._errorsFor(this.get('value')) ;
37
48
  var isVisible = errors && errors.length > 0 ;
38
49
  if (this.get('isVisible') != isVisible) this.set('isVisible',isVisible);
39
- }.observes('content'),
50
+ this.set('innerHTML', this.formatter(errors, this)) ;
51
+ }.observes('value'),
40
52
 
41
53
  init: function() {
42
54
  arguments.callee.base.apply(this,arguments) ;
43
- this._contentVisibleObserver() ;
55
+ this._valueObserver() ;
44
56
  }
57
+
45
58
  });
@@ -1,13 +1,23 @@
1
1
  // ========================================================================
2
2
  // SproutCore
3
- // copyright 2006-2007 Sprout Systems, Inc.
3
+ // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
- require('views/field') ;
6
+ require('views/field/field') ;
7
7
 
8
- // A text field is an input element with type "text". This view adds support
9
- // for hinted values, etc.
10
- SC.CheckboxFieldView = SC.FieldView.extend({
8
+ /**
9
+ @class
10
+
11
+ Supports using platform native checkboxs with the input field. If you
12
+ would like to make use of the extended SproutCore checkbox features
13
+ including a mixed state and theming support, use SC.CheckboxView instead.
14
+
15
+ @extends SC.FieldView
16
+ @author Charles Jolley
17
+ @version 1.0
18
+ */
19
+ SC.CheckboxFieldView = SC.FieldView.extend(
20
+ /** @scope SC.CheckboxFieldView.prototype */ {
11
21
 
12
22
  emptyElement: '<input type="checkbox" value="1" />',
13
23
 
@@ -19,7 +29,7 @@ SC.CheckboxFieldView = SC.FieldView.extend({
19
29
  return this.rootElement.checked;
20
30
  },
21
31
 
22
- valueBindingDefault: SC.Binding.Flag,
32
+ valueBindingDefault: SC.Binding.Bool,
23
33
 
24
34
  init: function() {
25
35
  arguments.callee.base.apply(this,arguments) ;
@@ -0,0 +1,219 @@
1
+ // ========================================================================
2
+ // SproutCore
3
+ // copyright 2006-2008 Sprout Systems, Inc.
4
+ // ========================================================================
5
+
6
+ require('views/view') ;
7
+ require('mixins/control') ;
8
+ require('mixins/validatable') ;
9
+
10
+ /**
11
+ @class
12
+
13
+ Generic base class for working with views that depend on the "input" HTML
14
+ tag such as text fields.
15
+
16
+ You can work with subclasses of SC.FieldView or extend this class with your
17
+ own values as well. Unlike most other HTML elements, web browsers have
18
+ built-in support for editing the value of an input field. This class
19
+ handles blending the browser input methods with the editing and events
20
+ handling provided by the framework.
21
+
22
+ @extends SC.View
23
+ @extends SC.Control
24
+ @extends SC.Validatable
25
+ @author Charles Jolley
26
+ @version 1.0
27
+ */
28
+ SC.FieldView = SC.View.extend(SC.Control, SC.Validatable,
29
+ /** @scope SC.FieldView.prototype */ {
30
+
31
+ // PUBLIC PROPERTIES
32
+ // You generally do not need to override these properties though you might
33
+ // change them....
34
+
35
+ /**
36
+ The value of the field.
37
+
38
+ The form view will pick up whatever value is published here. Generally
39
+ you do not need to observe this property directly. Instead you should
40
+ override setFieldValue(), getFieldValue() and the error property.
41
+
42
+ @field
43
+ */
44
+ value: null,
45
+
46
+ /**
47
+ name of key this field should display as part of a form.
48
+
49
+ If you add a field as part of an SC.FormView, then the form view will
50
+ automatically bind the field to the property key you name here on the
51
+ content object.
52
+ */
53
+ fieldKey: null,
54
+
55
+ /**
56
+ The human readable label you want shown for errors. May be a loc string.
57
+
58
+ If your field fails validation, then this is the name that will be shown
59
+ in the error explanation.
60
+ */
61
+ fieldLabel: null,
62
+
63
+ /**
64
+ The human readable label for this field for use in error strings.
65
+
66
+ This is either the fieldLabel or a humanized form of the fieldKey.
67
+
68
+ @field
69
+ */
70
+ errorLabel: function() {
71
+ var ret = this.get('fieldLabel') ;
72
+ if (ret) return ret ;
73
+
74
+ // if field label is not provided, compute something...
75
+ var fk = this.get('fieldKey') ;
76
+ var def = (fk || '').humanize().capitalize() ;
77
+ return "FieldKey.%@".fmt(fk).locWithDefault(def) ; // localize if poss.
78
+ }.property('fieldLabel','fieldKey'),
79
+
80
+ /**
81
+ The raw value of the field, ignoring validation.
82
+
83
+ You generally should not override this. Instead override setFieldValue()
84
+ and getFieldValue().
85
+
86
+ @field
87
+ */
88
+ fieldValue: function(key,value) {
89
+ if (value !== undefined) this._setFieldValue(value) ;
90
+ return this._getFieldValue() ;
91
+ }.property('value'),
92
+
93
+ // ACTIONS
94
+ // You generally do not need to override these but they may be used.
95
+
96
+ /**
97
+ Called to perform validation on the field just before the form
98
+ is submitted. If you have a validator attached, this will get the
99
+ validators.
100
+ */
101
+ validateSubmit: function() {
102
+ var ret = this.performValidateSubmit() ;
103
+ // save the value if needed
104
+ var value = ($ok(ret)) ? this._getFieldValue() : ret ;
105
+ if (value != this.get('value')) this.set('value', value) ;
106
+ return ret ;
107
+ },
108
+
109
+ // OVERRIDE IN YOUR SUBCLASS
110
+ // Override these primitives in your subclass as required.
111
+
112
+ /**
113
+ Override to set the actual value of the field.
114
+
115
+ The default implementations set the value on the new value. The value
116
+ will have already been converted to a field value using any validator.
117
+
118
+ @param {Object} newValue the value to display.
119
+ */
120
+ setFieldValue: function(newValue) {
121
+ if (this.rootElement.value != newValue) this.rootElement.value = newValue;
122
+ },
123
+
124
+ /**
125
+ Override to retrieve the actual value of the field.
126
+
127
+ The default implementation gets the value attribute of the rootElement.
128
+ */
129
+ getFieldValue: function() {
130
+ return this.rootElement.value;
131
+ },
132
+
133
+ /**
134
+ Call by your subclass anytime you want the view to pick up the current
135
+ value from the form and post it out.
136
+
137
+ @param partialChange (optional) YES if this is a partial change.
138
+ @returns result of validation.
139
+ */
140
+ fieldValueDidChange: function(partialChange) {
141
+
142
+ // get the field value and set it.
143
+ // if ret is an error, use that instead of the field value.
144
+ var ret = this.performValidate(partialChange) ;
145
+ if (ret == SC.Validator.NO_CHANGE) return ret ;
146
+
147
+ // if the validator says everything is OK, then in addition to posting
148
+ // out the value, go ahead and pass the value back through itself.
149
+ // This way if you have a formatter applied, it will reformat.
150
+ //
151
+ // Do this BEFORE we set the value so that the valueObserver will not
152
+ // overreact.
153
+ //
154
+ if (!partialChange && $ok(ret)) this._setFieldValue(value) ;
155
+
156
+ var value = ($ok(ret)) ? this._getFieldValue() : ret ;
157
+ if (value != this.get('value')) this.set('value',value) ;
158
+ return ret ;
159
+ },
160
+
161
+ /**
162
+ Override to enable editing of this field.
163
+
164
+ The default just sets the disabled property on the root element.
165
+ */
166
+ enableField: function() {
167
+ this.rootElement.disabled = NO ;
168
+ },
169
+
170
+ /**
171
+ Override to disable editing of the field
172
+
173
+ The default just sets the disabled property on the root element.
174
+ */
175
+ disableField: function() {
176
+ this.rootElement.disabled = YES ;
177
+ },
178
+
179
+ /**
180
+ Overrides enabled observer to also call enableField()/disableField()
181
+ methods.
182
+ */
183
+ isEnabledObserver: function() {
184
+ isEnabled = this.get('isEnabled') ;
185
+ arguments.callee.base.apply(this, arguments);
186
+ (isEnabled) ? this.enableField() : this.disableField();
187
+ }.observes('isEnabled'),
188
+
189
+ // PRIVATE SUPPORT METHODS
190
+ //
191
+ init: function() {
192
+ arguments.callee.base.call(this) ;
193
+ if (this.rootElement) this._setFieldValue(this.get('value')) ;
194
+ },
195
+
196
+
197
+ // called whenever the value is set on the object. Will set the value
198
+ // on the field if the value is changed.
199
+ _valueObserver: function() {
200
+ var value = this.get('value') ;
201
+ var isError = $type(value) == T_ERROR ;
202
+ if (!isError && (value != this._getFieldValue())) {
203
+ this._setFieldValue(value) ;
204
+ }
205
+ }.observes('value'),
206
+
207
+ // these methods use the validator to conver the raw field value returned
208
+ // by your subclass into an object and visa versa.
209
+ _setFieldValue: function(newValue) {
210
+ return this.setFieldValue(this.fieldValueForObject(newValue)) ;
211
+ },
212
+
213
+ _getFieldValue: function() {
214
+ return this.objectForFieldValue(this.getFieldValue()) ;
215
+ }
216
+
217
+ }) ;
218
+
219
+
@@ -1,28 +1,43 @@
1
1
  // ========================================================================
2
2
  // SproutCore
3
- // copyright 2006-2007 Sprout Systems, Inc.
3
+ // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
- require('views/field') ;
6
+ require('views/field/field') ;
7
7
 
8
- // A RadioFieldView can be used to wrap a series of radio inputs. The value
9
- // of this field will be the selected radio. To use this, you really need to
10
- // provide some preformatted HTML that already contains the radio buttons with
11
- // matching name attributes. If you use the form_view helpers, this will be
12
- // handled for you.
13
- SC.RadioFieldView = SC.FieldView.extend({
8
+ /**
9
+ @class
10
+
11
+ A RadioFieldView can be used to wrap a series of radio inputs. The value
12
+ of this field will be the selected radio. To use this, you really need to
13
+ provide some preformatted HTML that already contains the radio buttons with
14
+ matching name attributes. If you use the form_view helpers, this will be
15
+ handled for you.
16
+
17
+ @extends SC.FieldView
18
+ @author Charles Jolley
19
+ @version 1.0
20
+ */
21
+ SC.RadioFieldView = SC.FieldView.extend(
22
+ /** @scope SC.RadioFieldView.prototype */ {
14
23
 
15
24
  emptyElement: '<div></div>',
16
25
 
17
- // RO - returns the list of values allowed by these radio buttons.
26
+ /**
27
+ RO - The list of values allowed by these radio buttons.
28
+
29
+ @field
30
+ */
18
31
  values: function() {
19
32
  if (!this._fields) return [] ;
20
33
  return Object.keys(this._fields) ;
21
34
  }.property(),
22
35
 
23
- // If you would like your radio buttons to map to actual object values,
24
- // then set this to a hash with keys matching values found in the radio
25
- // buttons.
36
+ /**
37
+ If you would like your radio buttons to map to actual object values,
38
+ then set this to a hash with keys matching values found in the radio
39
+ buttons.
40
+ */
26
41
  objects: null,
27
42
 
28
43
  // INTERNAL SUPPORT METHODS
@@ -1,52 +1,83 @@
1
1
  // ========================================================================
2
2
  // SproutCore
3
- // copyright 2006-2007 Sprout Systems, Inc.
3
+ // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
- require('views/field') ;
6
+ require('views/field/field') ;
7
7
 
8
- // SelectFieldView displays browser-native popup menu. To use this view,
9
- // you should either bake into the HTML the preset list of options, or
10
- // you can set the -objects property to an array of items to show. The
11
- // value is current value of the select.
12
- SC.SelectFieldView = SC.FieldView.extend({
8
+ /**
9
+ @class
10
+
11
+ SelectFieldView displays browser-native popup menu. To use this view,
12
+ you should either bake into the HTML the preset list of options, or
13
+ you can set the -objects property to an array of items to show. The
14
+ value is current value of the select.
15
+
16
+ @extends SC.FieldView
17
+ @author Charles Jolley
18
+ @version 1.0
19
+ */
20
+ SC.SelectFieldView = SC.FieldView.extend(
21
+ /** @scope SC.SelectFieldView.prototype */ {
13
22
 
14
23
  emptyElement: '<select></select>',
15
24
 
16
- // set this property to an array of items that will form the menu
17
- // you want to show.
25
+ /**
26
+ An array of items that will form the menu you want to show.
27
+ */
18
28
  objects: null,
19
29
 
20
- // if you set this to a non-null value, then the name shown for each
21
- // menu item will be pulled from the object using the named property.
22
- // if this is null, the collection objects themselves will be used.
30
+ /**
31
+ If you set this to a non-null value, then the name shown for each
32
+ menu item will be pulled from the object using the named property.
33
+ if this is null, the collection objects themselves will be used.
34
+ */
23
35
  nameKey: null,
24
36
 
25
- // if you set this to a non-null value, then the value of this key will
26
- // be used to sort the objects. If this is not set, then nameKey will
27
- // be used.
28
- sortKey: null,
37
+ /**
38
+ If you set this to a non-null value, then the value of this key will
39
+ be used to sort the objects. If this is not set, then nameKey will
40
+ be used.
41
+ */
42
+ sortKey: null,
29
43
 
30
- // set this to a non-null value to use a key from the passed set of objects
31
- // as the value for the options popup. If you don't set this, then the
32
- // objects themselves will be used as the value.
33
- valueKey: null,
44
+ /**
45
+ Set this to a non-null value to use a key from the passed set of objects
46
+ as the value for the options popup. If you don't set this, then the
47
+ objects themselves will be used as the value.
48
+ */
49
+ valueKey: null,
34
50
 
35
- // set this to non-null to place an empty option at the top of the menu.
36
- emptyName: null,
51
+ /**
52
+ set this to non-null to place an empty option at the top of the menu.
53
+ */
54
+ emptyName: null,
37
55
 
38
- // if true, the empty name will be localized.
39
- localize: false,
56
+ /**
57
+ if true, the empty name will be localized.
58
+ */
59
+ localize: false,
40
60
 
41
- // override this to change the enabled/disabled state of menu items as they
42
- // are built. Return false if you want the menu item to be disabled.
43
- validateMenuItem: function(itemValue, itemName) {
61
+ /**
62
+ override this to change the enabled/disabled state of menu items as they
63
+ are built. Return false if you want the menu item to be disabled.
64
+
65
+ @param itemValue the value for the item to validate
66
+ @param itemName the name of the menu item to validate
67
+ @returns YES if the item should be enabled, NO otherwise
68
+ */
69
+ validateMenuItem: function(itemValue, itemName) {
44
70
  return true ;
45
- },
71
+ },
46
72
 
47
- // override this method to implement your own sorting of the menu. By
48
- // default, menu items are sorted using the value shown.
49
- sortObjects: function(objects) {
73
+ /**
74
+ override this method to implement your own sorting of the menu. By
75
+ default, menu items are sorted using the value shown or the sortKey
76
+
77
+ @param objects the unsorted array of objects to display.
78
+ @returns sorted array of objects
79
+ */
80
+ sortObjects: function(objects) {
50
81
  var nameKey = this.get('sortKey') || this.get('nameKey') ;
51
82
  objects = objects.sort(function(a,b) {
52
83
  if (nameKey) {
@@ -57,32 +88,30 @@ SC.SelectFieldView = SC.FieldView.extend({
57
88
  }) ;
58
89
 
59
90
  return objects ;
60
- },
91
+ },
61
92
 
62
- // call this method to rebuild the menu manually. Normally you should not
63
- // need to do this since the menu will be rebuilt as its data changes.
64
- rebuildMenu: function() {
93
+ /**
94
+ call this method to rebuild the menu manually. Normally you should not
95
+ need to do this since the menu will be rebuilt as its data changes.
96
+ */
97
+ rebuildMenu: function() {
65
98
  this._rebuildMenu() ;
66
- },
67
-
68
-
69
- mouseDown: function(e)
70
- {
71
- e._stopWhenHandled = false;
72
- return false;
73
- },
74
-
75
-
76
- // .......................................
77
- // PRIVATE
78
- //
99
+ },
100
+
101
+ // .......................................
102
+ // PRIVATE
103
+ //
104
+
105
+ /** @private */
106
+ mouseDown: function(e) { e._stopWhenHandled = false; return false; },
79
107
 
80
- // when fetching the raw value, convert back to an object if needed...
81
- getFieldValue: function() {
108
+ // when fetching the raw value, convert back to an object if needed...
109
+ /** @private */
110
+ getFieldValue: function() {
82
111
  var value = this.rootElement.value ; // get raw value...
83
112
  var valueKey = this.get('valueKey') ;
84
113
  var objects = this.get('objects') ;
85
-
114
+
86
115
  // Handle empty selection.
87
116
  if (value == '***') {
88
117
  value = null ;
@@ -95,33 +124,34 @@ SC.SelectFieldView = SC.FieldView.extend({
95
124
  var found = null ; // matching object goes here.
96
125
  while(!found && (--loc >= 0)) {
97
126
  var object = objects[loc] ;
98
-
127
+
99
128
  // get value using valueKey if there is one or use object
100
129
  // map to _guid or toString.
101
130
  if (valueKey) object = (object.get) ? object.get(valueKey) : object[valueKey] ;
102
131
  ov = (object) ? ((object._guid) ? object._guid : object.toString()) : null ;
103
-
132
+
104
133
  // use this object value if it matches.
105
134
  if (value == ov) found = object ;
106
135
  }
107
136
  }
108
-
137
+
109
138
  return value ;
110
- },
139
+ },
111
140
 
112
- // when setting the raw value, convert from object...
113
- setFieldValue: function(nv) {
141
+ // when setting the raw value, convert from object...
142
+ /** @private */
143
+ setFieldValue: function(nv) {
114
144
  if (nv) {
115
145
  nv = (nv._guid) ? nv._guid : nv.toString() ;
116
146
  } else {
117
147
  nv = "***" ;
118
148
  }
119
149
  if (this.rootElement.value != nv) this.rootElement.value = nv ;
120
- },
121
-
122
- // this method is called anytime the objects property or any of its member
123
- // objects change.
124
- _rebuildMenu: function() {
150
+ },
151
+
152
+ // this method is called anytime the objects property or any of its member
153
+ // objects change.
154
+ _rebuildMenu: function() {
125
155
  // get list of objects.
126
156
  var nameKey = this.get('nameKey') ;
127
157
  var valueKey = this.get('valueKey') ;
@@ -136,18 +166,18 @@ SC.SelectFieldView = SC.FieldView.extend({
136
166
  objects = Array.from(objects) ; // make array.
137
167
  objects = this.sortObjects(objects) ; // sort'em.
138
168
  var html = [] ;
139
-
169
+
140
170
  var emptyName = this.get('emptyName') ;
141
171
  if (emptyName) {
142
172
  if (this.get('localize')) emptyName = emptyName.loc() ;
143
173
  html.push('<option value="***">%@</option>'.fmt(emptyName)) ;
144
174
  html.push('<option disabled="disabled"></option>') ;
145
175
  }
146
-
176
+
147
177
  // generate option elements.
148
178
  objects.each(function(object) {
149
179
  if (object) {
150
-
180
+
151
181
  // either get the name from the object or convert object to string.
152
182
  var name = (nameKey) ? ((object.get) ? object.get(nameKey) : object[nameKey]) : object.toString() ;
153
183
 
@@ -155,28 +185,28 @@ SC.SelectFieldView = SC.FieldView.extend({
155
185
  // then convert to a string or use _guid if one of available.
156
186
  var value = (valueKey) ? ((object.get) ? object.get(valueKey) : object[valueKey]) : object ;
157
187
  if (value) value = (value._guid) ? value._guid : value.toString() ;
158
-
188
+
159
189
  // render HTML
160
190
  var disable = (this.validateMenuItem && this.validateMenuItem(value, name)) ? '' : 'disabled="disabled" ' ;
161
191
  html.push('<option %@value="%@">%@</option>'.fmt(disable,value,name)) ;
162
-
192
+
163
193
  // null value means separator.
164
194
  } else {
165
195
  html.push('<option disabled="disabled"></option>') ;
166
196
  }
167
197
  }.bind(this) );
168
-
198
+
169
199
  // replace the contents of this HTML element.
170
200
  this.update(html.join(""));
171
201
  this.rootElement.value = fieldValue ;
172
-
202
+
173
203
  } else {
174
204
  this.set('value',null);
175
205
  }
176
- },
206
+ },
177
207
 
178
- // object changes to the objects array of objects if possible.
179
- _objectsObserver: function() {
208
+ // object changes to the objects array of objects if possible.
209
+ _objectsObserver: function() {
180
210
  if (!this._boundObserver) {
181
211
  this._boundObserver = this._objectsItemObserver.bind(this) ;
182
212
  }
@@ -185,7 +215,7 @@ SC.SelectFieldView = SC.FieldView.extend({
185
215
  var loc ;
186
216
  var objects = Array.from(this.get('objects')) ;
187
217
  var func = this._boundObserver ;
188
-
218
+
189
219
  // stop observing old objects.
190
220
  if (this._objects) {
191
221
  loc = this._objects.length ;
@@ -206,7 +236,7 @@ SC.SelectFieldView = SC.FieldView.extend({
206
236
  this._objects = objects ;
207
237
  this._nameKey = this.get('nameKey') ;
208
238
  this._valueKey = this.get('valueKey') ;
209
-
239
+
210
240
  if (this._objects) {
211
241
  loc = this._objects.length ;
212
242
  while(--loc >= 0) {
@@ -221,41 +251,37 @@ SC.SelectFieldView = SC.FieldView.extend({
221
251
  } // if (object &&...)
222
252
  } // while(--loc)
223
253
  } // if (this._objects)
224
-
254
+
225
255
  this._rebuildMenu() ;
226
256
  } // if (this.didChangeFor...)
227
- }.observes('objects','nameKey','valueKey'),
257
+ }.observes('objects','nameKey','valueKey'),
228
258
 
229
- // this is invoked anytime an item we are interested in in the menu changes
230
- // rebuild the menu when this happens, but only one time.
231
- _objectsItemObserver: function(item, key, value) {
259
+ // this is invoked anytime an item we are interested in in the menu changes
260
+ // rebuild the menu when this happens, but only one time.
261
+ _objectsItemObserver: function(item, key, value) {
232
262
  if (item.didChangeFor(this._guid, key)) {
233
263
  console.log('rebuildMenu') ;
234
264
  this._rebuildMenu() ;
235
265
  }
236
- },
237
-
238
-
266
+ },
239
267
 
240
- _fieldDidFocus: function()
241
- {
268
+ _fieldDidFocus: function() {
242
269
  var isFocused = this.get('isFocused');
243
270
  if (!isFocused) this.set('isFocused', true);
244
271
  },
245
- _fieldDidBlur: function()
246
- {
272
+
273
+ _fieldDidBlur: function() {
247
274
  var isFocused = this.get('isFocused');
248
275
  if (isFocused) this.set('isFocused', false);
249
276
  },
250
- _isFocusedObserver: function()
251
- {
277
+
278
+ _isFocusedObserver: function() {
252
279
  var isFocused = this.get('isFocused');
253
280
  this.setClassName('focus', isFocused);
254
281
  }.observes('isFocused'),
255
282
 
256
283
 
257
- init: function()
258
- {
284
+ init: function() {
259
285
  arguments.callee.base.call(this);
260
286
  this._rebuildMenu();
261
287