diff --git a/client/client/src/basic-data/basic-data.html b/client/client/src/basic-data/basic-data.html index 02f71c7921..092e7d946d 100644 --- a/client/client/src/basic-data/basic-data.html +++ b/client/client/src/basic-data/basic-data.html @@ -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 diff --git a/client/core/src/autocomplete-v2/autocomplete.html b/client/core/src/autocomplete-v2/autocomplete.html index d84ad2411e..976deb095b 100644 --- a/client/core/src/autocomplete-v2/autocomplete.html +++ b/client/core/src/autocomplete-v2/autocomplete.html @@ -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> \ 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 8454418b72..d5e2d7e713 100644 --- a/client/core/src/autocomplete-v2/autocomplete.js +++ b/client/core/src/autocomplete-v2/autocomplete.js @@ -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' diff --git a/client/core/src/autocomplete-v2/style.scss b/client/core/src/autocomplete-v2/style.scss index 2b8220ede7..1472dbcf36 100644 --- a/client/core/src/autocomplete-v2/style.scss +++ b/client/core/src/autocomplete-v2/style.scss @@ -37,4 +37,7 @@ vn-autocomplete { vn-drop-down{ margin-top: 47px; } + vn-drop-down .dropdown-body .filter vn-icon { + margin-left: -26px; + } } \ 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 1b862cfba7..c65feac282 100644 --- a/client/core/src/drop-down/drop-down.html +++ b/client/core/src/drop-down/drop-down.html @@ -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> diff --git a/client/core/src/drop-down/drop-down.js b/client/core/src/drop-down/drop-down.js index b171394c30..d8de9c0144 100644 --- a/client/core/src/drop-down/drop-down.js +++ b/client/core/src/drop-down/drop-down.js @@ -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' diff --git a/client/core/src/drop-down/style.scss b/client/core/src/drop-down/style.scss index 01d565cc01..f66d23ea6f 100644 --- a/client/core/src/drop-down/style.scss +++ b/client/core/src/drop-down/style.scss @@ -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;