diff options
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.js | 221 |
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> */ | ||
6 | var Montage = require("montage").Montage, | ||
7 | Component = require("ui/component").Component; | ||
8 | |||
9 | var KEY_DELETE = 46, | ||
10 | KEY_BACKSPACE = 8, | ||
11 | KEY_LEFT = 37, | ||
12 | KEY_UP = 38, | ||
13 | KEY_RIGHT = 39, | ||
14 | KEY_DOWN = 40; | ||
15 | |||
16 | exports.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; | ||