From 6651f70e075bf923ed994cc182eba5b9df4d2759 Mon Sep 17 00:00:00 2001 From: Dani Herrero Date: Thu, 14 Sep 2017 13:40:55 +0200 Subject: [PATCH] autocomplete recatoring 80% --- .../src/autocomplete-v2/autocomplete.html | 27 +++-- .../core/src/autocomplete-v2/autocomplete.js | 24 +++++ client/core/src/autocomplete-v2/style.scss | 3 + client/core/src/drop-down/drop-down.html | 9 +- client/core/src/drop-down/drop-down.js | 98 ++++++++++++++++--- client/core/src/drop-down/style.scss | 2 +- client/core/src/icon-menu/icon-menu.html | 2 + client/core/src/icon-menu/icon-menu.js | 15 +++ 8 files changed, 141 insertions(+), 39 deletions(-) diff --git a/client/core/src/autocomplete-v2/autocomplete.html b/client/core/src/autocomplete-v2/autocomplete.html index f322a37ce..7daac5342 100644 --- a/client/core/src/autocomplete-v2/autocomplete.html +++ b/client/core/src/autocomplete-v2/autocomplete.html @@ -1,16 +1,13 @@ - - - - - - - + + + \ No newline at end of file diff --git a/client/core/src/autocomplete-v2/autocomplete.js b/client/core/src/autocomplete-v2/autocomplete.js index 9f86e433d..ecd72d6c2 100644 --- a/client/core/src/autocomplete-v2/autocomplete.js +++ b/client/core/src/autocomplete-v2/autocomplete.js @@ -16,6 +16,8 @@ class Autocomplete { this.maxRow = 10; this.showField = this.showField || 'name'; this.items = this.data || null; + + this.input = $element[0].querySelector('input'); } get showDropDown() { @@ -50,6 +52,7 @@ class Autocomplete { return this.items ? this.items : []; if (search && !this.finding) { + this.maxRow = false; let filter = {where: {name: {regexp: search}}}; let json = JSON.stringify(filter); this.finding = true; @@ -63,6 +66,7 @@ class Autocomplete { } ); } else if (!search && !this.finding) { + this.maxRow = 10; this.items = []; this.getItems(); } @@ -112,6 +116,26 @@ class Autocomplete { this.showDropDown = false; }); }); + this.$element.bind('focusin', e => { + this.$timeout(() => { + this.showDropDown = true; + }); + }); + this.$element.bind('focusout', e => { + this.$timeout(() => { + this.showDropDown = false; + }); + }); + + let rectangle = this.$element[0].getBoundingClientRect(); + this.width = Math.round(rectangle.width) - 15; + } + + $onDestroy() { + this.$element.unbind('mouseover'); + this.$element.unbind('mouseout'); + this.$element.unbind('focusin'); + this.$element.unbind('focusout'); } } diff --git a/client/core/src/autocomplete-v2/style.scss b/client/core/src/autocomplete-v2/style.scss index 5c4dd1a4b..3ea0428c6 100644 --- a/client/core/src/autocomplete-v2/style.scss +++ b/client/core/src/autocomplete-v2/style.scss @@ -34,4 +34,7 @@ vn-autocomplete { .material-icons { font-size: 18px; } + vn-drop-down{ + margin-top: 50px; + } } \ No newline at end of file diff --git a/client/core/src/drop-down/drop-down.html b/client/core/src/drop-down/drop-down.html index dad08a84f..87adbed17 100644 --- a/client/core/src/drop-down/drop-down.html +++ b/client/core/src/drop-down/drop-down.html @@ -1,18 +1,13 @@ -
- -
-
- -
+
diff --git a/client/core/src/drop-down/drop-down.js b/client/core/src/drop-down/drop-down.js index ece781507..7fce991b7 100644 --- a/client/core/src/drop-down/drop-down.js +++ b/client/core/src/drop-down/drop-down.js @@ -2,12 +2,41 @@ import {module} from '../module'; import './style.scss'; export default class DropDown { - constructor($element, $filter) { + constructor($element, $filter, $timeout) { this.$element = $element; this.$filter = $filter; - this.search = ''; - this.itemsFiltered = []; + this.$timeout = $timeout; + this.parent = this.parent || $element[0].parentNode; + this._search = null; + this.itemsFiltered = []; + this._activeOption = -1; + } + + get search() { + return this._search; + } + set search(value) { + let val = (value === undefined && value === '') ? null : value; + this._search = val; + + if (this.filterAction) + this.onFilterRest(); + else + this.filterItems(); + } + get activeOption() { + return this._activeOption; + } + set activeOption(value) { + if (value < 0) { + value = 0; + } else if (value >= this.items.length) { + value = this.items.length - 1; + } + this.$timeout(() => { + this._activeOption = value; + }); } filterItems() { @@ -15,32 +44,66 @@ export default class DropDown { } onFilterRest() { - this.showLoadMore = false; - if (this.filterAction) { - this.filterAction({search: this.search}); - } + this.filterAction({search: this.search}); } $onChanges(changesObj) { if (changesObj.show && changesObj.top && changesObj.top.currentValue) { this.$element.css('top', changesObj.top.currentValue + 'px'); } + if (changesObj.show && changesObj.itemWidth && changesObj.itemWidth.currentValue) { + this.$element.css('width', changesObj.itemWidth.currentValue + 'px'); + } if (changesObj.items) { this.filterItems(); } } clearSearch() { - this.search = ''; - this.showLoadMore = this.loadMore != null; - if (this.filterAction) { - this.filterAction({search: this.search}); - } else { - this.filterItems(); + this.search = null; + } + + selectOption() { + if (this.activeOption >= 0 && this.items[this.activeOption]) { + this.selected = this.items[this.activeOption]; + this.clearSearch(); } } + + onKeydown(event) { + if (this.show) { + switch (event.keyCode) { + case 13: // Enter + this.$timeout(() => { + this.selectOption(); + }); + event.preventDefault(); + break; + case 27: // Escape + this.clearSearch(); + break; + case 38: // Arrow up + this.activeOption--; + break; + case 40: // Arrow down + this.activeOption++; + break; + default: + return; + } + } + } + + $onInit() { + if (this.parent) + this.parent.addEventListener('keydown', e => this.onKeydown(e)); + } + $onDestroy() { + if (this.parent) + this.parent.removeEventListener('keydown', e => this.onKeydown(e)); + } } -DropDown.$inject = ['$element', '$filter']; +DropDown.$inject = ['$element', '$filter', '$timeout']; module.component('vnDropDown', { template: require('./drop-down.html'), @@ -50,9 +113,12 @@ module.component('vnDropDown', { show: '<', filter: '@?', selected: '=', + search: '=?', loadMore: '&?', filterAction: '&?', - showLoadMore: '
@@ -17,6 +18,7 @@ load-more="$ctrl.getItems()" show-load-more="$ctrl.maxRow" filter-action="$ctrl.findItems(search)" + parent="$ctrl.element" >
\ No newline at end of file diff --git a/client/core/src/icon-menu/icon-menu.js b/client/core/src/icon-menu/icon-menu.js index a81d3f512..4ac9d2302 100644 --- a/client/core/src/icon-menu/icon-menu.js +++ b/client/core/src/icon-menu/icon-menu.js @@ -9,6 +9,7 @@ export default class IconMenu { this._showDropDown = false; this.finding = false; this.findMore = false; + this.element = $element[0]; } get showDropDown() { return this._showDropDown; @@ -34,6 +35,7 @@ export default class IconMenu { } ); } else if (!search && !this.finding) { + this.maxRow = 10; this.items = []; this.getItems(); } @@ -83,10 +85,23 @@ export default class IconMenu { this.showDropDown = false; }); }); + this.$element.bind('focusin', e => { + this.$timeout(() => { + this.showDropDown = true; + }); + }); + this.$element.bind('focusout', e => { + this.$timeout(() => { + this.showDropDown = false; + }); + }); } + $onDestroy() { this.$element.unbind('mouseover'); this.$element.unbind('mouseout'); + this.$element.unbind('focusin'); + this.$element.unbind('focusout'); } } IconMenu.$inject = ['$element', '$http', '$timeout'];