import ngModule from '../../module'; import FormInput from '../form-input'; import './style.scss'; export default class Field extends FormInput { constructor($element, $scope, $transclude) { super($element, $scope, $transclude); this.prefix = null; this.suffix = null; this.container = this.element.querySelector('.container'); this.container.addEventListener('focusout', () => this.onFocus(false)); this.container.addEventListener('focusin', () => this.onFocus(true)); this.control = this.element.querySelector('.control'); } $onInit() { super.$onInit(); if (this.info) this.classList.add('has-icons'); this.element.addEventListener('change', event => this.onChange(event)); } set field(value) { if (value === this.field) return; super.field = value; this.classList.toggle('not-empty', value != null && value !== ''); this.validateValue(); } get field() { return super.field; } set input(value) { if (this.input) this.control.removeChild(this.input); this._input = value; if (value) this.control.appendChild(value); } get input() { return this._input; } set value(value) { this.input.value = 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 placeholder(value) { this.input.placeholder = value; } get placeholder() { return this.input.placeholder; } set required(value) { this._required = 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) { if (value === this.error) return; this._error = value; this.refreshHint(); } get error() { return this._error; } get shownError() { return this.error || this.inputError || null; } get autocomplete() { return this._autocomplete; } set autocomplete(value) { this._autocomplete = value; if (value === 'off') this.input.setAttribute('autocomplete', 'off'); } refreshHint() { let error = this.shownError; let hint = error || this.hint; let hintEl = this.element.querySelector('.hint'); hintEl.innerText = hint || ''; hintEl.classList.toggle('filled', Boolean(hint)); this.classList.toggle('invalid', Boolean(error)); } refreshFix(selector, text) { let fix = this.element.querySelector(selector); display(fix, text); fix.innerText = text || ''; } onFocus(hasFocus) { this.classList.toggle('focused', hasFocus); } onClear(event) { if (event.defaultPrevented) return; event.preventDefault(); this.field = null; this.element.dispatchEvent(new Event('change')); } buildInput(type) { let template = ``; this.input = this.$compile(template)(this.$)[0]; } /** * If input value is invalid, sets the error message as hint. */ validateValue() { let error = this.input.checkValidity() ? null : this.input.validationMessage; if (error === this.inputError) return; this.inputError = error; this.refreshHint(); } onChange($event) { // Changes doesn't reflect until appling async this.$.$applyAsync(() => { this.emit('change', { value: this.field, $event: $event }); }); } } Field.$inject = ['$element', '$scope', '$transclude']; ngModule.vnComponent('vnField', { template: require('./index.html'), transclude: { prepend: '?prepend', append: '?append' }, controller: Field, bindings: { type: '@?', autocomplete: '@?', placeholder: '@?', clearDisabled: '