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.
- 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
|
|