autocomplete con seleccion multiple

This commit is contained in:
Dani Herrero 2017-09-20 13:52:53 +02:00
parent d81d36217a
commit 1dad2147ca
7 changed files with 91 additions and 15 deletions

View File

@ -30,7 +30,7 @@
select-fields="surname"
label="Salesperson">
<tpl-item>
{{::$parent.$parent.item.name}} {{::$parent.$parent.item.surname}}
{{$parent.$parent.item.name}} {{$parent.$parent.item.surname}}
</tpl-item>
</vn-autocomplete>
<vn-autocomplete vn-one

View File

@ -4,10 +4,11 @@
items="$ctrl.items"
show="$ctrl.showDropDown"
selected="$ctrl.field"
search="$ctrl.displayValue"
filter="true"
load-more="$ctrl.getItems()"
show-load-more="$ctrl.maxRow"
filter-action="$ctrl.findItems(search)"
item-width="$ctrl.width"
multiple="$ctrl.multiple"
><vn-item ng-transclude="tplItem">{{$parent.item.name}}</vn-item></vn-drop-down>
</vn-vertical>

View File

@ -20,6 +20,8 @@ class Autocomplete extends Component {
this.showField = this.showField || 'name';
this.valueField = this.valueField || 'id';
this.items = this.data || [];
this.displayValueMultiCheck = [];
this._multiField = [];
}
get showDropDown() {
@ -38,26 +40,50 @@ class Autocomplete extends Component {
}
set displayValue(value) {
this._value = (value === undefined || value === '') ? null : value;
let val = (value === undefined || value === '') ? null : value;
if (this.multiple && val) {
let index = this.displayValueMultiCheck.indexOf(val);
if (index === -1)
this.displayValueMultiCheck.push(val);
else
this.displayValueMultiCheck.splice(index, 1);
this._value = this.displayValueMultiCheck.join(', ');
} else {
this._value = val;
}
if (value === null) {
this.field = null;
if (this.multiple && this.items.length) {
this.displayValueMultiCheck = [];
this.items.map(item => {
item.checked = false;
return item;
});
}
}
}
get field() {
return this._field;
return this.multiple ? this._multiField : this._field;
}
set field(value) {
this.finding = true;
if (value && value.hasOwnProperty(this.valueField))
if (value && value.hasOwnProperty(this.valueField)) {
this._field = value[this.valueField];
else
this.setMultiField(value[this.valueField]);
} else {
this.setValue(value);
}
if (value && value.hasOwnProperty(this.showField))
this.displayValue = value[this.showField];
this.finding = false;
if (this.onChange)
this.onChange({item: this._field});
}
set initialData(value) {
@ -66,6 +92,22 @@ class Autocomplete extends Component {
}
}
setMultiField(val) {
if (val && typeof val === 'object' && val[this.valueField]) {
val = val[this.valueField];
}
if (val === null) {
this._multiField = [];
} else {
let index = this._multiField.indexOf(val);
if (index === -1) {
this._multiField.push(val);
} else {
this._multiField.splice(index, 1);
}
}
}
setValue(value) {
if (value) {
let data = this.items;
@ -80,6 +122,7 @@ class Autocomplete extends Component {
this.requestItem(value);
} else {
this._field = null;
this.setMultiField(null);
this.displayValue = '';
}
}
@ -112,6 +155,7 @@ class Autocomplete extends Component {
showItem(item) {
this.displayValue = item ? item[this.showField] : '';
this.field = item;
this.setMultiField(item);
}
getRequestFields() {
@ -137,7 +181,15 @@ class Autocomplete extends Component {
this.finding = true;
this.$http.get(`${this.url}?filter=${json}`).then(
json => {
this.items = json.data;
this.items = [];
json.data.forEach(
el => {
if (this.multiple) {
el.checked = this.field.indexOf(el[this.valueField]) !== -1;
}
this.items.push(el);
}
);
this.finding = false;
},
() => {
@ -168,6 +220,9 @@ class Autocomplete extends Component {
if (json.data.length)
json.data.forEach(
el => {
if (this.multiple) {
el.checked = this.field.indexOf(el[this.valueField]) !== -1;
}
this.items.push(el);
}
);
@ -209,7 +264,6 @@ class Autocomplete extends Component {
let rectangle = this.$element[0].getBoundingClientRect();
this.width = Math.round(rectangle.width) - 10;
}
$onDestroy() {
@ -237,7 +291,8 @@ module.component('vnAutocomplete', {
itemAs: '@?',
field: '=',
label: '@',
itemTemplate: '@?'
itemTemplate: '@?',
multiple: '@?'
},
transclude: {
tplItem: '?tplItem'

View File

@ -37,4 +37,7 @@ vn-autocomplete {
vn-drop-down{
margin-top: 47px;
}
vn-drop-down .dropdown-body .filter vn-icon {
margin-left: -26px;
}
}

View File

@ -1,4 +1,4 @@
<vn-vertical class="dropdown-body" ng-show="$ctrl.show && $ctrl.itemsFiltered.length > 1">
<vn-vertical class="dropdown-body" ng-show="$ctrl.show">
<vn-one ng-show="$ctrl.filter" class="filter">
<vn-horizontal>
<input vn-one placeholder="{{'Search' | translate}}" type="text" ng-model="$ctrl.search"/>
@ -7,13 +7,14 @@
</vn-one>
<vn-one>
<ul class="dropdown">
<li
<li tabIndex="-1"
ng-repeat="item in $ctrl.itemsFiltered track by $index"
ng-click="$ctrl.selected = item; $ctrl.show = false"
ng-class="{'active': $index === $ctrl.activeOption}"
ng-click="$ctrl.selectItem(item)"
ng-class="{'active': $index === $ctrl.activeOption, 'checked': item.checked}"
ng-mouseover="$ctrl.activeOption = $index"
>
<div ng-transclude="vnItem">{{::item.name}}</div>
<input type="checkbox" ng-checked="item.checked" ng-if="$ctrl.multiple">
<div ng-transclude="vnItem">{{item.name}}</div>
</li>
<li ng-if="$ctrl.showLoadMore" class="dropdown__loadMore" tabIndex="-1" ng-class="{'active': $ctrl.itemsFiltered.length === $ctrl.activeOption}" ng-click="$ctrl.loadMore();$ctrl.show = true;" translate="Load More"></li>
</ul>

View File

@ -110,6 +110,16 @@ export default class DropDown {
}
}
selectItem(item) {
this.selected = item;
if (this.multiple) {
item.checked = !item.checked;
this.show = true;
} else {
this.show = false;
}
}
$onInit() {
if (this.parent)
this.parent.addEventListener('keydown', e => this.onKeydown(e));
@ -135,7 +145,8 @@ module.component('vnDropDown', {
showLoadMore: '=?',
top: '<?',
itemWidth: '<?',
parent: '<?'
parent: '<?',
multiple: '<?'
},
transclude: {
vnItem: '?vnItem'

View File

@ -30,6 +30,7 @@ vn-drop-down {
max-height: 400px;
overflow-y: auto;
li {
outline: none;
list-style-type: none;
padding: 5px 10px;
cursor: pointer;
@ -38,6 +39,10 @@ vn-drop-down {
color: rgb(255,171,64);
font-weight: 700;
}
input[type=checkbox]{
float: left;
margin: 5px 5px 0 0;
}
}
li.active{
background-color: #3D3A3B;