Skip to content

Commit

Permalink
fix: match area codes or priority when determining country code
Browse files Browse the repository at this point in the history
* Suggesting this basic solution to check the area codes when determining the country code.

Why: When the phone number control value is set programatically, eg. when a record is read and the
control is populated with the phone number so that it can be edited, the area codes were NOT taken
into consideration when attempting to determine the country code.

For example, when I programmatically set the value of the control with a US phone number,
eg. +19781234567 the country returned was American Samoa (+1 684).

* Suggesting a check of the country 'priority'.

Why: To ensure that the highest priority country is associated with any country code that is
utilized by multiple countries, eg. +39 is shared by Italy and Vatican City. I'm not sure how to
can figure out which country was used when the phone number was created. The phone numbers,
eg. +39 312 345 6789 do NOT contain any 'priority' info.

* Suggesting adding the country name is displayed on hover.

Why: The country name could be useful to user unfamiliar with the selected flag and the hover
tooltip is the quickest and easiest way to provide that information.

These changes would go a long way to help me adopt using the component I my project.
While I have tinkered with the code, and offered some basic solutions, please don't hestitate to
make different, better changes (perhaps make the tooltip configurable) yourself that might support
the needs described above.

I added an input field to the test application for testing that programmatically setting the
component value returns the correct country code based on country and area code.

Please let me know if you have any questions or concerns.
  • Loading branch information
Glen Hollingworth committed Aug 14, 2024
1 parent 2ce2072 commit 1e0e003
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 17 deletions.
5 changes: 5 additions & 0 deletions apps/ngx-material-intl-tel-input/src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<section>
<form [formGroup]="formTestGroup" (ngSubmit)="onSubmit()">
<mat-form-field>
<mat-label>Set phone number</mat-label>
<input matInput type="text" formControlName="setPhoneTextbox" />
</mat-form-field>
<button mat-flat-button (click)="setPhone()">Set phone number</button>
<ngx-material-intl-tel-input
(currentValue)="getValue($event)"
fieldControlName="phone"
Expand Down
15 changes: 13 additions & 2 deletions apps/ngx-material-intl-tel-input/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
} from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatChipsModule } from '@angular/material/chips';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { RouterModule } from '@angular/router';
import { NgxMaterialIntlTelInputComponent } from 'ngx-material-intl-tel-input';

Expand All @@ -17,7 +19,9 @@ import { NgxMaterialIntlTelInputComponent } from 'ngx-material-intl-tel-input';
RouterModule,
ReactiveFormsModule,
MatButtonModule,
MatChipsModule
MatChipsModule,
MatFormFieldModule,
MatInputModule
],
selector: 'ngx-material-intl-tel-input-root',
templateUrl: './app.component.html',
Expand All @@ -32,7 +36,8 @@ export class AppComponent {

constructor(private fb: FormBuilder) {
this.formTestGroup = this.fb.group({
phone: ['', [Validators.required]]
phone: ['', [Validators.required]],
setPhoneTextbox: ['']
});
}

Expand All @@ -51,4 +56,10 @@ export class AppComponent {
onSubmit(): void {
this.submittedPhoneValue.set(this.formTestGroup.value['phone']);
}

setPhone(): void {
this.formTestGroup.controls['phone'].setValue(
this.formTestGroup.value['setPhoneTextbox']
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
[formGroup]="telForm"
[ngClass]="{ 'is-focused': isFocused() }"
>
<mat-form-field appearance="fill" class="prefix-form-field">
<mat-form-field
appearance="fill"
class="prefix-form-field"
matTooltip="{{ prefixCtrl.value?.name }}"
>
<mat-select
formControlName="prefixCtrl"
[placeholder]="(!isLoading() && textLabels().codePlaceholder) || ''"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { GeoData } from '../types/geo.type';
import { TextLabels } from '../types/text-labels.type';
import { CountryISO } from '../enums/country-iso.enum';
import { CountryDataService } from '../services/country-data/country-data.service';
import { MatTooltipModule } from '@angular/material/tooltip';

@Component({
selector: 'ngx-material-intl-tel-input',
Expand All @@ -54,6 +55,7 @@ import { CountryDataService } from '../services/country-data/country-data.servic
NgClass,
MatFormFieldModule,
MatInputModule,
MatTooltipModule,
NgTemplateOutlet
],
providers: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,35 @@ export default class TelValidators {
return null;
}

const parsed = phoneNumberUtil.parse(
control.value,
telForm?.value?.prefixCtrl?.iso2
);
// NOTE: the PhoneNumberUtil.parse() method does NOT appear to correctly parse phone numbers with
// country codes which include the 'area code' eg. Dominica (+1767), Grenada (+1473), etc.
// Instead, the returned phone number is for the US (+1) country code.
const parsed = phoneNumberUtil.parse(control.value);

const setPrefixControlValue = (
countryCode: string | number | undefined,
allCountries: Country[],
telForm: FormGroup
) => {
const country = allCountries.find(
(c) => c.dialCode === countryCode?.toString()
);
const country = allCountries.find((c) => {
if (c.dialCode === countryCode?.toString()) {
if (c.areaCodes) {
// Checking the area codes only works because the countries using the same country code as the
// US (+1) and UK (+44) are ALL defined earlier in the list of all countries (country-code.ts)
// and are checked before defaulting to the US or UK (which are defined without area codes and
// have the highest priority (0)).
return c.areaCodes?.find((ac) =>
parsed.getNationalNumber()?.toString().startsWith(ac)
);
} else if (c.priority === 0) {
// If a country does NOT have any area codes but shares a country code with another country,
// return the country with the highest priority (0), eg. country code '599' belongs to both
// 'Carribean Netherlands' (priority 1) and 'Curaçao' (priority 0).
return c;
}
}
return undefined;
});
if (country && country.iso2 !== telForm?.value?.prefixCtrl?.iso2) {
telForm.get('prefixCtrl')?.setValue(country, { emitEvent: false });
}
Expand All @@ -52,13 +68,7 @@ export default class TelValidators {
?.setValue(formattedOnlyNumber, { emitEvent: false });

const isValidNumber = phoneNumberUtil.isValidNumber(parsed);
if (
parsed.getCountryCode() &&
parsed.getCountryCode()?.toString() !==
telForm?.value?.prefixCtrl?.dialCode
) {
setPrefixControlValue(parsed.getCountryCode(), allCountries, telForm);
}
setPrefixControlValue(parsed.getCountryCode(), allCountries, telForm);
if (!isValidNumber) {
control.setErrors({ invalidNumber: true });
telForm.get('numberControl')?.setErrors({ invalidNumber: true });
Expand Down

0 comments on commit 1e0e003

Please sign in to comment.