intl_mobile_field logo

MIT License pub version


A customized Flutter TextFormField to input an international Mobile number along with the country code.

intl_mobile_field is a powerful and flexible Flutter package designed to handle international phone number input easily. It offers advanced features, improved compatibility, and enhanced customization options to meet modern development needs. Visit the Changelog to stay updated on the latest additions and improvements.

Installing

To use this package:

Run this command:

flutter pub add intl_mobile_field

Or, add the following to your pubspec.yaml file under dependencies:

intl_mobile_field: ^2.1.7

Sometimes you may want to use the latest version of the package, instead of a published version. To do that, use the git syntax:

dependencies:
  intl_mobile_field:
    git:
      url: https://github.com/MdAshrafUllah/intl_mobile_field.git
      ref: master

How to Use

import the url

import 'package:intl_mobile_field/intl_mobile_field.dart';

For FlagsDropDown you have to import.

import 'package:intl_mobile_field/flags_drop_down.dart';

Simply create a IntlMobileField widget, and pass the required params:

Example: 1 (without favorite)

IntlMobileField(
  initialCountryCode: 'BD', // initial Country is Bangladesh
  languageCode: "en", // initial language is English
  decoration: const InputDecoration(
    labelText: 'Mobile Number',
    border: OutlineInputBorder(
      borderSide: BorderSide(),
    ),
  ),
  disableLengthCounter: true,
),

output

Screenshot 1 Screenshot 2

Example: 2 (Custom Mobile Field)

Row(
  spacing: 10,
  children: [
    Container(
      height: 48,
      decoration: BoxDecoration(
        border: Border.all(width: 0.6, color: Colors.black87),
        borderRadius: BorderRadius.circular(4.0),
      ),
      child: CountryDropDown(
        countries: countries,
        onCountryChanged: (value) {
          setState(() {
            countryCode = value.dialCode;
          });
        },
      ),
    ),
    Expanded(
      child: TextFormField(
        controller: mobileControllerSeparate,
        decoration: InputDecoration(
          labelText: t('mobileNumber'),
          border: const OutlineInputBorder(),
          alignLabelWithHint: true,
        ),
        onChanged: (value) {
          log("Mobile: $countryCode$value");
        },
      ),
    ),
  ],
),

output

Screenshot 11

Example: 3 (with favorite - style one)

IntlMobileField(
  favorite: const ['BD', 'US', 'MY'],
  favoriteIcon: Icon(
    Icons.star,
    color: Colors.amber,
  ),
  favoriteIconPosition: Position.trailing,
  favoriteCountryCodePosition: Position.trailing,
  initialCountryCode: 'BD',
  languageCode: "en", // default is 'en'
  onCountryChanged: (country) {
    log('Country changed to: ${country.name}');
  },
  decoration: const InputDecoration(
    labelText: 'Mobile Number',
    border: OutlineInputBorder(
      borderSide: BorderSide(),
    ),
  ),
  disableLengthCounter: true,
  onChanged: (mobile) {
    log(mobile.completeNumber);
  },
),

output

Screenshot 1 Screenshot 6 Screenshot 5

Example: 4 (with favorite - style two)

IntlMobileField(
  favorite: const ['BD', 'US', 'MY'],
  favoriteIcon: Icon(
    Icons.favorite,
    color: Colors.pinkAccent,
  ),
  favoriteIconPosition: Position.trailing,
  initialCountryCode: 'BD',
  languageCode: "en", // default is 'en'
  onCountryChanged: (country) {
    log('Country changed to: ${country.name}');
  },
  decoration: const InputDecoration(
    labelText: 'Mobile Number',
    border: OutlineInputBorder(
      borderSide: BorderSide(),
    ),
  ),
  disableLengthCounter: true,
  onChanged: (mobile) {
    log(mobile.completeNumber);
  },
),

output

Screenshot 1 Screenshot 4

Use initialCountryCode to set an initial Country Code.

For PickerDialogStyle you have to import.

import 'package:intl_mobile_field/country_picker_dialog.dart';

Example 5 (CountryDropDown)

CountryDropDown(
    countries: countries,
    showFieldCountryFlag:
        true, // default is true, if You want to hide country flag, set it to false
    showDialogCountryFlag:
        false, // default is true, if You want to hide country flag in dialog box, set it to false
    showCountryName:
        false, // default is true. if You want to show country name, set it to false
    onCountryChanged: (country) {
    debugPrint('Country changed to: ${country.name}');
    },
    flagWidth: 150,
)

