This commit is contained in:
Juan Ferrer Toribio 2017-01-19 14:45:50 +01:00
parent 33711c5e33
commit 3e16417965
7 changed files with 152 additions and 109 deletions

View File

@ -1,82 +1,154 @@
import {module} from '../module'; import {module} from '../module';
export {factory as mdlFactory} from './index.mdl'; export {factory as mdlFactory} from './index.mdl';
import * as resolveFactory from '../resolveDefaultComponents';
import * as normalizerFactory from '../inputAttrsNormalizer';
require('./style.css'); require('./style.css');
directive.$inject = [resolveFactory.NAME, normalizerFactory.NAME]; export const component = {
export function directive(resolve, normalizer) {
return {
restrict: 'E', restrict: 'E',
transclude: true, transclude: true,
scope: { bindings: {
url: '@', url: '@',
showField: '@', showField: '@',
valueField: '@', valueField: '@',
model: '<' model: '<'
}, },
template: function(element, attrs) { template: template,
normalizer.normalize(attrs);
return resolve.getTemplate('autocomplete', attrs);
},
link: function(scope, element, attrs) {
scope.$watch(attrs.model, () => {
let mdlField = element[0].firstChild.MaterialTextfield;
if (mdlField)
mdlField.updateClasses_();
});
componentHandler.upgradeElement(element[0].firstChild);
},
controller: controller controller: controller
}; };
module.component('vnAutocomplete', component);
template.$inject = ['$element', '$attrs', 'vnInputAttrsNormalizer', 'vnResolveDefaultComponent'];
function template($element, $attrs, normalizer, resolve) {
normalizer.normalize($attrs);
return resolve.getTemplate('autocomplete', $attrs);
} }
module.directive('vnAutocomplete', directive);
controller.$inject = ['$http', '$element', '$attrs', '$scope', '$parse', '$document', 'vnPopover']; controller.$inject = ['$http', '$element', '$attrs', '$scope', '$parse', '$document', 'vnPopover'];
export function controller($http, $element, $attrs, $scope, $parse, $document, popover) { function controller($http, $element, $attrs, $scope, $parse, $document, popover) {
let dropdown = null; let dropdown = null;
let input = $element.find('input'); let input = $element.find('input');
let data = []; let data = [];
let locked = false; let locked = false;
let timeoutId = null;
$http.get($scope.url).then(
json => {
data = json.data;
setTimeout(function() {
$scope.setValue($scope.model);
});
},
json => {data = [];}
);
$scope.$watch($attrs.model, (newValue) => { $scope.$watch($attrs.model, (newValue) => {
if(!locked) { if(!locked) {
locked = true; locked = true;
$scope.setValue(newValue); this.setValue(newValue);
locked = false; locked = false;
} }
});
$scope.setValue = function(value) { let mdlField = $element[0].firstChild.MaterialTextfield;
if (mdlField)
mdlField.updateClasses_();
});
componentHandler.upgradeElement($element[0].firstChild);
this.loadData = function(where, callback) {
if(!where) where = {};
let fields = {};
fields[this.valueField] = true;
fields[this.showField] = true;
let filter = {
fields: fields,
where: where,
order: `${this.showField} ASC`,
limit: 5
};
let json = JSON.stringify(filter);
$http.get(`${this.url}?filter=${json}`).then(
json => {
data = json.data;
if (callback) callback();
},
json => {
data = [];
}
);
};
this.onClick = function() {
input[0].select();
this.showDropdown();
};
this.showDropdown = function() {
//FIXME
popover.hide();
dropdown = $document[0].createElement('ul');
dropdown.addEventListener('click',
(e) => this.onOptionClick(e));
dropdown.className = 'vn-dropdown';
for(let i = 0; i < data.length; i++) {
let li = $document[0].createElement('li');
li.tabIndex = 0;
li.appendChild($document[0].createTextNode(data[i][this.showField]));
dropdown.appendChild(li);
}
popover.show(dropdown, input);
}
this.onOptionClick = function(event) {
popover.hide();
let childs = dropdown.childNodes;
for(let i = 0; i < childs.length; i++)
if(childs[i] === event.target) {
this.selectOptionByIndex(i);
break;
}
}
this.onTimeout = function() {
let value = input.val();
let filter = {};
filter[this.showField] = {ilike: value};
this.loadData(filter, () => this.showDropdown());
clearTimeout(timeoutId);
timeoutId = null;
}
this.onKeyup = function(event) {
if(timeoutId) clearTimeout(timeoutId);
console.log(event.keyCode);
switch(event.keyCode) {
case 13: // Enter
this.selectOptionByIndex(0);
return;
case 40: // Arrow down
dropdown.firstChild.focus();
return;
}
timeoutId = setTimeout(() => this.onTimeout(), 300);
};
this.setValue = function(value) {
let index = -1; let index = -1;
if(value && data) if(value && data)
for(let i = 0; i < data.length; i++) for(let i = 0; i < data.length; i++)
if(data[i][$scope.valueField] == value) { if(data[i][this.valueField] == value) {
$scope.selectOptionByIndex(i); this.selectOptionByIndex(i);
return; return;
} }
$scope.selectOptionByIndex(-1); this.selectOptionByIndex(-1);
} }
$scope.selectOptionByIndex = function(index) { this.selectOptionByIndex = function(index) {
let value; let value;
if(index >= 0) { if(index >= 0 && index < data.length) {
let item = data[index]; let item = data[index];
input.val(item[$scope.showField]); input.val(item[this.showField]);
value = item[$scope.valueField]; value = item[this.valueField];
} }
else { else {
input.val(''); input.val('');
@ -92,33 +164,7 @@ export function controller($http, $element, $attrs, $scope, $parse, $document, p
} }
} }
function onOptionClick(event) { this.loadData(null, () => {
popover.hide(); setTimeout(() => this.setValue(this.model));
});
let childs = dropdown.childNodes;
for(let i = 0; i < childs.length; i++)
if(childs[i] === event.target) {
$scope.selectOptionByIndex(i);
break;
}
}
$scope.onClick = () => {
dropdown = $document[0].createElement('ul');
dropdown.addEventListener('click', onOptionClick);
dropdown.className = 'vn-dropdown';
for(let i = 0; i < data.length; i++) {
let item = $document[0].createElement('li');
item.className = 'vn-dropdown-item';
item.appendChild($document[0].createTextNode(data[i][$scope.showField]));
dropdown.appendChild(item);
}
popover.show(dropdown, input);
};
$scope.onKeypress = () => {
console.log(input.val());
};
} }

View File

@ -1,4 +1,4 @@
<div class="mdl-textfield mdl-js-textfield *[className]*" ng-click="onClick()"> <div class="mdl-textfield mdl-js-textfield *[className]*" ng-click="$ctrl.onClick($event)">
<input class="mdl-textfield__input" type="text" rule="*[rule]*" ng-keypress="onKeypress()" *[enabled]* *[focus]*/> <input class="mdl-textfield__input" type="text" rule="*[rule]*" ng-keyup="$ctrl.onKeyup($event)" *[enabled]* *[focus]*/>
<label class="mdl-textfield__label" translate>*[label]*</label> <label class="mdl-textfield__label" translate>*[label]*</label>
</div> </div>

View File

@ -4,15 +4,15 @@
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
.vn-dropdown-item { .vn-dropdown > li {
display: block; display: block;
padding: .8em; padding: .8em;
margin: 0; margin: 0;
} }
.vn-dropdown-item:hover { .vn-dropdown > li:hover {
background-color: rgba(1,1,1,.1); background-color: rgba(1,1,1,.1);
cursor: pointer; cursor: pointer;
} }
.vn-dropdown-item:active { .vn-dropdown > li:active {
background-color: rgba(1,1,1,.2); background-color: rgba(1,1,1,.2);
} }

View File

@ -77,6 +77,7 @@ function provider($document, $compile) {
this.show(childElement, parent); this.show(childElement, parent);
}, },
hide: function() { hide: function() {
if(!this.popover) return;
$document.off('mousedown', this.docMouseDownHandler); $document.off('mousedown', this.docMouseDownHandler);
$document[0].body.removeChild (this.popover); $document[0].body.removeChild (this.popover);
this.popover = null; this.popover = null;

View File

@ -21,11 +21,7 @@ export const COMPONENT = {
this.$onDestroy = function() { this.$onDestroy = function() {
deregister(); deregister();
}; };
/*
$http.get('/client/api/SalesPeople').then(
json => {this.sales = json.data;}
);
*/
function callback(transition) { function callback(transition) {
if (!equalsObject(self.client, self.clientOld)) { if (!equalsObject(self.client, self.clientOld)) {
self.state = transition.to().name; self.state = transition.to().name;

View File

@ -13,12 +13,20 @@
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>
<vn-textfield vn-one label="Código postal" field="fiscal.client.postcode"></vn-textfield> <vn-textfield vn-one label="Código postal" field="fiscal.client.postcode"></vn-textfield>
<vn-combo vn-one label="Provincia" field="fiscal.client.province"> <vn-autocomplete vn-one
<option ng-repeat="p in fiscal.provinces | orderBy:'name'" value="{{p.id}}">{{p.name}}</option> field="fiscal.client.province"
</vn-combo> url="/client/api/Provinces"
<vn-combo vn-one label="País" field="fiscal.client.country"> show-field="name"
<option ng-repeat="c in fiscal.countries | orderBy:'name'" value="{{c.id}}">{{c.name}}</option> value-field="id"
</vn-combo> label="Provincia">
</vn-autocomplete>
<vn-autocomplete vn-one
field="fiscal.client.country"
url="/client/api/Countries"
show-field="name"
value-field="id"
label="País">
</vn-autocomplete>
</vn-horizontal> </vn-horizontal>
</vn-vertical> </vn-vertical>
</vn-card> </vn-card>
@ -27,9 +35,13 @@
<vn-title>Información de facturación</vn-title> <vn-title>Información de facturación</vn-title>
<vn-horizontal> <vn-horizontal>
<vn-textfield vn-two label="IBAN" field="fiscal.client.iban"></vn-textfield> <vn-textfield vn-two label="IBAN" field="fiscal.client.iban"></vn-textfield>
<vn-combo vn-two label="Forma de pago" field="fiscal.client.payMethod"> <vn-autocomplete vn-two
<option ng-repeat="p in fiscal.payments" value="{{p.id}}">{{p.name}}</option> field="fiscal.client.payMethod"
</vn-combo> url="/client/api/PaymentMethods"
show-field="name"
value-field="id"
label="Forma de pago">
</vn-autocomplete>
<vn-textfield vn-one label="Vencimiento" field="fiscal.client.dueDay"></vn-textfield> <vn-textfield vn-one label="Vencimiento" field="fiscal.client.dueDay"></vn-textfield>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal>

View File

@ -12,18 +12,6 @@ export const COMPONENT = {
var self = this; var self = this;
var deregister = $transitions.onStart({ }, callback); var deregister = $transitions.onStart({ }, callback);
$http.get('/client/api/Countries').then(
json => this.countries = json.data
);
$http.get('/client/api/Provinces').then(
json => this.provinces = json.data
);
$http.get('/client/api/PaymentMethods').then(
json => this.payments = json.data
);
this.submit = function() { this.submit = function() {
if (!equalsObject(this.client, this.clientOld)) { if (!equalsObject(this.client, this.clientOld)) {
this.client.modify = "FiscalData"; this.client.modify = "FiscalData";