autocomplete recatoring 80%
This commit is contained in:
parent
f9b3657440
commit
6651f70e07
|
@ -1,16 +1,13 @@
|
|||
<vn-vertical>
|
||||
<vn-one>
|
||||
<vn-textfield label="{{$ctrl.label}}" model="$ctrl.displayValue"></vn-textfield>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<vn-drop-down
|
||||
items="$ctrl.items"
|
||||
show="$ctrl.showDropDown"
|
||||
selected="$ctrl.field"
|
||||
filter="true"
|
||||
load-more="$ctrl.getItems()"
|
||||
show-load-more="$ctrl.maxRow"
|
||||
filter-action="$ctrl.findItems(search)"
|
||||
></vn-drop-down>
|
||||
</vn-one>
|
||||
<vn-vertical ng-click="$ctrl.showDropDown = true">
|
||||
<vn-textfield vn-one label="{{$ctrl.label}}" model="$ctrl.displayValue"></vn-textfield>
|
||||
<vn-drop-down vn-one
|
||||
items="$ctrl.items"
|
||||
show="$ctrl.showDropDown"
|
||||
selected="$ctrl.field"
|
||||
search="$ctrl.displayValue"
|
||||
load-more="$ctrl.getItems()"
|
||||
show-load-more="$ctrl.maxRow"
|
||||
filter-action="$ctrl.findItems(search)"
|
||||
item-width="$ctrl.width"
|
||||
></vn-drop-down>
|
||||
</vn-vertical>
|
|
@ -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');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,4 +34,7 @@ vn-autocomplete {
|
|||
.material-icons {
|
||||
font-size: 18px;
|
||||
}
|
||||
vn-drop-down{
|
||||
margin-top: 50px;
|
||||
}
|
||||
}
|
|
@ -1,18 +1,13 @@
|
|||
<vn-vertical class="dropdown-body" ng-show="$ctrl.show">
|
||||
<vn-one ng-show="$ctrl.filter" class="filter">
|
||||
<vn-horizontal>
|
||||
<div ng-if="$ctrl.filterAction">
|
||||
<input vn-one placeholder="{{'Search' | translate}}" type="text" ng-model="$ctrl.search" ng-change="$ctrl.onFilterRest()"/>
|
||||
</div>
|
||||
<div ng-if="!$ctrl.filterAction">
|
||||
<input vn-one placeholder="{{'Search' | translate}}" type="text" ng-model="$ctrl.search" ng-change="$ctrl.filterItems()"/>
|
||||
</div>
|
||||
<input vn-one placeholder="{{'Search' | translate}}" type="text" ng-model="$ctrl.search"/>
|
||||
<vn-icon vn-none icon="clear" ng-click="$ctrl.clearSearch()"></vn-icon>
|
||||
</vn-horizontal>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<ul class="dropdown">
|
||||
<li ng-repeat="item in $ctrl.itemsFiltered" ng-click="$ctrl.selected = item">{{::item.name}}</li>
|
||||
<li ng-repeat="item in $ctrl.itemsFiltered track by $index" ng-click="$ctrl.selected = item" ng-class="{'active': $index === $ctrl.activeOption}" ng-mouseover="$ctrl.activeOption = $index">{{::item.name}}</li>
|
||||
<li ng-if="$ctrl.showLoadMore" class="dropdown__loadMore" ng-click="$ctrl.loadMore()" translate="Load More"></li>
|
||||
</ul>
|
||||
</vn-one>
|
||||
|
|
|
@ -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: '<?',
|
||||
top: '<?'
|
||||
showLoadMore: '=?',
|
||||
top: '<?',
|
||||
itemWidth: '<?',
|
||||
parent: '<?'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -39,7 +39,7 @@ vn-drop-down {
|
|||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
li:hover{
|
||||
li.active{
|
||||
background-color: #3D3A3B;
|
||||
color: white;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
show="$ctrl.showDropDown"
|
||||
selected="$ctrl.selected"
|
||||
filter="true"
|
||||
parent="$ctrl.element"
|
||||
></vn-drop-down>
|
||||
</div>
|
||||
<div ng-if="$ctrl.findMore">
|
||||
|
@ -17,6 +18,7 @@
|
|||
load-more="$ctrl.getItems()"
|
||||
show-load-more="$ctrl.maxRow"
|
||||
filter-action="$ctrl.findItems(search)"
|
||||
parent="$ctrl.element"
|
||||
></vn-drop-down>
|
||||
</div>
|
||||
</div>
|
|
@ -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'];
|
||||
|
|
Loading…
Reference in New Issue