Merge pull request #6817 from ArtemDzhereleiko/AD/bug-fix/phone-input
[3.4] UI: Change type of loading lib for phone number input and fix bugs
This commit is contained in:
commit
c3d11ace34
@ -19,7 +19,8 @@
|
|||||||
<form [formGroup]="phoneFormGroup">
|
<form [formGroup]="phoneFormGroup">
|
||||||
<div class="phone-input-container">
|
<div class="phone-input-container">
|
||||||
<div class="flags-select-container" *ngIf="enableFlagsSelect">
|
<div class="flags-select-container" *ngIf="enableFlagsSelect">
|
||||||
<span class="flag-container">{{ flagIcon }}</span>
|
<span class="flag-container" *ngIf="!isLoad">{{ flagIcon }}</span>
|
||||||
|
<mat-spinner diameter="20" class="flag-loader" *ngIf="isLoad"></mat-spinner>
|
||||||
<mat-select class="country-select" formControlName="country">
|
<mat-select class="country-select" formControlName="country">
|
||||||
<mat-option *ngFor="let country of allCountries" [value]="country.iso2">
|
<mat-option *ngFor="let country of allCountries" [value]="country.iso2">
|
||||||
<span style="font-size: 20px;">{{country.flag}}</span>
|
<span style="font-size: 20px;">{{country.flag}}</span>
|
||||||
|
|||||||
@ -15,6 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
:host ::ng-deep {
|
:host ::ng-deep {
|
||||||
|
|
||||||
|
.flag-loader {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 0;
|
||||||
|
transform: translate(0, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
.phone-input-container {
|
.phone-input-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@ -30,7 +30,6 @@ import {
|
|||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { Country, CountryData } from '@shared/models/country.models';
|
import { Country, CountryData } from '@shared/models/country.models';
|
||||||
import examples from 'libphonenumber-js/examples.mobile.json';
|
import examples from 'libphonenumber-js/examples.mobile.json';
|
||||||
import { CountryCode, getExampleNumber, parsePhoneNumberFromString } from 'libphonenumber-js';
|
|
||||||
import { phoneNumberPattern } from '@shared/models/settings.models';
|
import { phoneNumberPattern } from '@shared/models/settings.models';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { FloatLabelType, MatFormFieldAppearance } from '@angular/material/form-field/form-field';
|
import { FloatLabelType, MatFormFieldAppearance } from '@angular/material/form-field/form-field';
|
||||||
@ -59,7 +58,7 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida
|
|||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
defaultCountry: CountryCode = 'US';
|
defaultCountry = 'US';
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
enableFlagsSelect = true;
|
enableFlagsSelect = true;
|
||||||
@ -80,13 +79,29 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida
|
|||||||
label = 'phone-input.phone-input-label';
|
label = 'phone-input.phone-input-label';
|
||||||
|
|
||||||
allCountries: Array<Country> = this.countryCodeData.allCountries;
|
allCountries: Array<Country> = this.countryCodeData.allCountries;
|
||||||
phonePlaceholder: string;
|
phonePlaceholder = '+12015550123';
|
||||||
flagIcon: string;
|
flagIcon: string;
|
||||||
phoneFormGroup: FormGroup;
|
phoneFormGroup: FormGroup;
|
||||||
phoneNumberPattern = phoneNumberPattern;
|
phoneNumberPattern = phoneNumberPattern;
|
||||||
|
|
||||||
|
private isLoading = true;
|
||||||
|
get isLoad(): boolean {
|
||||||
|
return this.isLoading;
|
||||||
|
}
|
||||||
|
|
||||||
|
set isLoad(value) {
|
||||||
|
if (this.isLoading) {
|
||||||
|
this.isLoading = value;
|
||||||
|
if (this.phoneFormGroup) {
|
||||||
|
this.defineCountryFromNumber(this.phoneFormGroup.get('phoneNumber').value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getExampleNumber;
|
||||||
|
private parsePhoneNumberFromString;
|
||||||
private baseCode = 127397;
|
private baseCode = 127397;
|
||||||
private countryCallingCode: string;
|
private countryCallingCode = '+';
|
||||||
private modelValue: string;
|
private modelValue: string;
|
||||||
private valueChange$: Subscription = null;
|
private valueChange$: Subscription = null;
|
||||||
private propagateChange = (v: any) => { };
|
private propagateChange = (v: any) => { };
|
||||||
@ -94,6 +109,10 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida
|
|||||||
constructor(private translate: TranslateService,
|
constructor(private translate: TranslateService,
|
||||||
private fb: FormBuilder,
|
private fb: FormBuilder,
|
||||||
private countryCodeData: CountryData) {
|
private countryCodeData: CountryData) {
|
||||||
|
import('libphonenumber-js/max').then((libphonenubmer) => {
|
||||||
|
this.parsePhoneNumberFromString = libphonenubmer.parsePhoneNumberFromString;
|
||||||
|
this.getExampleNumber = libphonenubmer.getExampleNumber;
|
||||||
|
}).then(() => this.isLoad = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@ -108,13 +127,7 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida
|
|||||||
|
|
||||||
this.valueChange$ = this.phoneFormGroup.get('phoneNumber').valueChanges.subscribe(value => {
|
this.valueChange$ = this.phoneFormGroup.get('phoneNumber').valueChanges.subscribe(value => {
|
||||||
this.updateModel();
|
this.updateModel();
|
||||||
if (value) {
|
this.defineCountryFromNumber(value);
|
||||||
const parsedPhoneNumber = parsePhoneNumberFromString(value);
|
|
||||||
const country = this.phoneFormGroup.get('country').value;
|
|
||||||
if (parsedPhoneNumber?.country && parsedPhoneNumber?.country !== country) {
|
|
||||||
this.phoneFormGroup.get('country').patchValue(parsedPhoneNumber.country, {emitEvent: true});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.phoneFormGroup.get('country').valueChanges.subscribe(value => {
|
this.phoneFormGroup.get('country').valueChanges.subscribe(value => {
|
||||||
@ -155,9 +168,11 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getPhoneNumberData(country): void {
|
private getPhoneNumberData(country): void {
|
||||||
const phoneData = getExampleNumber(country, examples);
|
if (this.getExampleNumber) {
|
||||||
this.phonePlaceholder = phoneData.number;
|
const phoneData = this.getExampleNumber(country, examples);
|
||||||
this.countryCallingCode = '+' + phoneData.countryCallingCode;
|
this.phonePlaceholder = phoneData.number;
|
||||||
|
this.countryCallingCode = `+${this.enableFlagsSelect ? phoneData.countryCallingCode : ''}`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getFlagIcon(countryCode) {
|
private getFlagIcon(countryCode) {
|
||||||
@ -167,8 +182,8 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida
|
|||||||
validatePhoneNumber(): ValidatorFn {
|
validatePhoneNumber(): ValidatorFn {
|
||||||
return (c: FormControl) => {
|
return (c: FormControl) => {
|
||||||
const phoneNumber = c.value;
|
const phoneNumber = c.value;
|
||||||
if (phoneNumber) {
|
if (phoneNumber && this.parsePhoneNumberFromString) {
|
||||||
const parsedPhoneNumber = parsePhoneNumberFromString(phoneNumber);
|
const parsedPhoneNumber = this.parsePhoneNumberFromString(phoneNumber);
|
||||||
if (!parsedPhoneNumber?.isValid() || !parsedPhoneNumber?.isPossible()) {
|
if (!parsedPhoneNumber?.isValid() || !parsedPhoneNumber?.isPossible()) {
|
||||||
return {
|
return {
|
||||||
invalidPhoneNumber: {
|
invalidPhoneNumber: {
|
||||||
@ -181,6 +196,16 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private defineCountryFromNumber(phoneNumber) {
|
||||||
|
if (phoneNumber && this.parsePhoneNumberFromString) {
|
||||||
|
const parsedPhoneNumber = this.parsePhoneNumberFromString(phoneNumber);
|
||||||
|
const country = this.phoneFormGroup.get('country').value;
|
||||||
|
if (parsedPhoneNumber?.country && parsedPhoneNumber?.country !== country) {
|
||||||
|
this.phoneFormGroup.get('country').patchValue(parsedPhoneNumber.country, {emitEvent: true});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
validate(): ValidationErrors | null {
|
validate(): ValidationErrors | null {
|
||||||
return this.phoneFormGroup.get('phoneNumber').valid ? null : {
|
return this.phoneFormGroup.get('phoneNumber').valid ? null : {
|
||||||
phoneFormGroup: false
|
phoneFormGroup: false
|
||||||
@ -205,8 +230,11 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida
|
|||||||
|
|
||||||
writeValue(phoneNumber): void {
|
writeValue(phoneNumber): void {
|
||||||
this.modelValue = phoneNumber;
|
this.modelValue = phoneNumber;
|
||||||
const country = phoneNumber ? parsePhoneNumberFromString(phoneNumber)?.country : this.defaultCountry;
|
let country = this.defaultCountry;
|
||||||
this.getFlagAndPhoneNumberData(country);
|
if (this.parsePhoneNumberFromString) {
|
||||||
|
country = phoneNumber ? this.parsePhoneNumberFromString(phoneNumber)?.country : this.defaultCountry;
|
||||||
|
this.getFlagAndPhoneNumberData(country);
|
||||||
|
}
|
||||||
this.phoneFormGroup.patchValue({phoneNumber, country}, {emitEvent: !phoneNumber});
|
this.phoneFormGroup.patchValue({phoneNumber, country}, {emitEvent: !phoneNumber});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,7 +243,7 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida
|
|||||||
if (phoneNumber.valid && phoneNumber.value) {
|
if (phoneNumber.valid && phoneNumber.value) {
|
||||||
this.modelValue = phoneNumber.value;
|
this.modelValue = phoneNumber.value;
|
||||||
this.propagateChange(this.modelValue);
|
this.propagateChange(this.modelValue);
|
||||||
} else {
|
} else if (phoneNumber.invalid && phoneNumber.value) {
|
||||||
this.propagateChange(null);
|
this.propagateChange(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -357,7 +357,7 @@ export class CountryData {
|
|||||||
{name: 'Gibraltar', iso2: CountryISO.Gibraltar, dialCode: '350', flag: '🇬🇮'},
|
{name: 'Gibraltar', iso2: CountryISO.Gibraltar, dialCode: '350', flag: '🇬🇮'},
|
||||||
{name: 'Greece', iso2: CountryISO.Greece, dialCode: '30', flag: '🇬🇷'},
|
{name: 'Greece', iso2: CountryISO.Greece, dialCode: '30', flag: '🇬🇷'},
|
||||||
{name: 'Greenland', iso2: CountryISO.Greenland, dialCode: '299', flag: '🇬🇱'},
|
{name: 'Greenland', iso2: CountryISO.Greenland, dialCode: '299', flag: '🇬🇱'},
|
||||||
{name: 'Grenada', iso2: CountryISO.Grenada, dialCode: '1473', flag: '🇬🇩'},
|
{name: 'Grenada', iso2: CountryISO.Grenada, dialCode: '1', flag: '🇬🇩'},
|
||||||
{name: 'Guadeloupe', iso2: CountryISO.Guadeloupe, dialCode: '590', flag: '🇬🇵'},
|
{name: 'Guadeloupe', iso2: CountryISO.Guadeloupe, dialCode: '590', flag: '🇬🇵'},
|
||||||
{name: 'Guam', iso2: CountryISO.Guam, dialCode: '1', flag: '🇬🇺'},
|
{name: 'Guam', iso2: CountryISO.Guam, dialCode: '1', flag: '🇬🇺'},
|
||||||
{name: 'Guatemala', iso2: CountryISO.Guatemala, dialCode: '502', flag: '🇬🇹'},
|
{name: 'Guatemala', iso2: CountryISO.Guatemala, dialCode: '502', flag: '🇬🇹'},
|
||||||
@ -432,7 +432,7 @@ export class CountryData {
|
|||||||
{name: 'Niue', iso2: CountryISO.Niue, dialCode: '683', flag: '🇳🇺'},
|
{name: 'Niue', iso2: CountryISO.Niue, dialCode: '683', flag: '🇳🇺'},
|
||||||
{name: 'Norfolk Island', iso2: CountryISO.NorfolkIsland, dialCode: '672', flag: '🇳🇫'},
|
{name: 'Norfolk Island', iso2: CountryISO.NorfolkIsland, dialCode: '672', flag: '🇳🇫'},
|
||||||
{name: 'North Korea', iso2: CountryISO.NorthKorea, dialCode: '850', flag: '🇰🇵'},
|
{name: 'North Korea', iso2: CountryISO.NorthKorea, dialCode: '850', flag: '🇰🇵'},
|
||||||
{name: 'Northern Mariana Islands', iso2: CountryISO.NorthernMarianaIslands, dialCode: '1670', flag: '🇲🇵'},
|
{name: 'Northern Mariana Islands', iso2: CountryISO.NorthernMarianaIslands, dialCode: '1', flag: '🇲🇵'},
|
||||||
{name: 'Norway', iso2: CountryISO.Norway, dialCode: '47', flag: '🇳🇴'},
|
{name: 'Norway', iso2: CountryISO.Norway, dialCode: '47', flag: '🇳🇴'},
|
||||||
{name: 'Oman', iso2: CountryISO.Oman, dialCode: '968', flag: '🇴🇲'},
|
{name: 'Oman', iso2: CountryISO.Oman, dialCode: '968', flag: '🇴🇲'},
|
||||||
{name: 'Pakistan', iso2: CountryISO.Pakistan, dialCode: '92', flag: '🇵🇰'},
|
{name: 'Pakistan', iso2: CountryISO.Pakistan, dialCode: '92', flag: '🇵🇰'},
|
||||||
@ -453,7 +453,7 @@ export class CountryData {
|
|||||||
{name: 'Rwanda', iso2: CountryISO.Rwanda, dialCode: '250', flag: '🇷🇼'},
|
{name: 'Rwanda', iso2: CountryISO.Rwanda, dialCode: '250', flag: '🇷🇼'},
|
||||||
{name: 'Saint Barthélemy', iso2: CountryISO.SaintBarthélemy, dialCode: '590', flag: '🇧🇱'},
|
{name: 'Saint Barthélemy', iso2: CountryISO.SaintBarthélemy, dialCode: '590', flag: '🇧🇱'},
|
||||||
{name: 'Saint Helena', iso2: CountryISO.SaintHelena, dialCode: '290', flag: '🇸🇭'},
|
{name: 'Saint Helena', iso2: CountryISO.SaintHelena, dialCode: '290', flag: '🇸🇭'},
|
||||||
{name: 'Saint Kitts and Nevis', iso2: CountryISO.SaintKittsAndNevis, dialCode: '1869', flag: '🇰🇳'},
|
{name: 'Saint Kitts and Nevis', iso2: CountryISO.SaintKittsAndNevis, dialCode: '1', flag: '🇰🇳'},
|
||||||
{name: 'Saint Lucia', iso2: CountryISO.SaintLucia, dialCode: '1', flag: '🇱🇨'},
|
{name: 'Saint Lucia', iso2: CountryISO.SaintLucia, dialCode: '1', flag: '🇱🇨'},
|
||||||
{name: 'Saint Martin', iso2: CountryISO.SaintMartin, dialCode: '590', flag: '🇲🇫'},
|
{name: 'Saint Martin', iso2: CountryISO.SaintMartin, dialCode: '590', flag: '🇲🇫'},
|
||||||
{name: 'Saint Pierre and Miquelon', iso2: CountryISO.SaintPierreAndMiquelon, dialCode: '508', flag: '🇵🇲'},
|
{name: 'Saint Pierre and Miquelon', iso2: CountryISO.SaintPierreAndMiquelon, dialCode: '508', flag: '🇵🇲'},
|
||||||
@ -496,7 +496,7 @@ export class CountryData {
|
|||||||
{name: 'Tunisia', iso2: CountryISO.Tunisia, dialCode: '216', flag: '🇹🇳'},
|
{name: 'Tunisia', iso2: CountryISO.Tunisia, dialCode: '216', flag: '🇹🇳'},
|
||||||
{name: 'Turkey', iso2: CountryISO.Turkey, dialCode: '90', flag: '🇹🇷'},
|
{name: 'Turkey', iso2: CountryISO.Turkey, dialCode: '90', flag: '🇹🇷'},
|
||||||
{name: 'Turkmenistan', iso2: CountryISO.Turkmenistan, dialCode: '993', flag: '🇹🇲'},
|
{name: 'Turkmenistan', iso2: CountryISO.Turkmenistan, dialCode: '993', flag: '🇹🇲'},
|
||||||
{name: 'Turks and Caicos Islands', iso2: CountryISO.TurksAndCaicosIslands, dialCode: '1649', flag: '🇹🇨'},
|
{name: 'Turks and Caicos Islands', iso2: CountryISO.TurksAndCaicosIslands, dialCode: '1', flag: '🇹🇨'},
|
||||||
{name: 'Tuvalu', iso2: CountryISO.Tuvalu, dialCode: '688', flag: '🇹🇻'},
|
{name: 'Tuvalu', iso2: CountryISO.Tuvalu, dialCode: '688', flag: '🇹🇻'},
|
||||||
{name: 'U.S. Virgin Islands', iso2: CountryISO.USVirginIslands, dialCode: '1', flag: '🇻🇮'},
|
{name: 'U.S. Virgin Islands', iso2: CountryISO.USVirginIslands, dialCode: '1', flag: '🇻🇮'},
|
||||||
{name: 'Uganda', iso2: CountryISO.Uganda, dialCode: '256', flag: '🇺🇬'},
|
{name: 'Uganda', iso2: CountryISO.Uganda, dialCode: '256', flag: '🇺🇬'},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user