import ngModule from '../../module'; import FormInput from '../form-input'; import './style.scss'; export default class Field extends FormInput { 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)); this.container = this.element.querySelector('.container'); this.container.addEventListener('mousedown', e => this.onMouseDown(e)); } $onInit() { super.$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}); }); } 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; this.control.appendChild(value); } get input() { return this._input; } 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 placeholder(value) { this.input.placeholder = value; } get placeholder() { return this.input.placeholder; } set tabIndex(value) { this.input.tabIndex = value; } get tabIndex() { return this.input.tabIndex; } 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) { if (value === this.error) return; this._error = value; this.refreshHint(); } get error() { return this._error; } get shownError() { return this.error || this.inputError || null; } 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 || ''; } 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]; } /** * 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(); } } Field.$inject = ['$element', '$scope', '$compile']; ngModule.vnComponent('vnField', { template: require('./index.html'), transclude: { prepend: '?prepend', append: '?append' }, controller: Field, bindings: { type: '@?', placeholder: '@?', value: '=?', info: '@?', required: '