1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | 'use strict';
|
7 |
|
8 | function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
9 |
|
10 | var Util = _interopDefault(require('../util.js'));
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 | var extendStatics = function(d, b) {
|
29 | extendStatics = Object.setPrototypeOf ||
|
30 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
31 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
32 | return extendStatics(d, b);
|
33 | };
|
34 |
|
35 | function __extends(d, b) {
|
36 | extendStatics(d, b);
|
37 | function __() { this.constructor = d; }
|
38 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
39 | }
|
40 |
|
41 | var Component = (function () {
|
42 | function Component(name, defaultProps, props) {
|
43 | var _this = this;
|
44 | this.template = '';
|
45 | this.id = null;
|
46 | this.eventHandlers = [];
|
47 | this.registeredElements = [];
|
48 | this.name = name;
|
49 | var element = typeof props.element === 'string'
|
50 | ? document.querySelector(props.element) : props.element;
|
51 | var config = {};
|
52 | if (element) {
|
53 | var dataConfig = Util.Selector.attrConfig(element);
|
54 | if (dataConfig) {
|
55 | config = dataConfig;
|
56 | }
|
57 | }
|
58 | this.defaultProps = defaultProps;
|
59 | this.props = Object.assign(defaultProps, config, props, { element: element });
|
60 | this.id = this.uid();
|
61 | this.elementListener = function (event) { return _this.onBeforeElementEvent(event); };
|
62 | this.setEventsHandler();
|
63 | }
|
64 | Component.prototype.setTemplate = function (template) {
|
65 | this.template = template;
|
66 | };
|
67 | Component.prototype.getTemplate = function () {
|
68 | return this.template;
|
69 | };
|
70 | Component.prototype.getElement = function () {
|
71 | return this.getProp('element') || null;
|
72 | };
|
73 | Component.prototype.setElement = function (element) {
|
74 | this.props.element = element;
|
75 | };
|
76 | Component.prototype.getId = function () {
|
77 | return this.id;
|
78 | };
|
79 | Component.prototype.uid = function () {
|
80 | return Math.random().toString(36).substr(2, 10);
|
81 | };
|
82 | Component.prototype.getName = function () {
|
83 | return this.name;
|
84 | };
|
85 | Component.prototype.getProps = function () {
|
86 | return this.props;
|
87 | };
|
88 | Component.prototype.getProp = function (name) {
|
89 | var defaultValue = this.defaultProps[name];
|
90 | return typeof this.props[name] !== 'undefined' ? this.props[name] : defaultValue;
|
91 | };
|
92 | Component.prototype.setProps = function (props) {
|
93 | var componentProps = Object.assign({}, props);
|
94 | this.props = Object.assign(this.props, componentProps);
|
95 | };
|
96 | Component.prototype.setProp = function (name, value) {
|
97 | if (typeof this.props[name] === 'undefined') {
|
98 | throw new Error('Cannot set an invalid prop');
|
99 | }
|
100 | this.props[name] = value;
|
101 | };
|
102 | Component.prototype.registerElements = function (elements) {
|
103 | var _this = this;
|
104 | elements.forEach(function (element) { return _this.registerElement(element); });
|
105 | };
|
106 | Component.prototype.registerElement = function (element) {
|
107 | element.target.addEventListener(element.event, this.elementListener);
|
108 | this.registeredElements.push(element);
|
109 | };
|
110 | Component.prototype.unregisterElements = function () {
|
111 | var _this = this;
|
112 | this.registeredElements.forEach(function (element) {
|
113 | _this.unregisterElement(element);
|
114 | });
|
115 | };
|
116 | Component.prototype.unregisterElement = function (element) {
|
117 | var registeredElementIndex = this.registeredElements
|
118 | .findIndex(function (el) { return el.target === element.target && el.event === element.event; });
|
119 | if (registeredElementIndex > -1) {
|
120 | element.target.removeEventListener(element.event, this.elementListener);
|
121 | this.registeredElements.splice(registeredElementIndex, 1);
|
122 | }
|
123 | else {
|
124 | console.error('Warning! Could not remove element:'
|
125 | + ' ' + (element.target + " with event: " + element.event + "."));
|
126 | }
|
127 | };
|
128 | Component.prototype.triggerEvent = function (eventName, detail, objectEventOnly) {
|
129 | var _this = this;
|
130 | if (detail === void 0) { detail = {}; }
|
131 | if (objectEventOnly === void 0) { objectEventOnly = false; }
|
132 | var eventNameObject = eventName.split('.').reduce(function (acc, current, index) {
|
133 | if (index === 0) {
|
134 | return current;
|
135 | }
|
136 | return acc + current.charAt(0).toUpperCase() + current.slice(1);
|
137 | });
|
138 | var eventNameAlias = "on" + eventNameObject
|
139 | .charAt(0).toUpperCase() + eventNameObject.slice(1);
|
140 | var props = this.getProps();
|
141 | this.eventHandlers.forEach(function (scope) {
|
142 | if (typeof scope[eventNameObject] === 'function') {
|
143 | scope[eventNameObject].apply(_this, [detail]);
|
144 | }
|
145 | if (typeof scope[eventNameAlias] === 'function') {
|
146 | props[eventNameAlias].apply(_this, [detail]);
|
147 | }
|
148 | });
|
149 | if (objectEventOnly) {
|
150 | return;
|
151 | }
|
152 | var element = this.getElement();
|
153 | if (element) {
|
154 | Util.Dispatch.elementEvent(element, eventName, this.name, detail);
|
155 | }
|
156 | else {
|
157 | Util.Dispatch.winDocEvent(eventName, this.name, detail);
|
158 | }
|
159 | };
|
160 | Component.prototype.preventClosable = function () {
|
161 | return false;
|
162 | };
|
163 | Component.prototype.destroy = function () {
|
164 | this.unregisterElements();
|
165 | };
|
166 | Component.prototype.onElementEvent = function (event) {
|
167 | };
|
168 | Component.prototype.setEventsHandler = function () {
|
169 | var props = this.getProps();
|
170 | var scope = Object.keys(props).reduce(function (cur, key) {
|
171 | if (typeof props[key] === 'function') {
|
172 | cur[key] = props[key];
|
173 | }
|
174 | return cur;
|
175 | }, {});
|
176 | if (Object.keys(scope).length > 0) {
|
177 | this.eventHandlers.push(scope);
|
178 | }
|
179 | };
|
180 | Component.prototype.onBeforeElementEvent = function (event) {
|
181 | if (this.preventClosable()) {
|
182 | return;
|
183 | }
|
184 | this.onElementEvent(event);
|
185 | };
|
186 | return Component;
|
187 | }());
|
188 |
|
189 | var Selectbox = (function (_super) {
|
190 | __extends(Selectbox, _super);
|
191 | function Selectbox(props) {
|
192 | var _this = _super.call(this, 'selectbox', {
|
193 | name: null,
|
194 | selectable: true,
|
195 | filterItems: null,
|
196 | multiple: false,
|
197 | tag: false,
|
198 | }, props) || this;
|
199 | if (!_this.getProp('name')) {
|
200 | var hiddenInput = _this.getElement().querySelector('input[type="hidden"]');
|
201 | if (hiddenInput) {
|
202 | _this.setProp('name', hiddenInput.getAttribute('name'));
|
203 | }
|
204 | }
|
205 | _this.filterItemsHandler = function (event) {
|
206 | var target = event.target;
|
207 | if (!target) {
|
208 | return;
|
209 | }
|
210 | var search = target.value;
|
211 | if (search === '') {
|
212 | _this.showItems();
|
213 | return;
|
214 | }
|
215 | _this.getItems().forEach(function (item) {
|
216 | var filterItems = _this.getProp('filterItems');
|
217 | var fn = typeof filterItems === 'function' ? filterItems : _this.filterItems;
|
218 | if (fn(search, item)) {
|
219 | item.element.style.display = 'block';
|
220 | }
|
221 | else {
|
222 | item.element.style.display = 'none';
|
223 | }
|
224 | });
|
225 | };
|
226 | _this.registerElement({ target: _this.getElement(), event: Util.Event.CLICK });
|
227 | _this.searchInputInContainer = _this.getElement()
|
228 | .querySelector('.selectbox-input-container .input-select-one') !== null;
|
229 | var selectedItem = _this.getItemData(_this.getElement().querySelector('[data-selected]'));
|
230 | if (selectedItem) {
|
231 | _this.setSelected(selectedItem.value, selectedItem.text);
|
232 | }
|
233 | return _this;
|
234 | }
|
235 | Selectbox.attachDOM = function () {
|
236 | Util.Observer.subscribe({
|
237 | componentClass: 'selectbox',
|
238 | onAdded: function (element, create) {
|
239 | create(new Selectbox({ element: element }));
|
240 | },
|
241 | onRemoved: function (element, remove) {
|
242 | remove('Selectbox', element);
|
243 | },
|
244 | });
|
245 | };
|
246 | Selectbox.prototype.getSearchInput = function () {
|
247 | return this.getElement().querySelector('.input-select-one');
|
248 | };
|
249 | Selectbox.prototype.filterItems = function (search, item) {
|
250 | if (search === void 0) { search = ''; }
|
251 | return item.value.indexOf(search) > -1 || item.text.indexOf(search) > -1;
|
252 | };
|
253 | Selectbox.prototype.showItems = function () {
|
254 | this.getItems().forEach(function (item) {
|
255 | item.element.style.display = 'block';
|
256 | });
|
257 | };
|
258 | Selectbox.prototype.getItems = function () {
|
259 | var _this = this;
|
260 | var items = Array
|
261 | .from(this.getElement().querySelectorAll('.selectbox-menu-item') || []);
|
262 | return items.map(function (item) {
|
263 | var info = _this.getItemData(item);
|
264 | return { text: info.text, value: info.value, element: item };
|
265 | });
|
266 | };
|
267 | Selectbox.prototype.setSelected = function (value, text) {
|
268 | if (value === void 0) { value = ''; }
|
269 | if (text === void 0) { text = ''; }
|
270 | var selectable = this.getProp('selectable');
|
271 | if (!selectable) {
|
272 | return false;
|
273 | }
|
274 | var element = this.getElement();
|
275 | var multiple = this.getProp('multiple');
|
276 | if (multiple) {
|
277 | this.addItemSelection(value);
|
278 | }
|
279 | else {
|
280 | var itemsSelected = Array
|
281 | .from(element.querySelectorAll('.selectbox-item-selection .item-selected') || []);
|
282 | if (itemsSelected.length === 0) {
|
283 | this.addItemSelection(value);
|
284 | }
|
285 | }
|
286 | var lastSelectedEl = element
|
287 | .querySelector('.selectbox-item-selection .item-selected:last-child');
|
288 | var spanEl = lastSelectedEl.querySelector('[data-value]');
|
289 | if (spanEl) {
|
290 | spanEl.innerHTML = text;
|
291 | }
|
292 | else {
|
293 | lastSelectedEl.innerHTML = text;
|
294 | }
|
295 | var hiddenInputs = Array
|
296 | .from(this.getElement().querySelectorAll('input[type="hidden"]') || []);
|
297 | var lastInput = hiddenInputs.slice(-1).pop();
|
298 | if (lastInput) {
|
299 | lastInput.setAttribute('value', value);
|
300 | }
|
301 | this.updateActiveList();
|
302 | this.setSearchInputWidth();
|
303 | var searchInput = this.getSearchInput();
|
304 | if (value === '') {
|
305 | this.showPlaceholder();
|
306 | }
|
307 | else {
|
308 | this.showPlaceholder(false);
|
309 | }
|
310 | return true;
|
311 | };
|
312 | Selectbox.prototype.getSelected = function () {
|
313 | var hiddenInputs = Array
|
314 | .from(this.getElement().querySelectorAll('input[type="hidden"]') || []);
|
315 | if (!this.getProp('multiple')) {
|
316 | return hiddenInputs.length > 0 ? hiddenInputs[0].value : '';
|
317 | }
|
318 | return hiddenInputs.map(function (input) { return input.value; });
|
319 | };
|
320 | Selectbox.prototype.setSearchInputWidth = function () {
|
321 | if (!this.searchInputInContainer) {
|
322 | return;
|
323 | }
|
324 | var selectbox = this.getElement();
|
325 | var selection = selectbox.querySelector('.selectbox-item-selection');
|
326 | var availableSpace = selectbox.offsetWidth - selection.offsetWidth;
|
327 | var searchInput = this.getSearchInput();
|
328 | if (!searchInput) {
|
329 | throw new Error('Selectbox: search input is not defined');
|
330 | }
|
331 | var selectedItemWidth = Array
|
332 | .from(selectbox.querySelectorAll('.item-selected') || [])
|
333 | .reduce(function (total, el) { return (total + el.offsetWidth); }, 0);
|
334 | if (availableSpace > 0) {
|
335 | searchInput.style.width = "calc(100% - " + (selectedItemWidth + 15) + "px)";
|
336 | }
|
337 | searchInput.style.left = selectedItemWidth + "px";
|
338 | };
|
339 | Selectbox.prototype.getItemData = function (item) {
|
340 | if (item === void 0) { item = null; }
|
341 | var text = '';
|
342 | var value = '';
|
343 | if (item) {
|
344 | text = item.getAttribute('data-text') || item.innerHTML;
|
345 | var selectedTextNode = item.querySelector('.text');
|
346 | if (selectedTextNode) {
|
347 | text = selectedTextNode.innerHTML;
|
348 | }
|
349 | value = item.getAttribute('data-value') || '';
|
350 | }
|
351 | return { text: text, value: value };
|
352 | };
|
353 | Selectbox.prototype.onElementEvent = function (event) {
|
354 | var target = event.target;
|
355 | if (event.type === Util.Event.START) {
|
356 | var selectbox = Util.Selector.closest(target, '.selectbox');
|
357 | if (!selectbox || selectbox !== this.getElement()) {
|
358 | this.hide();
|
359 | }
|
360 | }
|
361 | else if (event.type === Util.Event.CLICK) {
|
362 | var dataToggleAttr = target.getAttribute('data-toggle');
|
363 | if (dataToggleAttr && dataToggleAttr === 'selectbox') {
|
364 | this.toggle();
|
365 | return;
|
366 | }
|
367 | var dismissButton = Util.Selector
|
368 | .closest(target, '[data-dismiss="selectbox"]');
|
369 | if (dismissButton) {
|
370 | this.hide();
|
371 | return;
|
372 | }
|
373 | var selectedTag = Util.Selector.closest(target, '.icon-close');
|
374 | if (selectedTag) {
|
375 | this.removeSelected(selectedTag.parentNode);
|
376 | return;
|
377 | }
|
378 | var item = Util.Selector.closest(target, '.selectbox-menu-item');
|
379 | if (item && !item.classList.contains('disabled')) {
|
380 | var itemInfo = this.getItemData(item);
|
381 | if (this.getSelected() !== itemInfo.value) {
|
382 | this.setSelected(itemInfo.value, itemInfo.text);
|
383 | var selectInput = this.getElement().querySelector('.input-select-one').value = '';
|
384 | var detail = { item: item, text: itemInfo.text, value: itemInfo.value };
|
385 | this.triggerEvent(Util.Event.ITEM_SELECTED, detail);
|
386 | }
|
387 | this.hide();
|
388 | return;
|
389 | }
|
390 | var selectboxMenu = Util.Selector.closest(target, '.selectbox-menu');
|
391 | if (selectboxMenu) {
|
392 | return;
|
393 | }
|
394 | this.toggle();
|
395 | }
|
396 | else if (event.type === 'keyup' && event.keyCode === 8) {
|
397 | var inputTarget = event.target;
|
398 | if (inputTarget.value !== '') {
|
399 | return;
|
400 | }
|
401 | if (!this.searchInputInContainer) {
|
402 | return;
|
403 | }
|
404 | this.removeLastSelected();
|
405 | }
|
406 | };
|
407 | Selectbox.prototype.addItemSelection = function (value) {
|
408 | var itemSelectedEl = document.createElement('div');
|
409 | itemSelectedEl.classList.add('item-selected');
|
410 | if (this.getProp('tag')) {
|
411 | itemSelectedEl.classList.add('tag');
|
412 | var spanEl = document.createElement('span');
|
413 | spanEl.setAttribute('data-value', 'true');
|
414 | itemSelectedEl.appendChild(spanEl);
|
415 | var closeEl = document.createElement('button');
|
416 | closeEl.setAttribute('type', 'button');
|
417 | closeEl.classList.add('icon-close');
|
418 | var iconEl = document.createElement('span');
|
419 | iconEl.setAttribute('class', 'icon');
|
420 | iconEl.setAttribute('aria-hidden', 'true');
|
421 | closeEl.appendChild(iconEl);
|
422 | itemSelectedEl.appendChild(closeEl);
|
423 | }
|
424 | var element = this.getElement();
|
425 | element.querySelector('.selectbox-item-selection').appendChild(itemSelectedEl);
|
426 | var selectbox = this.getElement();
|
427 | var hiddenInputs = Array.from(selectbox.querySelectorAll('input[type="hidden"]') || []);
|
428 | var lastHiddenInput = hiddenInputs.length > 0 ? hiddenInputs[hiddenInputs.length - 1] : null;
|
429 | if ((!this.getProp('multiple') && !lastHiddenInput) || this.getProp('multiple')) {
|
430 | var hiddenInput = document.createElement('input');
|
431 | hiddenInput.setAttribute('type', 'hidden');
|
432 | var name_1 = this.getProp('name');
|
433 | hiddenInput.setAttribute('name', this.getProp('multiple') ? name_1 + "[]" : name_1);
|
434 | hiddenInput.setAttribute('value', value);
|
435 | selectbox.insertBefore(hiddenInput, lastHiddenInput ? lastHiddenInput.nextSibling : selectbox.firstChild);
|
436 | }
|
437 | };
|
438 | Selectbox.prototype.removeLastSelected = function () {
|
439 | var selectbox = this.getElement();
|
440 | var selectedItems = Array
|
441 | .from(selectbox.querySelectorAll('.selectbox-item-selection .item-selected') || []);
|
442 | if (selectedItems.length === 0) {
|
443 | return;
|
444 | }
|
445 | var lastSelectedItem = selectedItems[selectedItems.length - 1];
|
446 | this.removeSelected(lastSelectedItem);
|
447 | };
|
448 | Selectbox.prototype.removeSelected = function (selectedItem) {
|
449 | var selectbox = this.getElement();
|
450 | var selectedItems = Array
|
451 | .from(selectbox.querySelectorAll('.selectbox-item-selection .item-selected') || []);
|
452 | if (selectedItems.length === 0) {
|
453 | return;
|
454 | }
|
455 | selectbox.querySelector('.selectbox-item-selection').removeChild(selectedItem);
|
456 | if (this.getProp('multiple')) {
|
457 | var values = this.getSelected();
|
458 | var hiddenInput = selectbox
|
459 | .querySelector("input[type=\"hidden\"][value=\"" + values.slice(-1).pop() + "\"]");
|
460 | this.getElement().removeChild(hiddenInput);
|
461 | }
|
462 | else {
|
463 | var hiddenInput = selectbox.querySelector('input[type="hidden"]');
|
464 | if (!this.getProp('multiple') && hiddenInput) {
|
465 | hiddenInput.setAttribute('value', '');
|
466 | }
|
467 | }
|
468 | this.updateActiveList();
|
469 | this.setSearchInputWidth();
|
470 | if (selectedItems.length === 1) {
|
471 | this.showPlaceholder();
|
472 | }
|
473 | };
|
474 | Selectbox.prototype.showPlaceholder = function (show) {
|
475 | if (show === void 0) { show = true; }
|
476 | var searchInput = this.getSearchInput();
|
477 | if (!searchInput) {
|
478 | return;
|
479 | }
|
480 | if (show && searchInput.classList.contains('hide-placeholder')) {
|
481 | searchInput.classList.remove('hide-placeholder');
|
482 | }
|
483 | else if (!show && !searchInput.classList.contains('hide-placeholder')) {
|
484 | searchInput.classList.add('hide-placeholder');
|
485 | }
|
486 | };
|
487 | Selectbox.prototype.updateActiveList = function () {
|
488 | var _this = this;
|
489 | var selected = this.getSelected();
|
490 | var selectedItems = Array.isArray(selected) ? selected : [selected];
|
491 | var items = Array
|
492 | .from(this.getElement().querySelectorAll('.selectbox-menu-item') || []);
|
493 | items.forEach(function (item) {
|
494 | var data = _this.getItemData(item);
|
495 | if (selectedItems.indexOf(data.value) > -1) {
|
496 | if (!item.classList.contains('selected')) {
|
497 | item.classList.add('selected');
|
498 | }
|
499 | }
|
500 | else {
|
501 | if (item.classList.contains('selected')) {
|
502 | item.classList.remove('selected');
|
503 | }
|
504 | }
|
505 | });
|
506 | };
|
507 | Selectbox.prototype.toggle = function () {
|
508 | if (this.getElement().classList.contains('active')) {
|
509 | return this.hide();
|
510 | }
|
511 | return this.show();
|
512 | };
|
513 | Selectbox.prototype.show = function () {
|
514 | var element = this.getElement();
|
515 | if (element.classList.contains('active')) {
|
516 | return false;
|
517 | }
|
518 | element.classList.add('active');
|
519 | var selectboxMenu = element.querySelector('.selectbox-menu');
|
520 | var selectInput = this.getSearchInput();
|
521 | selectboxMenu.scrollTop = 0;
|
522 | this.triggerEvent(Util.Event.SHOW);
|
523 | this.triggerEvent(Util.Event.SHOWN);
|
524 | this.registerElement({ target: document.body, event: Util.Event.START });
|
525 | if (selectInput) {
|
526 | this.registerElement({ target: selectInput, event: 'keyup' });
|
527 | selectInput.addEventListener('keyup', this.filterItemsHandler);
|
528 | selectInput.focus();
|
529 | }
|
530 | var closeButton = element.querySelector('[data-dismiss="selectbox"]');
|
531 | if (closeButton) {
|
532 | this.registerElement({ target: closeButton, event: Util.Event.CLICK });
|
533 | }
|
534 | return true;
|
535 | };
|
536 | Selectbox.prototype.hide = function () {
|
537 | var element = this.getElement();
|
538 | if (!element.classList.contains('active')) {
|
539 | return false;
|
540 | }
|
541 | element.classList.remove('active');
|
542 | this.triggerEvent(Util.Event.HIDE);
|
543 | this.triggerEvent(Util.Event.HIDDEN);
|
544 | this.unregisterElement({ target: document.body, event: Util.Event.START });
|
545 | var closeButton = element.querySelector('[data-dismiss="selectbox"]');
|
546 | if (closeButton) {
|
547 | this.unregisterElement({ target: closeButton, event: Util.Event.CLICK });
|
548 | }
|
549 | var selectInput = this.getSearchInput();
|
550 | if (selectInput) {
|
551 | selectInput.removeEventListener('keyup', this.filterItemsHandler);
|
552 | selectInput.value = '';
|
553 | this.unregisterElement({ target: selectInput, event: 'keyup' });
|
554 | }
|
555 | this.showItems();
|
556 | return true;
|
557 | };
|
558 | return Selectbox;
|
559 | }(Component));
|
560 | Selectbox.attachDOM();
|
561 |
|
562 | module.exports = Selectbox;
|
563 |
|