import {Component, ElementRef, HostListener, Input, OnInit, forwardRef} from '@angular/core'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; import {AbstractComponent} from 'gp-admin-abstract'; @Component({ selector: 'gp-phone-input', template: `
{{ title }}
{{ error }}
`, styles: [ `@charset "UTF-8"; /** * Переменные */ :root { --color-white: white; --color-success: #00afec; --color-warning: #ffb827; --color-error: #f35252; --color-disabled: #dbdbdb; --color-black: black; --color-span: #b5b5b5; --color-span-second: #212121; --color-bg: #f8f8f8; --color-bg-second: #f8f8f8; --color-bg-success: rgba(0, 175, 236, 0.1); --color-bg-warning: var(--color-warning); --color-bg-error: var(--color-error); --color-placeholder: #b5b5b5; --color-border: #dbdbdb; --color-radio-border: #d3d3d3; --font-roboto: 'Roboto', sans-serif; --font-helvetica: 'Helvetica', sans-serif; } /** * */ /** * Стили для компонента "gp-phone-input" */ .gp-phone-input--success input.gp-phone-input__area { border-color: #00afec; } .gp-phone-input--success .gp-phone-input__title { color: #00afec; } .gp-phone-input--error input.gp-phone-input__area { border-color: #f35252; } .gp-phone-input--error .gp-phone-input__title { color: #f35252; } .gp-phone-input--error .gp-phone-input__error { display: block; } .gp-phone-input--disabled input.gp-phone-input__area { cursor: not-allowed; color: #b5b5b5; border-color: #dbdbdb; background-color: #f8f8f8; } .gp-phone-input__title { font: 400 1.2rem/1.4rem "Roboto", sans-serif; margin-bottom: 0.5rem; color: #b5b5b5; } .gp-phone-input__error { font: 400 1.2rem/1.4rem "Roboto", sans-serif; display: none; color: #f35252; } .gp-phone-input__area { font: 1.3rem/1.5rem "Roboto", sans-serif; width: 100%; padding: 1rem 1.5rem; color: #212121; border: 0.1rem solid #dbdbdb; border-radius: 0.2rem; background-color: #fff; } .gp-phone-input__area[type="password"] { letter-spacing: 0.5rem; font-weight: 900; } .gp-phone-input input::-webkit-input-placeholder, .gp-phone-input input:-ms-input-placeholder, .gp-phone-input input::placeholder { color: #b5b5b5; } `], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => PhoneInputComponent), multi: true } ], }) export class PhoneInputComponent extends AbstractComponent implements OnInit, ControlValueAccessor { /** * Регулярное выражение * @type {regexp} */ private static readonly PHONE_FORMAT_REGEXP: Array = [ {regexp: '^(\d)$', format: '+$1'}, {regexp: '^(\d)(\d{1,3})$', format: '+$1 $2'}, {regexp: '^(\d)(\d{3})(\d{1,3})$', format: '+$1 $2 $3'}, {regexp: '^(\d)(\d{3})(\d{3})(\d{1,2})$', format: '+$1 $2 $3-$4'}, {regexp: '^(\d)(\d{3})(\d{3})(\d{2})(\d{1,2})$', format: '+$1 $2 $3-$4-$5'} ]; /** * Состояние компонента * @type {boolean} */ @Input() disabled: boolean = false; /** * Уникальное имя */ @Input() name: string; /** * Плейсхолдер - для предпросмотра * @type {string} */ @Input() placeholder: string = 'Телефон'; /** * Текст ошибки */ @Input() error: string; /** * Заголовок компонента * @type {string} */ @Input() title: string = 'Телефон'; /** * Телефон */ @Input() phone: string | null; constructor(protected el: ElementRef) { super(el); } @HostListener('keydown', ['$event']) onKeyDown(event: any) { const e = event; if ([46, 8, 9, 27, 13, 110, 190].indexOf(e.keyCode) !== -1 || // Allow: Ctrl+A (e.keyCode === 65 && e.ctrlKey === true) || // Allow: Ctrl+C (e.keyCode === 67 && e.ctrlKey === true) || // Allow: Ctrl+V (e.keyCode === 86 && e.ctrlKey === true) || // Allow: Ctrl+X (e.keyCode === 88 && e.ctrlKey === true) || // Allow: home, end, left, right (e.keyCode >= 35 && e.keyCode <= 39)) { // let it happen, don't do anything return; } // Ensure that it is a number and stop the keypress if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) { e.preventDefault(); } } ngOnInit() { if (this.phone) { this.prettyPhone(this.phone); } } writeValue(value: string): void { if (value) { this.prettyPhone(value); } else { this.phone = null; } } registerOnChange(fn: any): void { this.propagateChange = fn; } propagateChange = (_: any) => { } registerOnTouched(fn: any): void { } setDisabledState(isDisabled: boolean): void { this.disabled = isDisabled; } /** * При вводе чисел * @param e */ onChange(e: any) { this.prettyPhone(e); } /** * Преобразование телефона * @param phone */ private prettyPhone(phone: any): void { phone = phone.replace(/\D/g, ''); for (let i = 0; i < PhoneInputComponent.PHONE_FORMAT_REGEXP.length; i++) { const exp = PhoneInputComponent.PHONE_FORMAT_REGEXP[i].regexp; const format = PhoneInputComponent.PHONE_FORMAT_REGEXP[i].format; const re = new RegExp(exp); if (re.test(phone)) { phone = phone.replace(exp, format); break; } } this.phone = phone; this.propagateChange(this.phone); } }