transclude funcionando

This commit is contained in:
Dani Herrero 2017-09-20 11:50:53 +02:00
parent e525f1da30
commit d81d36217a
7 changed files with 139 additions and 28 deletions

View File

@ -22,7 +22,7 @@
<vn-horizontal>
<vn-textfield vn-one label="Email" field="$ctrl.client.email"></vn-textfield>
<vn-autocomplete vn-one
initial-value="$ctrl.client.salesPerson"
initial-data="$ctrl.client.salesPerson"
field="$ctrl.client.salesPersonFk"
url="/client/api/Employees"
show-field="name"
@ -30,11 +30,11 @@
select-fields="surname"
label="Salesperson">
<tpl-item>
{{::i.name}} {{::i.surname}}
{{::$parent.$parent.item.name}} {{::$parent.$parent.item.surname}}
</tpl-item>
</vn-autocomplete>
<vn-autocomplete vn-one
initial-value="$ctrl.client.contactChannel"
initial-data="$ctrl.client.contactChannel"
field="$ctrl.client.contactChannelFk"
url="/client/api/ContactChannels"
label="Channel">

View File

@ -20,7 +20,7 @@
<vn-horizontal>
<vn-textfield vn-one label="Código postal" field="$ctrl.client.postcode"></vn-textfield>
<vn-autocomplete vn-one
initial-value="$ctrl.client.province"
initial-data="$ctrl.client.province"
field="$ctrl.client.provinceFk"
url="/client/api/Provinces"
show-field="name"
@ -28,7 +28,7 @@
label="Provincia">
</vn-autocomplete>
<vn-autocomplete vn-one
initial-value="$ctrl.client.country"
initial-data="$ctrl.client.country"
field="$ctrl.client.countryFk"
url="/client/api/Countries"
show-field="name"

View File

@ -9,5 +9,5 @@
show-load-more="$ctrl.maxRow"
filter-action="$ctrl.findItems(search)"
item-width="$ctrl.width"
></vn-drop-down>
><vn-item ng-transclude="tplItem">{{$parent.item.name}}</vn-item></vn-drop-down>
</vn-vertical>

View File

@ -1,8 +1,10 @@
import {module} from '../module';
import Component from '../lib/component';
import './style.scss';
class Autocomplete {
class Autocomplete extends Component {
constructor($element, $scope, $http, $timeout) {
super($element);
this.$element = $element;
this.$scope = $scope;
this.$http = $http;
@ -13,17 +15,21 @@ class Autocomplete {
this.findMore = false;
this._value = null;
this._field = null;
this._preLoad = false;
this.maxRow = 10;
this.showField = this.showField || 'name';
this.items = this.data || null;
this.input = $element[0].querySelector('input');
this.valueField = this.valueField || 'id';
this.items = this.data || [];
}
get showDropDown() {
return this._showDropDown;
}
set showDropDown(value) {
if (value && this.url && !this._preLoad) {
this._preLoad = true;
this.getItems();
}
this._showDropDown = value;
}
@ -42,9 +48,82 @@ class Autocomplete {
return this._field;
}
set field(value) {
this._field = value;
this.finding = true;
if (value && value.hasOwnProperty(this.valueField))
this._field = value[this.valueField];
else
this.setValue(value);
if (value && value.hasOwnProperty(this.showField))
this.displayValue = value[this.showField];
this.finding = false;
}
set initialData(value) {
if (value) {
this.field = value;
}
}
setValue(value) {
if (value) {
let data = this.items;
if (data && data.length)
for (let i = 0; i < data.length; i++)
if (data[i][this.valueField] === value) {
this.showItem(data[i]);
return;
}
this.requestItem(value);
} else {
this._field = null;
this.displayValue = '';
}
}
requestItem(value) {
if (!value) return;
let where = {};
where[this.valueField] = value;
let filter = {
fields: this.getRequestFields(),
where: where
};
let json = JSON.stringify(filter);
this.$http.get(`${this.url}?filter=${json}`).then(
json => this.onItemRequest(json.data),
json => this.onItemRequest(null)
);
}
onItemRequest(data) {
if (data && data.length > 0)
this.showItem(data[0]);
else
this.showItem(null);
}
showItem(item) {
this.displayValue = item ? item[this.showField] : '';
this.field = item;
}
getRequestFields() {
let fields = {};
fields[this.valueField] = true;
fields[this.showField] = true;
if (this._selectFields)
for (let field of this._selectFields)
fields[field] = true;
return fields;
}
findItems(search) {
@ -98,37 +177,39 @@ class Autocomplete {
);
}
$onInit() {
if (!this.items && this.url) {
this.items = [];
this.getItems();
}
this.findMore = this.url && this.maxRow;
this.mouseFocus = false;
this.focused = false;
this.$element.bind('mouseover', e => {
this.$timeout(() => {
this.showDropDown = true;
this.mouseFocus = true;
this.showDropDown = this.focused;
});
});
this.$element.bind('mouseout', () => {
this.$timeout(() => {
this.showDropDown = false;
this.mouseFocus = false;
this.showDropDown = this.focused;
});
});
this.$element.bind('focusin', e => {
this.$timeout(() => {
this.focused = true;
this.showDropDown = true;
});
});
this.$element.bind('focusout', e => {
this.$timeout(() => {
this.showDropDown = false;
this.focused = false;
this.showDropDown = this.mouseFocus;
});
});
});
let rectangle = this.$element[0].getBoundingClientRect();
this.width = Math.round(rectangle.width) - 15;
this.width = Math.round(rectangle.width) - 10;
}
$onDestroy() {
@ -155,6 +236,10 @@ module.component('vnAutocomplete', {
data: '<?',
itemAs: '@?',
field: '=',
label: '@'
label: '@',
itemTemplate: '@?'
},
transclude: {
tplItem: '?tplItem'
}
});

View File

@ -35,6 +35,6 @@ vn-autocomplete {
font-size: 18px;
}
vn-drop-down{
margin-top: 50px;
margin-top: 47px;
}
}

