From dd83fad4f38abf4bc6a1af2ac99506b838dfe6a5 Mon Sep 17 00:00:00 2001 From: kauli sabino Date: Tue, 11 Oct 2022 12:13:27 -0300 Subject: [PATCH 1/5] Add support for custom input formatters --- lib/src/widgets/input_widget.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/widgets/input_widget.dart b/lib/src/widgets/input_widget.dart index 94972bad18..4a75deb30d 100644 --- a/lib/src/widgets/input_widget.dart +++ b/lib/src/widgets/input_widget.dart @@ -80,7 +80,7 @@ class InternationalPhoneNumberInput extends StatefulWidget { final TextAlign textAlign; final TextAlignVertical textAlignVertical; final EdgeInsets scrollPadding; - + final List? inputFormatters; final FocusNode? focusNode; final Iterable? autofillHints; @@ -124,6 +124,7 @@ class InternationalPhoneNumberInput extends StatefulWidget { this.focusNode, this.cursorColor, this.autofillHints, + this.inputFormatters, this.countries}) : super(key: key); @@ -451,6 +452,8 @@ class _InputWidgetView }, ) : FilteringTextInputFormatter.digitsOnly, + if (widget.inputFormatters != null) + ...widget.inputFormatters! ], onChanged: state.onChanged, ), From 4be0101e82ff299268153665e6797499d41cc083 Mon Sep 17 00:00:00 2001 From: kauli sabino Date: Tue, 11 Oct 2022 15:23:28 -0300 Subject: [PATCH 2/5] Add listener to country changes --- .flutter-plugins-dependencies | 2 +- lib/src/models/country_model.dart | 4 ++++ lib/src/utils/formatter/as_you_type_formatter.dart | 4 +++- lib/src/widgets/input_widget.dart | 4 +++- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index 630b9ae1b2..13be946d79 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"libphonenumber","path":"/Users/nathaniel.ogunye/.pub-cache/hosted/pub.dartlang.org/libphonenumber-2.0.2/","native_build":true,"dependencies":[]},{"name":"libphonenumber_plugin","path":"/Users/nathaniel.ogunye/.pub-cache/hosted/pub.dartlang.org/libphonenumber_plugin-0.2.3/","native_build":true,"dependencies":["libphonenumber"]}],"android":[{"name":"libphonenumber","path":"/Users/nathaniel.ogunye/.pub-cache/hosted/pub.dartlang.org/libphonenumber-2.0.2/","native_build":true,"dependencies":[]},{"name":"libphonenumber_plugin","path":"/Users/nathaniel.ogunye/.pub-cache/hosted/pub.dartlang.org/libphonenumber_plugin-0.2.3/","native_build":true,"dependencies":["libphonenumber"]}],"macos":[],"linux":[],"windows":[],"web":[{"name":"libphonenumber_web","path":"/Users/nathaniel.ogunye/.pub-cache/hosted/pub.dartlang.org/libphonenumber_web-0.2.0+1/","dependencies":[]}]},"dependencyGraph":[{"name":"libphonenumber","dependencies":[]},{"name":"libphonenumber_plugin","dependencies":["libphonenumber_web","libphonenumber"]},{"name":"libphonenumber_web","dependencies":[]}],"date_created":"2022-09-21 11:56:42.923067","version":"3.3.0"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"libphonenumber","path":"/opt/flutter/.pub-cache/hosted/pub.dartlang.org/libphonenumber-2.0.2/","native_build":true,"dependencies":[]},{"name":"libphonenumber_plugin","path":"/opt/flutter/.pub-cache/hosted/pub.dartlang.org/libphonenumber_plugin-0.2.3/","native_build":true,"dependencies":["libphonenumber"]}],"android":[{"name":"libphonenumber","path":"/opt/flutter/.pub-cache/hosted/pub.dartlang.org/libphonenumber-2.0.2/","native_build":true,"dependencies":[]},{"name":"libphonenumber_plugin","path":"/opt/flutter/.pub-cache/hosted/pub.dartlang.org/libphonenumber_plugin-0.2.3/","native_build":true,"dependencies":["libphonenumber"]}],"macos":[],"linux":[],"windows":[],"web":[{"name":"libphonenumber_web","path":"/opt/flutter/.pub-cache/hosted/pub.dartlang.org/libphonenumber_web-0.2.0+1/","dependencies":[]}]},"dependencyGraph":[{"name":"libphonenumber","dependencies":[]},{"name":"libphonenumber_plugin","dependencies":["libphonenumber_web","libphonenumber"]},{"name":"libphonenumber_web","dependencies":[]}],"date_created":"2022-10-11 12:06:09.311884","version":"3.3.0"} \ No newline at end of file diff --git a/lib/src/models/country_model.dart b/lib/src/models/country_model.dart index 3806e21d8e..e7aafcc883 100644 --- a/lib/src/models/country_model.dart +++ b/lib/src/models/country_model.dart @@ -18,6 +18,8 @@ class Country { /// The flagUri which links to the flag for the [Country] in the library assets final String flagUri; + final int? numCode; + /// The nameTranslation for translation final Map? nameTranslations; @@ -27,6 +29,7 @@ class Country { required this.alpha3Code, required this.dialCode, required this.flagUri, + this.numCode, this.nameTranslations, }); @@ -36,6 +39,7 @@ class Country { name: data['en_short_name'], alpha2Code: data['alpha_2_code'], alpha3Code: data['alpha_3_code'], + numCode: int.tryParse(data['num_code'] ?? ''), dialCode: data['dial_code'], flagUri: 'assets/flags/${data['alpha_2_code'].toLowerCase()}.png', nameTranslations: data['nameTranslations'] != null diff --git a/lib/src/utils/formatter/as_you_type_formatter.dart b/lib/src/utils/formatter/as_you_type_formatter.dart index da96ffa330..49bd5abb65 100644 --- a/lib/src/utils/formatter/as_you_type_formatter.dart +++ b/lib/src/utils/formatter/as_you_type_formatter.dart @@ -99,7 +99,9 @@ class AsYouTypeFormatter extends TextInputFormatter { Future formatAsYouType({required String input}) async { try { String? formattedPhoneNumber = await PhoneNumberUtil.formatAsYouType( - phoneNumber: input, isoCode: isoCode); + phoneNumber: input, + isoCode: isoCode, + ); return formattedPhoneNumber; } on Exception { return ''; diff --git a/lib/src/widgets/input_widget.dart b/lib/src/widgets/input_widget.dart index 4a75deb30d..76d34cf5ac 100644 --- a/lib/src/widgets/input_widget.dart +++ b/lib/src/widgets/input_widget.dart @@ -83,13 +83,14 @@ class InternationalPhoneNumberInput extends StatefulWidget { final List? inputFormatters; final FocusNode? focusNode; final Iterable? autofillHints; - + final ValueChanged? onCountryChanged; final List? countries; InternationalPhoneNumberInput( {Key? key, this.selectorConfig = const SelectorConfig(), required this.onInputChanged, + this.onCountryChanged, this.onInputValidated, this.onSubmit, this.onFieldSubmitted, @@ -339,6 +340,7 @@ class _InputWidgetState extends State { /// Changes Selector Button Country and Validate Change. void onCountryChanged(Country? country) { + widget.onCountryChanged?.call(country); setState(() { this.country = country; }); From 8970ea053d9646af9cbcbb74d9cee4825df3534f Mon Sep 17 00:00:00 2001 From: kauli sabino Date: Tue, 11 Oct 2022 16:37:38 -0300 Subject: [PATCH 3/5] Add numCode to Phone number --- lib/src/models/country_model.dart | 1 + lib/src/utils/phone_number.dart | 5 +++-- lib/src/widgets/input_widget.dart | 16 ++++++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/src/models/country_model.dart b/lib/src/models/country_model.dart index e7aafcc883..ceed4d203a 100644 --- a/lib/src/models/country_model.dart +++ b/lib/src/models/country_model.dart @@ -65,5 +65,6 @@ class Country { 'alpha2: $alpha2Code, ' 'alpha3: $alpha3Code, ' 'dialCode: $dialCode ' + 'numCode: $numCode ' '}'; } diff --git a/lib/src/utils/phone_number.dart b/lib/src/utils/phone_number.dart index a8393f330d..1e3b98af9c 100644 --- a/lib/src/utils/phone_number.dart +++ b/lib/src/utils/phone_number.dart @@ -32,7 +32,7 @@ class PhoneNumber extends Equatable { /// Country [isoCode] of the phone number final String? isoCode; - + final int? numCode; /// [_hash] is used to compare instances of [PhoneNumber] object. final int _hash; @@ -46,12 +46,13 @@ class PhoneNumber extends Equatable { PhoneNumber({ this.phoneNumber, this.dialCode, + this.numCode, this.isoCode, }) : _hash = 1000 + Random().nextInt(99999 - 1000); @override String toString() { - return 'PhoneNumber(phoneNumber: $phoneNumber, dialCode: $dialCode, isoCode: $isoCode)'; + return 'PhoneNumber(phoneNumber: $phoneNumber, dialCode: $dialCode, isoCode: $isoCode, numCode: $numCode)'; } /// Returns [PhoneNumber] which contains region information about diff --git a/lib/src/widgets/input_widget.dart b/lib/src/widgets/input_widget.dart index 76d34cf5ac..8db0340b8a 100644 --- a/lib/src/widgets/input_widget.dart +++ b/lib/src/widgets/input_widget.dart @@ -237,10 +237,14 @@ class _InputWidgetState extends State { '${this.country?.dialCode}$parsedPhoneNumberString'; if (widget.onInputChanged != null) { - widget.onInputChanged!(PhoneNumber( + widget.onInputChanged!( + PhoneNumber( phoneNumber: phoneNumber, + numCode: this.country?.numCode, isoCode: this.country?.alpha2Code, - dialCode: this.country?.dialCode)); + dialCode: this.country?.dialCode, + ), + ); } if (widget.onInputValidated != null) { @@ -249,10 +253,14 @@ class _InputWidgetState extends State { this.isNotValid = true; } else { if (widget.onInputChanged != null) { - widget.onInputChanged!(PhoneNumber( + widget.onInputChanged!( + PhoneNumber( phoneNumber: phoneNumber, + numCode: this.country?.numCode, isoCode: this.country?.alpha2Code, - dialCode: this.country?.dialCode)); + dialCode: this.country?.dialCode, + ), + ); } if (widget.onInputValidated != null) { From 1ab540ba3bf6559b6212e392e63503f677e48d82 Mon Sep 17 00:00:00 2001 From: kauli sabino Date: Tue, 11 Oct 2022 17:11:30 -0300 Subject: [PATCH 4/5] Implements method to get formatted area code --- lib/src/models/country_model.dart | 4 ++-- lib/src/utils/phone_number.dart | 6 +++++- lib/src/widgets/input_widget.dart | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/src/models/country_model.dart b/lib/src/models/country_model.dart index ceed4d203a..a909d87841 100644 --- a/lib/src/models/country_model.dart +++ b/lib/src/models/country_model.dart @@ -18,7 +18,7 @@ class Country { /// The flagUri which links to the flag for the [Country] in the library assets final String flagUri; - final int? numCode; + final String? numCode; /// The nameTranslation for translation final Map? nameTranslations; @@ -39,7 +39,7 @@ class Country { name: data['en_short_name'], alpha2Code: data['alpha_2_code'], alpha3Code: data['alpha_3_code'], - numCode: int.tryParse(data['num_code'] ?? ''), + numCode: data['num_code'], dialCode: data['dial_code'], flagUri: 'assets/flags/${data['alpha_2_code'].toLowerCase()}.png', nameTranslations: data['nameTranslations'] != null diff --git a/lib/src/utils/phone_number.dart b/lib/src/utils/phone_number.dart index 1e3b98af9c..3740d5ef00 100644 --- a/lib/src/utils/phone_number.dart +++ b/lib/src/utils/phone_number.dart @@ -32,7 +32,7 @@ class PhoneNumber extends Equatable { /// Country [isoCode] of the phone number final String? isoCode; - final int? numCode; + final String? numCode; /// [_hash] is used to compare instances of [PhoneNumber] object. final int _hash; @@ -50,6 +50,10 @@ class PhoneNumber extends Equatable { this.isoCode, }) : _hash = 1000 + Random().nextInt(99999 - 1000); + String? getFormattedNumCode() { + return phoneNumber?.trim().substring(0, numCode?.length ?? 0); + } + @override String toString() { return 'PhoneNumber(phoneNumber: $phoneNumber, dialCode: $dialCode, isoCode: $isoCode, numCode: $numCode)'; diff --git a/lib/src/widgets/input_widget.dart b/lib/src/widgets/input_widget.dart index 8db0340b8a..815b5b3900 100644 --- a/lib/src/widgets/input_widget.dart +++ b/lib/src/widgets/input_widget.dart @@ -367,6 +367,7 @@ class _InputWidgetState extends State { PhoneNumber( phoneNumber: phoneNumber, isoCode: this.country?.alpha2Code, + numCode: this.country?.numCode, dialCode: this.country?.dialCode), ); } From 3ab72027b2d76395f1a4c42e7bd15d5a2991906e Mon Sep 17 00:00:00 2001 From: kauli sabino Date: Tue, 11 Oct 2022 18:42:04 -0300 Subject: [PATCH 5/5] Fix formatted num code --- lib/src/utils/phone_number.dart | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/src/utils/phone_number.dart b/lib/src/utils/phone_number.dart index 3740d5ef00..c654c40a9d 100644 --- a/lib/src/utils/phone_number.dart +++ b/lib/src/utils/phone_number.dart @@ -51,7 +51,22 @@ class PhoneNumber extends Equatable { }) : _hash = 1000 + Random().nextInt(99999 - 1000); String? getFormattedNumCode() { - return phoneNumber?.trim().substring(0, numCode?.length ?? 0); + final phoneWithoutDialCode = phoneNumber?.trim() + .replaceAll(RegExp('[^0-9]'), '') + .replaceFirst(dialCode?.replaceAll(RegExp('[^0-9]'), '') ?? '', ''); + if ((phoneWithoutDialCode?.length ?? 0) < (dialCode?.length ?? 0)) { + return phoneWithoutDialCode + ?.substring(0, phoneWithoutDialCode.length); + } + return phoneWithoutDialCode + ?.substring(0, numCode?.length ?? 0); + } + + String? getFormattedPhone() { + return phoneNumber?.trim() + .replaceAll(RegExp('[^0-9]'), '') + .replaceFirst(dialCode?.replaceAll(RegExp('[^0-9]'), '') ?? '', '') + .replaceFirst(getFormattedNumCode() ?? '', ''); } @override