I’ve created my own custom component for a country-flag dropdown and currently I’m facing an issue where if a user selects a country that has a incorrect placeholder like this +_3 ___ ___ ____. This issue is only for dials code with 9s in them.
`
/**
* Handles the event when a country is selected, updating the dial code, mask, and placeholder.
* @param isoCode2 The ISO code of the selected country.
*/
public onCountryChange(isoCode2: string): void {
if (!isoCode2) {
this.resetPhoneNumberField();
return;
}
const selectedCountry = this.countries.find((country) => country.isoCode2 === isoCode2);
if (selectedCountry) {
this.selectedCountry = selectedCountry;
this.selectedDialCode = selectedCountry.dialCodes[0];
this.phoneNumberMask = this.getPhoneNumberMask(selectedCountry.isoCode2);
this.phoneNumberPlaceholder = this.createPlaceholderFromMask(this.phoneNumberMask);
this.form.get(this.controlName)?.setValue(`+${this.selectedDialCode}`);
this.form.get(this.controlName)?.markAsDirty();
this.phoneNumberChange.emit(`+${this.selectedDialCode}`);
this.cdRef.detectChanges();
}
}
/**
* Generates the mask pattern for the phone number input based on the selected country.
* @param isoCode The ISO code of the selected country.
* @returns The mask pattern for the phone number.
*/
private getPhoneNumberMask(isoCode: string): string {
try {
const exampleNumber = this.phoneNumberUtil.getExampleNumberForType(isoCode, PhoneNumberType.MOBILE);
if (exampleNumber) {
const formattedExample = this.phoneNumberUtil.format(exampleNumber, PhoneNumberFormat.NATIONAL);
return this.createMaskFromPhoneNumber(formattedExample);
}
return "";
} catch (error) {
return "";
}
}
/**
* Converts a phone number example into a mask pattern.
* @param phoneNumber The example phone number.
* @returns The mask pattern based on the phone number.
*/
private createMaskFromPhoneNumber(phoneNumber: string): string {
let mask = phoneNumber.replace(/d/g, "9");
if (this.selectedDialCode) {
mask = `+${this.selectedDialCode} ${mask}`;
}
return mask;
}
/**
* Converts a mask pattern into a placeholder for the phone number input.
* @param mask The mask pattern for the phone number.
* @returns The placeholder string for the phone number input.
*/
private createPlaceholderFromMask(mask: string): string {
let placeholder = mask.replace(/9/g, "_");
if (this.selectedDialCode) {
const dialCodeLength = this.selectedDialCode.length;
placeholder = `+${this.selectedDialCode}${placeholder.slice(dialCodeLength + 1)}`;
}
return placeholder;
}
/**
* Handles the phone number input event, updating the formatted phone number and validation status.
* @param event The input event from the phone number field.
*/
public onPhoneNumberInput(event: any): void {
const inputElement = event.target as HTMLInputElement;
const inputValue = inputElement.value.trim();
if (this.phoneNumberInputTimer) {
clearTimeout(this.phoneNumberInputTimer);
}
if (!inputValue) {
this.isPhoneNumberValid = true;
this.form.get(this.controlName)?.setValue("");
this.form.get(this.controlName)?.markAsDirty();
this.cdRef.detectChanges();
return;
}
const dialCode = this.extractDialCode(inputValue);
const phoneNumberWithoutDialCode = inputValue.replace(dialCode, "");
this.phoneNumberInputTimer = setTimeout(() => {
const formattedPhoneNumber = this.formatPhoneNumber(phoneNumberWithoutDialCode, true);
this.isPhoneNumberValid = this.validatePhoneNumber(formattedPhoneNumber);
this.form.get(this.controlName)?.setValue(formattedPhoneNumber);
this.form.get(this.controlName)?.markAsDirty();
this.phoneNumberChange.emit(formattedPhoneNumber);
this.cdRef.detectChanges();
}, 500);
const countryCode = this.getCountryCodeFromPhoneNumber(inputValue);
if (countryCode) {
const isoCode = this.phoneNumberUtil.getRegionCodeForCountryCode(parseInt(countryCode));
if (isoCode) {
this.updateCountrySelectionByIsoCode(isoCode);
}
} else {
this.resetToDefaultCountry();
}
}
`
I can see the problem is in the method createPlaceHolder where the mask comes in as: “+91 999999 99999” and the regex sets placeholder to “+_1 ______ _____”.
I tried doing something like if number starts with +, only do the regex after the first space like this:
`
private createPlaceholderFromMask(mask: string): string {
const firstSpaceIndex = mask.indexOf(‘ ‘);
if (firstSpaceIndex !== -1) {
// Replace digits after the first space with underscores
const dialCode = mask.substring(0, firstSpaceIndex + 1); // Include the space
const phoneNumberPart = mask.substring(firstSpaceIndex + 1).replace(/d/g, "_");
return dialCode + phoneNumberPart;
} else {
// If no space is found, fall back to replacing all digits (not typical for valid masks)
return mask.replace(/d/g, "_");
}
}
`
But that also didn’t work – any help would be appreciated!