Output

Screenshot 9 Screenshot 10

Example 6 (Validation Message)

When you want to show a invalid Number message you can pass it through invalidNumberMessage

IntlMobileField(
  decoration: InputDecoration(
    labelText: "Mobile Number",
    border: OutlineInputBorder(),
  ),
  invalidNumberMessage: "Enter a Valid Number",
),

Output

Screenshot 12

Example 7 (Custom Validation)

you can add your own validation message.

IntlMobileField(
  initialCountryCode: "BD",
  decoration: InputDecoration(
    labelText: "Mobile Number",
    border: OutlineInputBorder(),
  ),
  invalidNumberMessage:
      "Enter a Valid Number", // fallback error message
  validator: (mobileNumber) {
    if (mobileNumber == null || mobileNumber.number.isEmpty) {
      return 'Please enter a mobile number';
    }
    if (!RegExp(r'^[0-9]+$').hasMatch(mobileNumber.number)) {
      return 'Only digits are allowed';
    }
    return null;
  },
),

Output

Screenshot 13 Screenshot 14

Example 8 (Custom Country List)

By default, all countries are available.

Use the countries property to control which countries appear:

Allow only specific countries (default behavior):

IntlMobileField(
  initialCountryCode: "BD",
  decoration: const InputDecoration(
    labelText: "Mobile Number",
    border: OutlineInputBorder(),
  ),
  countries: ['BD', 'MY', 'US', 'AE', 'UK', 'NL'], // or ['880', '60', '971']
)

Exclude specific countries:

IntlMobileField(
  initialCountryCode: "BD",
  decoration: const InputDecoration(
    labelText: "Mobile Number",
    border: OutlineInputBorder(),
  ),
  countries: ['IL'],
  excludeCountries: true,
)

In the second example, all countries will be available except Israel (IL).

Output

Dial Code Country Code Except Country
Dial Code Screenshot Country Code Screenshot Except Country Screenshot

Search By

Control how users can search for countries in the picker dialog.

Use searchBy to choose the search behavior.

  • SearchBy.name searches by country name only.
  • SearchBy.dialCode searches by country dial code only (for example: 880 or +880).
  • SearchBy.both (default) searches by both country name and dial code.

Example

IntlMobileField(
  searchBy: SearchBy.both,
)

Available Options

Value Description
SearchBy.name Search by country name only.
SearchBy.dialCode Search by country dial code only.
SearchBy.both Search by both country name and dial code (default).

Output

SearchBy.name SearchBy.dialCode SearchBy.dialCode (without '+')
SearchBy.name Screenshot SearchBy.dialCode Screenshot SearchBy.dialCode (without '+') Screenshot

Note: SearchBy.both is the default behavior, so you only need to set searchBy if you want to restrict the search.

RTL Support

If you select languageCode Arabic, Urdu, Persian, or Cantonese (Chinese), the flag will automatically be on the right, and the country code will automatically be on the left. You can also turn off RLT Support by adding rltSupport: false.

output

LRT Languages RLT Language
LRT Languages Screenshot 1 RLT Language Screenshot 1
LRT Languages Screenshot 2 RLT Language Screenshot 2

Supported Languages

We support more than 26 languages, including:

No Code Language No Code Language
01huHungarian 15arArabic
02skSlovak 16faPersian
03seSwedish 17yueCantonese (Chinese)
04plPolish 18bdBangla (Bangladesh)
05noNorwegian 19inHindi (India)
06jaJapanese 20urUrdu (Pakistan)
07itItalian 21pt_brBrazilian Portuguese
08zhSimplified Chinese 22sr_cyrlSerbian (Cyrillic)
09nlDutch 23sr_latnSerbian (Latin)
10deGerman 24zh_twTraditional Chinese
11frFrench 25trTurkish
12esSpanish 26roRomanian
13enEnglish 27ptPortuguese
14viVietnamese

Enjoy multilingual support with easy-to-read formatting!

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

Comment on Issue or Pull Request.

Maintainers

LICENSE

This project is licensed under the MIT license. See LICENSE for more information.

Support the Package

If you find this package helpful, please consider sharing it with your friends, teammates, or the Flutter community.

Your support helps the package reach more developers and motivates me to keep improving it.

Thank you for your love and support! 💙