aboutsummaryrefslogtreecommitdiff
path: root/node_modules/montage/ui/token-field/token-field.reel/token-field.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/montage/ui/token-field/token-field.reel/token-field.js')
-rw-r--r--node_modules/montage/ui/token-field/token-field.reel/token-field.js221
1 files changed, 221 insertions, 0 deletions
diff --git a/node_modules/montage/ui/token-field/token-field.reel/token-field.js b/node_modules/montage/ui/token-field/token-field.reel/token-field.js
new file mode 100644
index 00000000..9f08e477
--- /dev/null
+++ b/node_modules/montage/ui/token-field/token-field.reel/token-field.js
@@ -0,0 +1,221 @@
1/* <copyright>
2 This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
3 No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
4 (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved.
5 </copyright> */
6var Montage = require("montage").Montage,
7 Component = require("ui/component").Component;
8
9var KEY_DELETE = 46,
10KEY_BACKSPACE = 8,
11KEY_LEFT = 37,
12KEY_UP = 38,
13KEY_RIGHT = 39,
14KEY_DOWN = 40;
15
16exports.TokenField = Montage.create(Component, {
17
18 delegate: {value: null},
19
20 values: {value: null},
21
22 /**
23 * Path to a String within an Object that is representative of the Object
24 */
25 textPropertyPath: {value: null},
26
27 /**
28 * Allow ad-hoc strings (strings that do not have corresponding represented object) to be entered.
29 */
30 allowAdHocValues: {value: null},
31
32 placeholder: {value: null},
33
34
35 // private
36
37 __hasFocus: {value: null},
38 _hasFocus: {
39 get: function() {
40 return this.__hasFocus;
41 },
42 set: function(value) {
43 if(value != this.__hasFocus) {
44 this.__hasFocus = value;
45 this.needsDraw = true;
46 }
47 }
48 },
49
50 _tokensController: {value: null},
51 _tokenList: {value: null, enumerable: false},
52 _autocomplete: {value: null, enumerable: false},
53 __autocompleteValue: {value: null},
54 _autocompleteValue: {
55 get: function() {
56 return this.__autocompleteValue;
57 },
58 set: function(value) {
59 this.__autocompleteValue = value;
60 }
61 },
62
63 __suggestedValue: {value: null},
64 _suggestedValue: {
65 get: function() {
66 return this.__suggestedValue;
67 },
68 set: function(newValue) {
69 if(newValue) {
70 var representedObject;
71 if(!this.allowAdHocValues && String.isString(newValue)) {
72 // since ad-hoc values are not allowed, check with the delegate
73 // if a representedObject can be found for this string
74 representedObject = this.callDelegateMethod('getRepresentedObject', newValue);
75 } else {
76 representedObject = newValue;
77 }
78 if(representedObject) {
79 this.__suggestedValue = representedObject;
80 // able to find a representedObject
81 if(!this.values) {
82 this.values = [];
83 }
84 this.values.push(this.__suggestedValue);
85 this._autocomplete.value = '';
86 }
87
88 }
89 }
90 },
91
92 prepareForActivationEvents: {
93 value: function() {
94 this.element.addEventListener('mouseup', this);
95 }
96 },
97
98 prepareForDraw: {
99 value: function() {
100 this._autocomplete.delegate = this.delegate;
101 if(this.identifier) {
102 this._autocomplete.identifier = this.identifier;
103 // @todo : this might be a problem. Since delegate methods are prefixed with
104 // the identifier
105 //this.identifier = 'token-field-' + this.identifier;
106 }
107 this._autocomplete.element.addEventListener("keyup", this);
108 }
109 },
110
111 draw: {
112 value: function() {
113 if(this._hasFocus) {
114 this._autocomplete.element.focus();
115 this.__hasFocus = false;
116 } else {
117 if(this.placeholder) {
118 this._autocomplete.element.style.width = 'auto';
119 }
120 }
121 }
122 },
123
124 // Event handling
125 handleMouseup: {
126 value: function(event) {
127 this._hasFocus = true;
128 }
129 },
130
131 handleKeyup: {
132 enumerable: false,
133 value: function(e) {
134 var code = e.keyCode;
135 //console.log('keyCode', code);
136 if(this.values && this.values.length > 0) {
137 var selectedIndexes = this._tokensController.selectedIndexes;
138 var selectedIndex = (selectedIndexes && selectedIndexes.length > 0 ? selectedIndexes[0] : null);
139 var lastIndex = this.values.length - 1, len = this.values.length;
140
141 switch(code) {
142 // @todo - check Keycode in Windows/Linux/Mobile browsers
143 case KEY_BACKSPACE:
144 case KEY_DELETE:
145 // Only remove the token if the token has already been selected
146 // So the behavior is to select the last token if it is not selected already.
147 // If selected already, then remove it
148
149 if(!this._autocompleteValue) {
150 // check if the selected token is the last one
151 if(selectedIndexes && selectedIndexes.length > 0) {
152 // removes the selected one
153 this._tokensController.remove();
154 } else {
155 this._tokensController.selectedIndexes = [this.values.length-1];
156 }
157 }
158
159 break;
160
161 case KEY_LEFT:
162 if(!this._autocompleteValue) {
163 if(selectedIndex != null) {
164 selectedIndex = selectedIndex - 1;
165 if(selectedIndex < 0) {
166 selectedIndex = lastIndex;
167 }
168 } else {
169 selectedIndex = lastIndex;
170 }
171 this._tokensController.selectedIndexes = [selectedIndex];
172 }
173
174 break;
175
176 case KEY_RIGHT:
177 if(!this._autocompleteValue) {
178 if(selectedIndex != null) {
179 selectedIndex = selectedIndex + 1;
180 if(selectedIndex > lastIndex) {
181 selectedIndex = 0;
182 }
183 } else {
184 selectedIndex = 0;
185 }
186 this._tokensController.selectedIndexes = [selectedIndex];
187 }
188
189 break;
190
191
192 case KEY_UP:
193 if(selectedIndex != null) {
194 this._tokensController.selectedIndexes = [0];
195 }
196
197 break;
198
199 case KEY_DOWN:
200 if(selectedIndex != null) {
201 this._tokensController.selectedIndexes = [lastIndex];
202 }
203
204 break;
205
206
207 default:
208 this._tokensController.selectedIndexes = [];