sproutcore 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +233 -0
- data/Manifest.txt +67 -34
- data/bin/sc-build +12 -1
- data/bin/sc-gen +1 -1
- data/bin/sproutcore +14 -0
- data/clients/sc_docs/controllers/docs.js +38 -8
- data/clients/sc_docs/english.lproj/body.css +80 -127
- data/clients/sc_docs/english.lproj/body.rhtml +43 -23
- data/clients/sc_docs/english.lproj/no_docs.rhtml +2 -1
- data/clients/sc_docs/english.lproj/tabs.rhtml +16 -0
- data/clients/sc_docs/main.js +14 -9
- data/clients/sc_docs/models/doc.js +1 -1
- data/clients/sc_docs/tests/controllers/docs.rhtml +1 -2
- data/clients/sc_docs/tests/models/doc.rhtml +1 -2
- data/clients/sc_docs/tests/views/doc_frame.rhtml +1 -2
- data/clients/sc_docs/tests/views/doc_label_view.rhtml +1 -2
- data/clients/sc_docs/views/doc_frame.js +1 -1
- data/clients/sc_test_runner/controllers/runner.js +31 -8
- data/clients/sc_test_runner/english.lproj/body.css +62 -122
- data/clients/sc_test_runner/english.lproj/body.rhtml +62 -26
- data/clients/sc_test_runner/main.js +1 -6
- data/clients/sc_test_runner/models/test.js +14 -1
- data/clients/sc_test_runner/views/runner_frame.js +4 -2
- data/clients/view_builder/builders/builder.js +339 -0
- data/clients/view_builder/builders/button.js +81 -0
- data/clients/view_builder/controllers/document.js +21 -0
- data/clients/view_builder/core.js +19 -0
- data/clients/view_builder/english.lproj/body.css +77 -0
- data/clients/view_builder/english.lproj/body.rhtml +41 -0
- data/clients/{sc_docs → view_builder}/english.lproj/controls.css +0 -0
- data/clients/view_builder/english.lproj/strings.js +14 -0
- data/clients/view_builder/main.js +38 -0
- data/clients/view_builder/tests/controllers/document.rhtml +20 -0
- data/clients/view_builder/tests/views/builder.rhtml +20 -0
- data/clients/view_builder/views/builder.js +23 -0
- data/frameworks/prototype/prototype.js +1 -1
- data/frameworks/sproutcore/Core.js +32 -7
- data/frameworks/sproutcore/README +1 -1
- data/frameworks/sproutcore/animation/animation.js +411 -0
- data/frameworks/sproutcore/controllers/array.js +17 -9
- data/frameworks/sproutcore/controllers/collection.js +9 -110
- data/frameworks/sproutcore/controllers/controller.js +1 -1
- data/frameworks/sproutcore/controllers/object.js +2 -1
- data/frameworks/sproutcore/drag/drag.js +267 -56
- data/frameworks/sproutcore/drag/drag_data_source.js +24 -16
- data/frameworks/sproutcore/drag/drag_source.js +53 -42
- data/frameworks/sproutcore/drag/drop_target.js +2 -2
- data/frameworks/sproutcore/english.lproj/buttons.css +337 -236
- data/frameworks/sproutcore/english.lproj/core.css +115 -0
- data/frameworks/sproutcore/english.lproj/icons.css +227 -0
- data/{clients/sc_docs → frameworks/sproutcore}/english.lproj/images/indicator.gif +0 -0
- data/frameworks/sproutcore/english.lproj/images/sc-theme-sprite.png +0 -0
- data/frameworks/sproutcore/english.lproj/images/sc-theme-ysprite.png +0 -0
- data/frameworks/sproutcore/english.lproj/images/shared-icons.png +0 -0
- data/frameworks/sproutcore/english.lproj/menu.css +1 -1
- data/frameworks/sproutcore/english.lproj/strings.js +1 -1
- data/frameworks/sproutcore/english.lproj/theme.css +405 -31
- data/frameworks/sproutcore/foundation/application.js +15 -11
- data/frameworks/sproutcore/foundation/benchmark.js +1 -1
- data/frameworks/sproutcore/foundation/binding.js +2 -2
- data/frameworks/sproutcore/foundation/date.js +1 -1
- data/frameworks/sproutcore/foundation/error.js +1 -1
- data/frameworks/sproutcore/foundation/input_manager.js +32 -21
- data/frameworks/sproutcore/foundation/mock.js +1 -1
- data/frameworks/sproutcore/foundation/node_descriptor.js +9 -6
- data/frameworks/sproutcore/foundation/object.js +249 -177
- data/frameworks/sproutcore/foundation/page.js +5 -2
- data/frameworks/sproutcore/foundation/path_module.js +11 -10
- data/frameworks/sproutcore/foundation/responder.js +5 -2
- data/frameworks/sproutcore/foundation/routes.js +17 -13
- data/frameworks/sproutcore/foundation/run_loop.js +249 -11
- data/frameworks/sproutcore/foundation/server.js +1 -1
- data/frameworks/sproutcore/foundation/set.js +3 -3
- data/frameworks/sproutcore/foundation/string.js +5 -3
- data/frameworks/sproutcore/foundation/timer.js +371 -0
- data/frameworks/sproutcore/foundation/undo_manager.js +1 -1
- data/frameworks/sproutcore/foundation/unittest.js +3 -3
- data/frameworks/sproutcore/foundation/utils.js +161 -2
- data/frameworks/sproutcore/globals/panels.js +1 -1
- data/frameworks/sproutcore/globals/popups.js +4 -3
- data/frameworks/sproutcore/globals/window.js +44 -4
- data/frameworks/sproutcore/lib/button_views.rb +328 -0
- data/frameworks/sproutcore/lib/collection_view.rb +80 -0
- data/frameworks/sproutcore/lib/core_views.rb +281 -0
- data/frameworks/sproutcore/lib/form_views.rb +253 -0
- data/frameworks/sproutcore/lib/index.rhtml +2 -0
- data/frameworks/sproutcore/lib/menu_views.rb +88 -0
- data/frameworks/sproutcore/{foundation → mixins}/array.js +60 -29
- data/frameworks/sproutcore/mixins/control.js +265 -0
- data/frameworks/sproutcore/mixins/delegate_support.js +66 -0
- data/frameworks/sproutcore/{foundation → mixins}/observable.js +176 -6
- data/frameworks/sproutcore/mixins/scrollable.js +245 -0
- data/frameworks/sproutcore/mixins/selection_support.js +148 -0
- data/frameworks/sproutcore/mixins/validatable.js +152 -0
- data/frameworks/sproutcore/models/collection.js +5 -5
- data/frameworks/sproutcore/models/record.js +1 -1
- data/frameworks/sproutcore/models/store.js +1 -1
- data/frameworks/sproutcore/panes/dialog.js +1 -1
- data/frameworks/sproutcore/panes/manager.js +1 -1
- data/frameworks/sproutcore/panes/menu.js +1 -1
- data/frameworks/sproutcore/panes/overlay.js +2 -2
- data/frameworks/sproutcore/panes/panel.js +1 -1
- data/frameworks/sproutcore/panes/picker.js +1 -1
- data/frameworks/sproutcore/tests/controllers/array.rhtml +44 -4
- data/frameworks/sproutcore/tests/foundation/timer/invalidate.rhtml +33 -0
- data/frameworks/sproutcore/tests/foundation/timer/invokeLater.rhtml +145 -0
- data/frameworks/sproutcore/tests/foundation/timer/isPaused.rhtml +70 -0
- data/frameworks/sproutcore/tests/foundation/timer/schedule.rhtml +145 -0
- data/frameworks/sproutcore/tests/views/{scroll.rhtml → checkbox.rhtml} +3 -3
- data/frameworks/sproutcore/tests/views/{collection.rhtml → collection/base.rhtml} +33 -32
- data/frameworks/sproutcore/tests/views/collection/incremental_rendering.rhtml +260 -0
- data/frameworks/sproutcore/tests/views/image_cell.rhtml +19 -0
- data/frameworks/sproutcore/tests/views/label_item.rhtml +2 -4
- data/frameworks/sproutcore/tests/views/list.rhtml +2 -3
- data/frameworks/sproutcore/tests/views/list_item.rhtml +20 -0
- data/frameworks/sproutcore/tests/views/slider.rhtml +20 -0
- data/frameworks/sproutcore/tests/views/text_cell.rhtml +19 -0
- data/frameworks/sproutcore/tests/views/view/clippingFrame.rhtml +395 -0
- data/frameworks/sproutcore/tests/views/view/frame.rhtml +353 -0
- data/frameworks/sproutcore/tests/views/view/innerFrame.rhtml +347 -0
- data/frameworks/sproutcore/tests/views/view/isVisibleInWindow.rhtml +148 -0
- data/frameworks/sproutcore/tests/views/view/scrollFrame.rhtml +468 -0
- data/frameworks/sproutcore/validators/credit_card.js +33 -13
- data/frameworks/sproutcore/validators/date.js +26 -6
- data/frameworks/sproutcore/validators/email.js +21 -3
- data/frameworks/sproutcore/validators/not_empty.js +11 -1
- data/frameworks/sproutcore/validators/number.js +18 -4
- data/frameworks/sproutcore/validators/password.js +12 -1
- data/frameworks/sproutcore/validators/validator.js +204 -194
- data/frameworks/sproutcore/views/{button.js → button/button.js} +96 -94
- data/frameworks/sproutcore/views/button/checkbox.js +29 -0
- data/frameworks/sproutcore/views/button/disclosure.js +42 -0
- data/frameworks/sproutcore/views/button/radio.js +29 -0
- data/frameworks/sproutcore/views/{collection.js → collection/collection.js} +1373 -1024
- data/frameworks/sproutcore/views/collection/grid.js +124 -46
- data/frameworks/sproutcore/views/collection/image_cell.js +17 -46
- data/frameworks/sproutcore/views/collection/list.js +45 -35
- data/frameworks/sproutcore/views/collection/source_list.js +386 -0
- data/frameworks/sproutcore/views/collection/table.js +118 -0
- data/frameworks/sproutcore/views/container.js +7 -2
- data/frameworks/sproutcore/views/error_explanation.js +23 -10
- data/frameworks/sproutcore/views/{checkbox_field.js → field/checkbox_field.js} +16 -6
- data/frameworks/sproutcore/views/field/field.js +219 -0
- data/frameworks/sproutcore/views/{radio_field.js → field/radio_field.js} +27 -12
- data/frameworks/sproutcore/views/{select_field.js → field/select_field.js} +116 -90
- data/frameworks/sproutcore/views/{text_field.js → field/text_field.js} +57 -8
- data/frameworks/sproutcore/views/{textarea_field.js → field/textarea_field.js} +13 -3
- data/frameworks/sproutcore/views/filter_button.js +2 -2
- data/frameworks/sproutcore/views/form.js +3 -3
- data/frameworks/sproutcore/views/image.js +128 -21
- data/frameworks/sproutcore/views/inline_text_editor.js +1 -1
- data/frameworks/sproutcore/views/label.js +149 -92
- data/frameworks/sproutcore/views/list_item.js +225 -0
- data/frameworks/sproutcore/views/menu_item.js +10 -4
- data/frameworks/sproutcore/views/pagination.js +11 -4
- data/frameworks/sproutcore/views/popup_button.js +25 -21
- data/frameworks/sproutcore/views/popup_menu.js +10 -4
- data/frameworks/sproutcore/views/progress.js +29 -16
- data/frameworks/sproutcore/views/radio_group.js +1 -1
- data/frameworks/sproutcore/views/scroll.js +60 -20
- data/frameworks/sproutcore/views/segmented.js +1 -1
- data/frameworks/sproutcore/views/slider.js +132 -0
- data/frameworks/sproutcore/views/source_list_group.js +130 -0
- data/frameworks/sproutcore/views/spinner.js +1 -1
- data/frameworks/sproutcore/views/split.js +292 -0
- data/frameworks/sproutcore/views/split_divider.js +109 -0
- data/frameworks/sproutcore/views/tab.js +1 -1
- data/frameworks/sproutcore/views/toolbar.js +1 -1
- data/frameworks/sproutcore/views/view.js +1272 -591
- data/generators/client/templates/english.lproj/body.css +1 -1
- data/generators/controller/controller_generator.rb +1 -1
- data/generators/controller/templates/test.rhtml +2 -1
- data/generators/model/templates/test.rhtml +1 -1
- data/generators/test/templates/test.rhtml +1 -1
- data/generators/view/templates/test.rhtml +1 -1
- data/jsdoc/templates/sproutcore/class.tmpl +241 -338
- data/jsdoc/templates/sproutcore/default.css +105 -155
- data/jsdoc/templates/sproutcore/index.tmpl +43 -8
- data/jsdoc/templates/sproutcore/publish.js +9 -4
- data/lib/sproutcore/build_tools/html_builder.rb +29 -13
- data/lib/sproutcore/build_tools/resource_builder.rb +1 -1
- data/lib/sproutcore/bundle.rb +86 -25
- data/lib/sproutcore/jsdoc.rb +2 -0
- data/lib/sproutcore/version.rb +1 -1
- data/lib/sproutcore/view_helpers.rb +36 -3
- data/tasks/deployment.rake +1 -1
- metadata +69 -36
- data/clients/sc_docs/english.lproj/icons/small/next.png +0 -0
- data/clients/sc_docs/english.lproj/icons/small/reset.png +0 -0
- data/clients/sc_docs/english.lproj/images/gradients.png +0 -0
- data/clients/sc_docs/english.lproj/images/toolbar.png +0 -0
- data/clients/sc_docs/english.lproj/warning.rhtml +0 -6
- data/clients/sc_test_runner/english.lproj/warning.rhtml +0 -6
- data/frameworks/sproutcore/english.lproj/buttons.png +0 -0
- data/frameworks/sproutcore/english.lproj/collections.css +0 -82
- data/frameworks/sproutcore/english.lproj/images/buttons-sprite.png +0 -0
- data/frameworks/sproutcore/views/collection/collection_item.js +0 -36
- data/frameworks/sproutcore/views/collection/text_cell.js +0 -128
- data/frameworks/sproutcore/views/field.js +0 -214
- data/frameworks/sproutcore/views/workspace.js +0 -170
- data/generators/client/templates/english.lproj/controls.css +0 -0
- data/generators/framework/templates/english.lproj/body.css +0 -0
- data/generators/framework/templates/english.lproj/body.rhtml +0 -3
- data/generators/framework/templates/english.lproj/controls.css +0 -0
- data/lib/sproutcore/view_helpers/button_views.rb +0 -302
- data/lib/sproutcore/view_helpers/core_views.rb +0 -292
- data/lib/sproutcore/view_helpers/form_views.rb +0 -258
- data/lib/sproutcore/view_helpers/menu_views.rb +0 -94
@@ -1,6 +1,6 @@
|
|
1
1
|
// ========================================================================
|
2
2
|
// SproutCore
|
3
|
-
// copyright 2006-
|
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
|
-
|
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-
|
3
|
+
// copyright 2006-2008 Sprout Systems, Inc.
|
4
4
|
// ========================================================================
|
5
5
|
|
6
6
|
require('views/label');
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
-
|
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
|
-
|
36
|
-
var errors = this._errorsFor(this.get('
|
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
|
-
|
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.
|
55
|
+
this._valueObserver() ;
|
44
56
|
}
|
57
|
+
|
45
58
|
});
|
@@ -1,13 +1,23 @@
|
|
1
1
|
// ========================================================================
|
2
2
|
// SproutCore
|
3
|
-
// copyright 2006-
|
3
|
+
// copyright 2006-2008 Sprout Systems, Inc.
|
4
4
|
// ========================================================================
|
5
5
|
|
6
|
-
require('views/field') ;
|
6
|
+
require('views/field/field') ;
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
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.
|
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-
|
3
|
+
// copyright 2006-2008 Sprout Systems, Inc.
|
4
4
|
// ========================================================================
|
5
5
|
|
6
|
-
require('views/field') ;
|
6
|
+
require('views/field/field') ;
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
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
|
-
|
24
|
-
|
25
|
-
|
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-
|
3
|
+
// copyright 2006-2008 Sprout Systems, Inc.
|
4
4
|
// ========================================================================
|
5
5
|
|
6
|
-
require('views/field') ;
|
6
|
+
require('views/field/field') ;
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
17
|
-
|
25
|
+
/**
|
26
|
+
An array of items that will form the menu you want to show.
|
27
|
+
*/
|
18
28
|
objects: null,
|
19
29
|
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
36
|
-
|
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
|
-
|
39
|
-
|
56
|
+
/**
|
57
|
+
if true, the empty name will be localized.
|
58
|
+
*/
|
59
|
+
localize: false,
|
40
60
|
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
-
|
48
|
-
|
49
|
-
|
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
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
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
|
-
|
81
|
-
|
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
|
-
|
113
|
-
|
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
|
-
|
123
|
-
|
124
|
-
|
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
|
-
|
179
|
-
|
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
|
-
|
257
|
+
}.observes('objects','nameKey','valueKey'),
|
228
258
|
|
229
|
-
|
230
|
-
|
231
|
-
|
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
|
-
|
246
|
-
{
|
272
|
+
|
273
|
+
_fieldDidBlur: function() {
|
247
274
|
var isFocused = this.get('isFocused');
|
248
275
|
if (isFocused) this.set('isFocused', false);
|
249
276
|
},
|
250
|
-
|
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
|
|