import ngModule from '../../module'; import Component from '../../lib/component'; import './style.scss'; export default class Field extends Component { constructor($element, $scope, $compile) { super($element, $scope); this.$compile = $compile; this.prefix = null; this.suffix = null; this.control = this.element.querySelector('.control'); this.classList = this.element.classList; this.classList.add('vn-field'); this.element.addEventListener('click', e => this.onClick(e)); let container = this.element.querySelector('.container'); container.addEventListener('mousedown', e => this.onMouseDown(e)); } $onInit() { if (this.info) this.classList.add('has-icons'); this.input.addEventListener('focus', () => this.onFocus(true)); this.input.addEventListener('blur', () => this.onFocus(false)); this.input.addEventListener('change', e => { this.emit('change', {event: e}); }); // XXX: Compatibility with old inputs let attrs = this.$element[0].attributes; if (!this.name && attrs.field) { let split = attrs.field.nodeValue.split('.'); this.name = split[split.length - 1]; } } set field(value) { this._field = value; this.classList.toggle('not-empty', value != null && value !== ''); if (this.form) this.form.$setDirty(); this.validateValue(); } get field() { return this._field; } set value(value) { this.field = value; } get value() { return this.input.value; } set type(value) { this.input.type = value; } get type() { return this.input.type; } set name(value) { this.input.name = value; } get name() { return this.input.name; } set disabled(value) { this._disabled = boolTag(value); this.input.disabled = this._disabled; this.classList.toggle('disabled', this._disabled); } get disabled() { return this._disabled; } set readonly(value) { this._readonly = boolTag(value); this.input.readOnly = this._readonly; this.classList.toggle('readonly', this._readonly); } get readonly() { return this._readonly; } set required(value) { this._required = boolTag(value); let required = this.element.querySelector('.required'); display(required, this._required); } get required() { return this._required; } set prefix(value) { this._prefix = value; this.refreshFix('.prefix', value); } get prefix() { return this._prefix; } set suffix(value) { this._suffix = value; this.refreshFix('.suffix', value); } get suffix() { return this._suffix; } set hint(value) { this._hint = value; this.refreshHint(); } get hint() { return this._hint; } set error(value) { this._error = value; this.refreshHint(); this.classList.toggle('invalid', Boolean(value)); } get error() { return this._error; } refreshHint() { let hint = this.error || this.hint || ''; let hintEl = this.element.querySelector('.hint'); hintEl.innerText = hint; hintEl.classList.toggle('filled', Boolean(hint)); } refreshFix(selector, text) { let fix = this.element.querySelector(selector); display(fix, text); fix.innerText = text || ''; } onClick() { if (event.defaultPrevented) return; event.preventDefault(); if (this.input !== document.activeElement) this.focus(); } onMouseDown(event) { if (event.target == this.input) return; event.preventDefault(); this.focus(); } onFocus(hasFocus) { this.classList.toggle('focused', hasFocus); } onClear(event) { if (event.defaultPrevented) return; event.preventDefault(); this.field = null; this.input.dispatchEvent(new Event('change')); } focus() { this.input.focus(); } select() { this.input.select(); } buildInput(type) { let template = ``; this.input = this.$compile(template)(this.$)[0]; this.control.appendChild(this.input); } /** * If input value is invalid, sets the error message as hint. */ validateValue() { this.error = this.input.checkValidity() ? null : this.input.validationMessage; } } Field.$inject = ['$element', '$scope', '$compile']; ngModule.vnComponent('vnField', { template: require('./index.html'), transclude: { prepend: '?prepend', append: '?append' }, controller: Field, bindings: { field: '=?', label: '@?', name: '@?', type: '@?', value: '=?', info: '@?', disabled: '