vnAutocomplete: Acepta plantillas

This commit is contained in:
Juan Ferrer Toribio 2017-05-24 13:24:32 +02:00
parent bcd4cedbcd
commit 345f2e55a5
4 changed files with 53 additions and 9 deletions

View File

@ -27,7 +27,11 @@
url="/client/api/Employees"
show-field="name"
value-field="id"
select-fields="surname"
label="Comercial">
<item-template>
{{::i.name}} {{::i.surname}}
</item-template>
</vn-autocomplete>
<vn-autocomplete vn-one
initial-value="$ctrl.client.contactChannel"

View File

@ -2,8 +2,6 @@ import {module} from '../module';
import './style.css';
import './item-client';
export const NAME = 'vnClientIndex';
export const COMPONENT = {
module.component('vnClientIndex', {
template: require('./index.html')
};
module.component(NAME, COMPONENT);
});

View File

@ -6,7 +6,7 @@ import './style.scss';
* Combobox like component with search and partial data loading features.
*/
export default class Autocomplete extends Component {
constructor($element, $scope, $http, vnPopover) {
constructor($element, $scope, $http, vnPopover, $transclude) {
super($element);
this.input = $element[0].querySelector('input');
this.item = null;
@ -23,12 +23,15 @@ export default class Autocomplete extends Component {
this.$http = $http;
this.$scope = $scope;
this.vnPopover = vnPopover;
this.$transclude = $transclude;
this.scopes = null;
Object.assign(this, {
maxRows: 10,
requestDelay: 350,
showField: 'name',
valueField: 'id'
valueField: 'id',
itemAs: 'i'
});
componentHandler.upgradeElement($element[0].firstChild);
@ -149,6 +152,11 @@ export default class Autocomplete extends Component {
if (this.hasFocus)
this.showPopover();
}
destroyScopes() {
if (this.scopes)
for (let scope of this.scopes)
scope.$destroy();
}
showPopover() {
let data = this.displayData;
@ -156,11 +164,25 @@ export default class Autocomplete extends Component {
return;
let fragment = this.document.createDocumentFragment();
this.destroyScopes();
this.scopes = [];
let hasTemplate = this.$transclude.isSlotFilled('itemTemplate');
for (let i = 0; i < data.length; i++) {
let li = this.document.createElement('li');
li.appendChild(this.document.createTextNode(data[i][this.showField]));
fragment.appendChild(li);
if (hasTemplate) {
this.$transclude((clone, scope) => {
scope[this.itemAs] = data[i];
li.appendChild(clone[0]);
this.scopes[i] = scope;
}, null, 'itemTemplate');
} else {
let text = this.document.createTextNode(data[i][this.showField]);
li.appendChild(text);
}
}
if (this.moreData) {
@ -189,6 +211,7 @@ export default class Autocomplete extends Component {
if (!this.popover) return;
this.activeOption = -1;
this.vnPopover.hide();
this.destroyScopes();
this.popover = null;
}
selectPopoverOption(index) {
@ -200,9 +223,17 @@ export default class Autocomplete extends Component {
this.requestData(this.lastRequest, true);
}
onPopoverClick(event) {
let target = event.target;
let childs = this.popover.childNodes;
if (target === this.popover)
return;
while (target.parentNode !== this.popover)
target = target.parentNode;
for (let i = 0; i < childs.length; i++)
if (childs[i] === event.target) {
if (childs[i] === target) {
this.selectPopoverOption(i);
break;
}
@ -362,8 +393,11 @@ export default class Autocomplete extends Component {
this.item = item;
this.mdlUpdate();
}
$onDestroy() {
this.destroyScopes();
}
}
Autocomplete.$inject = ['$element', '$scope', '$http', 'vnPopover'];
Autocomplete.$inject = ['$element', '$scope', '$http', 'vnPopover', '$transclude'];
module.component('vnAutocomplete', {
template: require('./index.html'),
@ -373,8 +407,12 @@ module.component('vnAutocomplete', {
valueField: '@?',
selectFields: '@?',
initialData: '<?',
itemAs: '@?',
field: '=',
label: '@'
},
transclude: {
itemTemplate: '?itemTemplate'
},
controller: Autocomplete
});

View File

@ -11,6 +11,10 @@
"name": {
"type": "string",
"required": true
},
"surname": {
"type": "string",
"required": true
}
},
"relations": {