comparison src/DML/MainVisBundle/Resources/assets/marionette/modules/MainRegionModule/MainRegionModule.50-cgpma.textfield.js @ 0:493bcb69166c

added public content
author Daniel Wolff
date Tue, 09 Feb 2016 20:54:02 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:493bcb69166c
1 "use strict";
2
3 (function($) {
4 $.widget("cgpma.textfield", {
5
6 options: {
7 value: "",
8 baseValue: "",
9 autocompleteMaxItemCount: 15,
10 autocompleteSort: false,
11 autocompleteSuggestions: null,
12 autocompleteIsAdvisory: false,
13 autocompleteCSSClasses: ""
14 },
15
16 isFocused: function() {
17 var widget = this;
18 return widget.$input.is(":focus");
19 },
20
21 focus: function() {
22 var widget = this;
23 return widget.$input.focus();
24 },
25
26 getTextRange: function() {
27 var widget = this;
28 return widget.$input.textrange();
29 },
30
31 setTextRange: function(textRange) {
32 var widget = this;
33 if (textRange.start != textRange.end) {
34 return widget.$input.textrange("set", textRange.start, textRange.end);
35 }
36 return widget.$input.textrange("setcursor", textRange.position);
37 },
38
39 _create : function() {
40 var widget = this;
41 widget.$element = this.element;
42 widget.$input = $.bem.generateElement("input", "cgpma", "textfield-input");
43 widget.$input.appendTo(widget.$element);
44
45 widget.$input.data("widget", widget);
46
47 widget._applyAutocompleteSuggestions();
48
49 widget.$input.bind("input", widget.__handleInputChange);
50 widget.$input.bind("keydown", widget.__handleInputKeyDown);
51 widget.$input.bind("keyup", widget.__handleInputKeyUp);
52 widget.$input.bind("click", widget.__handleInputClick);
53
54 },
55
56 _applyAutocompleteSuggestions: function() {
57 var widget = this;
58
59 if (widget.$input.data("ui-autocomplete")) {
60 widget.$input.autocomplete("destroy");
61 }
62
63 var autocompleteSuggestions = widget.options.autocompleteSuggestions;
64 if (!autocompleteSuggestions) {
65 return;
66 delete widget._invertedAutocompleteSuggestions;
67 }
68 widget._invertedAutocompleteSuggestions = _.invert(autocompleteSuggestions);
69
70 widget.$input.autocomplete({
71 delay : 0,
72 minLength : 0,
73 source : $.proxy(widget, "_autocompleteSource")
74 });
75
76 widget.$input.autocomplete(
77 "widget").addClass(widget.options.autocompleteCSSClasses);
78
79 widget._on(widget.$input, {
80 autocompleteselect : widget.__handleInputChange,
81 autocompleteopen : widget.__handleAutocompleteOpen,
82 autocompleteclose : widget.__handleAutocompleteClose,
83 //autocompletechange : widget.__handleInputChange
84 });
85 },
86
87 _autocompleteSource: function(request, response) {
88 var widget = this;
89
90 var matcher = new RegExp($.ui.autocomplete
91 .escapeRegex(_.str.trim(request.term)), "i");
92
93 var responseItems = [];
94 _.each(widget.options.autocompleteSuggestions, function(kindName, kind) {
95 if (widget.options.autocompleteAlwaysFull || !request.term || matcher.test(kindName)) {
96 responseItems.push({
97 label : kindName,
98 value : kindName,
99 });
100 };
101 });
102
103 if (responseItems.length == 1 && responseItems[0].label === request.term) {
104 responseItems = [];
105 }
106 if (responseItems.length > widget.options.autocompleteMaxItemCount) {
107 responseItems = responseItems.slice(0, widget.options.autocompleteMaxItemCount);
108 }
109 if (widget.options.autocompleteSort) {
110 responseItems = _.sortBy(responseItems, "label");
111 }
112
113 response(responseItems);
114 },
115
116 _createShowAllButton : function() {
117 return;
118 var input = this.input, wasOpen = false;
119 $("<a>").attr("tabIndex", -1).attr("title",
120 "Show All Items").tooltip().appendTo(
121 this.wrapper).button({
122 icons : {
123 primary : "ui-icon-triangle-1-s"
124 },
125 text : false
126 }).removeClass("ui-corner-all").addClass(
127 "custom-combobox-toggle ui-corner-right")
128 .mousedown(
129 function() {
130 wasOpen = input.autocomplete(
131 "widget")
132 .is(":visible");
133 }).click(function() {
134 input.focus();
135 // Close if already visible
136 if (wasOpen) {
137 return;
138 }
139 // Pass empty string as value to search
140 // for, displaying all results
141 input.autocomplete("search", "");
142 });
143 },
144
145 _isAutocompleteVisible : function() {
146 var widget = this;
147 if (widget.$input.data("ui-autocomplete")) {
148 return widget.$input.autocomplete("widget").is(":visible");
149 } else {
150 return false;
151 }
152 },
153
154 _destroy : function() {
155 this.$input.removeData();
156 },
157
158 _setOption: function (key, value) {
159 var widget = this;
160
161 // Check if such option exists, throw an error if not
162 if (!widget.options.hasOwnProperty(key)) {
163 throw "Option " + key + " does not exist";
164 }
165
166 // Check if value matches what it was, do nothing if yes
167 if (value === widget.options[key] || (_.isArray(value) && _.isEqual(value, widget.options[key]))) {
168 return;
169 }
170
171 // Save old option value
172 var prev = widget.options[key];
173
174 // Apply the option
175 this._super(key, value);
176
177 // Call corresponding update method depending on the option key
178 switch (key) {
179
180 case "value":
181 this._applyValue();
182 break;
183
184 case "baseValue":
185 this._updateStatus();
186 break;
187
188 case "autocompleteSuggestions":
189 this._applyAutocompleteSuggestions();
190 break;
191 }
192 widget._trigger("change" + key.toLowerCase(), null, {newValue: value, prevValue: prev});
193 },
194
195 _realValueToInputValue: function(realValue) {
196 var widget = this;
197
198 var value = realValue;
199 var valueInOptionsIsString = _.isString(value);
200 var trimmedValueInOptions = valueInOptionsIsString ? _.str.trim(value) : value;
201 var trimmedCharsOnLeft = valueInOptionsIsString ? value.indexOf(trimmedValueInOptions) : null;
202 var trimmedCharsOnRight = valueInOptionsIsString ? value.length - trimmedValueInOptions.length - trimmedCharsOnLeft : null;
203
204 if (valueInOptionsIsString && widget.options.autocompleteSuggestions && widget.options.autocompleteSuggestions[trimmedValueInOptions] !== undefined) {
205 value = value.substring(0, trimmedCharsOnLeft) + widget.options.autocompleteSuggestions[trimmedValueInOptions] + value.substring(value.length - trimmedCharsOnRight);
206 }
207 if (valueInOptionsIsString && value.length >= 4 && value.substring(0, 2) == "__" && value.substring(value.length - 2) == "__") {
208 value = value.substring(2, value.length - 2);
209 }
210
211 return value;
212
213 },
214
215 _inputValueToRealValue: function(inputValue) {
216 var widget = this;
217
218 var value = inputValue;
219 var trimmedValueInInput = _.str.trim(value);
220 var trimmedCharsOnLeft = value.indexOf(trimmedValueInInput);
221 var trimmedCharsOnRight = value.length - trimmedValueInInput.length - trimmedCharsOnLeft;
222
223 if (widget.options.autocompleteSuggestions && widget.options.autocompleteSuggestions[trimmedValueInInput] && widget.options.autocompleteSuggestions[trimmedValueInInput] !== trimmedValueInInput) {
224 value = "__" + value + "__";
225 }
226 if (widget._invertedAutocompleteSuggestions && widget._invertedAutocompleteSuggestions[trimmedValueInInput] !== undefined) {
227 value = value.substring(0, trimmedCharsOnLeft) + widget._invertedAutocompleteSuggestions[trimmedValueInInput] + value.substring(value.length - trimmedCharsOnRight);
228 }
229
230 return value;
231 },
232
233 _applyValue: function() {
234 var widget = this;
235
236 var inputValue = widget._realValueToInputValue(widget.options.value);
237
238 if (inputValue !== widget.$input.val() && !widget._doNotUpdateInputOnValueChange) {
239 widget.$input.val(inputValue);
240 }
241 widget._updateStatus();
242 },
243
244 _updateStatus: function() {
245 var widget = this;
246 widget.$element.toggleClass("cgpma__textfield_status_modified", widget.options.baseValue !== widget.options.value);
247 },
248
249 __handleInputChange: function() {
250
251 // this can be an instance of the widget or the DOM node
252 var $input = null;
253 if (this.element) {
254 $input = this.$input;
255 } else {
256 $input = $(this);
257 }
258 var widget = $input.data("widget");
259 var valueInInput = $input.val();
260
261 if (arguments[1] && arguments[1].item) {
262 valueInInput = arguments[1].item.value;
263 }
264
265 var realValue = widget._inputValueToRealValue(valueInInput);
266
267 widget._setOption("value", realValue);
268 },
269
270 __handleInputKeyDown: function(event) {
271 var $this = $(this);
272 var widget = $this.data("widget");
273 if (event.keyCode == 13) {
274 //widget._lastInputChangeWasCausedByAutocomplete = widget.$nput.autocomplete("widget").is(":visible");
275 }
276 if (event.keyCode == 38 || event.keyCode == 40) { // up or down
277 if (widget.$input.data("ui-autocomplete")) {
278 if (!widget._isAutocompleteVisible()) {
279 widget.$input.autocomplete("search", "");
280 } else {
281 widget._doNotUpdateInputOnValueChange = true;
282 widget._setOption("value", widget._inputValueToRealValue(widget.$input.val()));
283 delete widget._doNotUpdateInputOnValueChange;
284 }
285 }
286 }
287 },
288
289 __handleInputKeyUp: function(event) {
290 var $this = $(this);
291 var widget = $this.data("widget");
292 if (event.keyCode == 13) {
293 if (widget._lastInputChangeWasCausedByAutocomplete) {
294 widget._lastInputChangeWasCausedByAutocomplete = false;
295 } else {
296 widget._trigger("apply");
297 if (widget.$input.data("ui-autocomplete")) {
298 widget.$input.autocomplete("close");
299 }
300 }
301 }
302 if (event.keyCode == 27) {
303 if (!widget._isAutocompleteVisible()) {
304 widget._trigger("discard");
305 }
306 event.preventDefault();
307 }
308 },
309
310 __handleAutocompleteOpen: function(event) {
311 var widget = this;
312 widget.$element.addClass("cgpma__textfield_autocomplete-is-open");
313 },
314
315 __handleAutocompleteClose: function(event) {
316 var widget = this;
317 widget.$element.removeClass("cgpma__textfield_autocomplete-is-open");
318 },
319
320 __handleInputClick: function() {
321 var $this = $(this);
322 var widget = $this.data("widget");
323 if (widget.$input.data("ui-autocomplete")) {
324 widget.$input.autocomplete("search", "");
325 }
326 }
327
328 });
329 })(jQuery);