View File

@ -1,4 +1,4 @@
<vn-vertical class="dropdown-body" ng-show="$ctrl.show">
<vn-vertical class="dropdown-body" ng-show="$ctrl.show && $ctrl.itemsFiltered.length > 1">
<vn-one ng-show="$ctrl.filter" class="filter">
<vn-horizontal>
<input vn-one placeholder="{{'Search' | translate}}" type="text" ng-model="$ctrl.search"/>
@ -7,8 +7,15 @@
</vn-one>
<vn-one>
<ul class="dropdown">
<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>
<li
ng-repeat="item in $ctrl.itemsFiltered track by $index"
ng-click="$ctrl.selected = item; $ctrl.show = false"
ng-class="{'active': $index === $ctrl.activeOption}"
ng-mouseover="$ctrl.activeOption = $index"
>
<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>
</vn-one>
</vn-vertical>

View File

@ -32,7 +32,7 @@ export default class DropDown {
if (value < 0) {
value = 0;
} else if (value >= this.items.length) {
value = this.items.length - 1;
value = this.showLoadMore ? this.items.length : this.items.length - 1;
}
this.$timeout(() => {
this._activeOption = value;
@ -64,9 +64,12 @@ export default class DropDown {
}
selectOption() {
if (this.activeOption >= 0 && this.items[this.activeOption]) {
if (this.activeOption >= 0 && this.activeOption < this.items.length && this.items[this.activeOption]) {
this.selected = this.items[this.activeOption];
this.show = false;
this.clearSearch();
} else if (this.showLoadMore && this.activeOption === this.items.length) {
this.loadMore();
}
}
@ -84,15 +87,28 @@ export default class DropDown {
break;
case 38: // Arrow up
this.activeOption--;
this.$timeout(() => {
this.setScrollPosition();
}, 100);
break;
case 40: // Arrow down
this.activeOption++;
this.$timeout(() => {
this.setScrollPosition();
}, 100);
break;
default:
return;
}
}
}
setScrollPosition() {
let dropdown = this.$element[0].querySelector('ul.dropdown');
let child = dropdown ? dropdown.childNodes[this.activeOption] : null;
if (child && typeof child.scrollIntoView === 'function') {
child.scrollIntoView();
}
}
$onInit() {
if (this.parent)
@ -120,5 +136,8 @@ module.component('vnDropDown', {
top: '<?',
itemWidth: '<?',
parent: '<?'
},
transclude: {
vnItem: '?vnItem'
}
});