ngx-phone-field
Version:
An Angular directive for international phone input with country flag dropdowns.
250 lines (210 loc) • 24.8 kB
Markdown
# ngx-phone-field
`ngx-phone-field` is an Angular directive that provides international phone input with country flag dropdowns. It integrates with Angular forms, supporting both Reactive Forms and Template-Driven Forms.
## Table of Contents
1. [Features](#features)
2. [Version Compatibility](#version-compatibility)
3. [Installation](#installation)
- [Include Required Styles](#include-required-styles)
4. [Usage](#usage)
- [Standalone Directive and Example with Reactive Forms](#standalone-directive-and-example-with-reactive-forms)
- [Standalone Directive and Example with Template-Driven Forms](#standalone-directive-and-example-with-template-driven-forms)
5. [Configuration Options](#configuration-options)
6. [Instance Methods and Properties](#instance-methods-and-properties)
- [Static Methods](#static-methods)
- [Events](#events)
7. [Loading The Utilities Script](#loading-the-utilities-script)
8. [Development](#development)
9. [License](#license)
## Features
- International phone input field with country code selection.
- Supports `intl-tel-input` functionalities such as number validation, formatting, and placeholder management.
- Works with both Reactive Forms and Template-Driven Forms.
- Customizable via configuration options.
## Version Compatibility
| ngx-phone-field Version | Supported Angular Versions |
|------------------------------|-------------------------------------------|
| v3.x.x | Angular 19 |
| v2.x.x | Angular 15 to Angular 18 (inclusive) |
| v1.x.x | Angular 10 to Angular 14 (inclusive) |
## Installation
```bash
npm install ngx-phone-field intl-tel-input
```
### Include Required Styles
In order for the phone input field to render correctly with flags and dropdown styles, you need to include the required CSS file in your angular.json:
* Open your `angular.json` file.
* Add the `intl-tel-input` styles to the styles array in `angular.json`:
```json
{
"projects": {
"your-app": {
"architect": {
"build": {
"options": {
"styles": [
"src/styles.css",
"node_modules/intl-tel-input/build/css/intlTelInput.css"
]
}
}
}
}
}
}
```
## Usage
`ngxPhoneField` directive returns the full `intl-tel-input` instance when the input changes. This gives the access to all the methods and properties available in the `intl-tel-input` API, providing full flexibility for advanced use cases.
### Standalone directive and Example with Reactive Forms
```typescript
import { Component } from '@angular/core';
import { FormGroup, FormControl, ReactiveFormsModule } from '@angular/forms';
import { NgxPhoneField } from 'ngx-phone-field';
@Component({
selector: 'app-phone-form',
standalone: true,
template: `
<form [formGroup]="phoneForm">
<label for="phone">Phone Number</label>
<input
type="tel"
id="phone"
formControlName="phone"
ngxPhoneField
[ngxPhoneFieldParams]="params"
/>
</form>
`,
imports: [ReactiveFormsModule, NgxPhoneField]
})
export class PhoneFormComponent {
phoneForm = new FormGroup({
phone: new FormControl(''),
});
params = {
initialCountry: 'us',
allowDropdown: true,
formatAsYouType: true,
// @ts-ignore
loadUtilsOnInit: async () => import('intl-tel-input/utils'), // load utils script for formatting and validation
};
handleSubmit() {
const phoneControlValue = this.phoneForm.get('phone').value;
console.log(phoneControlValue); // Iti instance
}
}
```
### Standalone directive and Example with Template-Driven Forms
```typescript
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { NgxPhoneField } from 'ngx-phone-field';
@Component({
selector: 'app-template-phone-form',
standalone: true,
template: `
<form #phoneForm="ngForm">
<label for="phone">Phone Number</label>
<input
type="tel"
id="phone"
name="phone"
[(ngModel)]="phone"
ngxPhoneField
[ngxPhoneFieldParams]="params"
required
/>
</form>
<button (click)="logInstance()">Log Instance</button>
`,
imports: [FormsModule, NgxPhoneField]
})
export class TemplatePhoneFormComponent {
public phone: string = '';
params = {
initialCountry: 'us',
allowDropdown: true,
formatAsYouType: true,
// @ts-ignore
loadUtilsOnInit: async () => import('intl-tel-input/utils'), // load utils script for formatting and validation
};
logInstance() {
console.log(this.phone) // Iti instance
}
}
```
## Configuration Options
You can pass various options to configure the behavior of the phone input field through `ngxPhoneFieldParams`. The `ngxPhoneFieldParams` input accepts a configuration object, which includes all the properties from `intl-tel-input`. You can refer to the full list of properties in the `Initialisation Options` section [here](https://www.npmjs.com/package/intl-tel-input) or see them below:
.
| Option | Type | Default | Description |
|--------------------------|--------------------------------------|------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `allowDropdown` | Boolean | true | Whether or not to allow the dropdown. If disabled, the selected country is not clickable, and the flag appears on the right. If `separateDialCode` is enabled, `allowDropdown` is forced to true. |
| `autoPlaceholder` | String | "polite" | Set the input's placeholder to an example number for the selected country. You can specify the number type using `placeholderNumberType`. Requires the utils script to be loaded. |
| `containerClass` | String | "" | Additional classes to add to the wrapper `<div>`. |
| `countryOrder` | Array | null | Specify the order of the country list using an array of ISO2 country codes. Any omitted countries will appear after the specified ones. |
| `countrySearch` | Boolean | true | Add a search input to the top of the dropdown to filter the displayed countries. |
| `customPlaceholder` | Function | null | Change the placeholder generated by `autoPlaceholder`. The function must return a string. Example: `customPlaceholder: (placeholder, countryData) => "e.g. " + placeholder`. |
| `dropdownContainer` | Node | null | Instead of placing the country dropdown markup next to the input, append it to the specified node (e.g., `document.body`). Useful when the input is inside a container with `overflow: hidden`. |
| `excludeCountries` | Array | [] | Display all countries except the ones specified in this array. |
| `fixDropdownWidth` | Boolean | true | Fix the dropdown width to match the input width. |
| `formatAsYouType` | Boolean | true | Automatically format the number as the user types. Requires the utils script to be loaded. |
| `formatOnDisplay` | Boolean | true | Format the input value during initialization and on `setNumber`. Requires the utils script to be loaded. |
| `geoIpLookup` | Function | null | Custom function for IP lookup services to get the user's location and return the relevant country code. Requires setting `initialCountry` to `auto`. |
| `hiddenInput` | Function | null | Allows creating hidden input fields within a form to store the full international number and country code. This requires the input to be inside a form and the utils script to be loaded. |
| `i18n` | Object | {} | Localize or customize the country names and other user interface text. You can import predefined translations or provide your own custom translations. |
| `initialCountry` | String | "" | Set the initial country selection using the country code (e.g., `"us"` for the United States). Can also be set to `"auto"` for automatic IP-based country detection. |
| `loadUtilsOnInit` | String or () => Promise<module> | "" | URL to the utils.js script for formatting/validation. It can also be a function returning a promise. Example: `{ loadUtilsOnInit: () => import("intl-tel-input/utils") }`. |
| `nationalMode` | Boolean | true | Format numbers in the national format rather than the international format. This applies to placeholder numbers and when displaying existing numbers. |
| `onlyCountries` | Array | [] | In the dropdown, display only the countries specified in this array. |
| `placeholderNumberType` | String | "MOBILE" | Set the number type for the placeholder (e.g., `"FIXED_LINE"`). |
| `showFlags` | Boolean | true | Show or hide the country flags. If set to `false`, a globe icon will be displayed instead of the flags. |
| `separateDialCode` | Boolean | false | Display the selected country's dial code next to the input field. Automatically opens the country dropdown if the user types a new dial code. |
| `strictMode` | Boolean | false | As the user types, ignore irrelevant characters and cap the input to the maximum valid number length. Requires the utils script to be loaded. |
| `useFullscreenPopup` | Boolean | true (on mobile) | Show the country list as a fullscreen popup on mobile devices and as an inline dropdown on larger devices. |
| `utilsScript` | String or () => Promise<module> | "" | ⚠️ **Deprecated**. Use `loadUtilsOnInit` instead. |
| `validationNumberType` | String | "MOBILE" | Set the number type to enforce during validation with `isValidNumber` and number length enforcement with `strictMode`.
## Instance Methods and Properties
Once you initialize the `ngxPhoneField`, the directive returns an instance of `intl-tel-input` with the following methods and properties:
| Method | Description |
|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `destroy()` | Removes the plugin from the input and unbinds all event listeners. |
| `getExtension()` | Returns the extension from the current number. Requires the utils script to be loaded. Example: if the input value is `"(702) 555-5555 ext. 1234"`, this will return `"1234"`. |
| `getNumber(format?)` | Gets the current number in the specified format. Defaults to E.164 format. Formats are available in `intlTelInput.utils.numberFormat`. Example: `iti.getNumber(intlTelInput.utils.numberFormat.E164)` returns a string like `"+17024181234"`. Requires utils script. |
| `getNumberType()` | Returns the type of the current number (fixed-line/mobile/toll-free, etc.). Requires the utils script to be loaded. Example: `iti.getNumberType()` returns an integer matched against `intlTelInput.utils.numberType`. |
| `getSelectedCountryData()` | Returns the country data for the currently selected country, e.g., `{ name: "Afghanistan", iso2: "af", dialCode: "93" }`. |
| `getValidationError()` | Returns information about a validation error. Example: `iti.getValidationError()` returns an integer matched against `intlTelInput.utils.validationError`. |
| `isValidNumber()` | Returns `true` or `false` based on whether the current number is valid (based on length). It respects the `validationNumberType` option (set to `"MOBILE"` by default). Requires utils script. |
| `isValidNumberPrecise()` | Returns `true` or `false` for more precise validation using detailed matching rules for each country/area code. This is more accurate but requires the plugin to be up-to-date. Requires the utils script. |
| `setCountry(countryCode)` | Changes the selected country. Example: `iti.setCountry("gb")`. This method automatically updates when calling `setNumber` with a full international number. |
| `setNumber(number)` | Inserts a number into the input and updates the selected country accordingly. If `formatOnDisplay` is enabled, it formats the number based on `nationalMode`. Example: `iti.setNumber("+447733123456")`. |
| `setPlaceholderNumberType(type)` | Changes the `placeholderNumberType` option. Example: `iti.setPlaceholderNumberType("FIXED_LINE")`. |
| `setDisabled(isDisabled)` | Sets the disabled attribute of both the input field and the selected country button. Example: `iti.setDisabled(true)`. |
### Static Methods
| Method | Description |
|-------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `getCountryData()` | Retrieves the plugin's country data, which can be reused elsewhere or modified before initialization. Example: `intlTelInput.getCountryData()` returns an array of country objects. |
| `getInstance(input)` | After initializing the plugin, access the instance again by passing in the input element. Example: `const iti = intlTelInput.getInstance(input); iti.isValidNumber();`. |
| `loadUtils()` | Manually loads the utils.js script. Can be useful for enabling formatting/validation on demand. Returns a `Promise` that can be handled with `.then()`. Example: `intlTelInput.loadUtils("/build/js/utils.js")`. |
### Events
| Event | Description |
|-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `countrychange` | Triggered when the selected country is updated (e.g., user selects a country from the dropdown, types a new dial code, or `setCountry` is called). Example: `input.addEventListener("countrychange", () => { iti.getSelectedCountryData(); });`. |
| `open:countrydropdown` | Triggered when the user opens the dropdown. |
| `close:countrydropdown` | Triggered when the user closes the dropdown. |
## Loading The Utilities Script
Enabling formatting and validation for phone numbers requires the `utils.js` script. Make sure to include this in your project to fully enable these features. For more information, you can refer to the [official documentation](https://www.npmjs.com/package/intl-tel-input) - Loading The Utilities Script section.
## Development
If you want to contribute or modify the package, follow these steps:
* Fork the repository to your own GitHub account.
* Clone your forked repository locally:
```bash
git clone https://github.com/alex-mirankov/ngx-phone-field.git
```
* Run `npm install` to install dependencies.
* Run `ng build ngx-phone-field` to build the project.
* Run `ng serve intl-tel-demo` to run the demo project and see your changes in action (if applicable).
* Make changes to the codebase.
* Test your changes thoroughly before submitting.
* Create a pull request from your fork to the original repository.
* Pass the code review and ensure your changes meet the project's contribution guidelines.
## License
This project is licensed under the MIT License. See the LICENSE file for more information.