Skip to content

Commit

Permalink
fix: #270 allow deleting area codes
Browse files Browse the repository at this point in the history
Formatting of the entered number is now skipped if the text input is within an area code, such as (416 and the closing parentheses is missing.
  • Loading branch information
josh-burton committed Nov 22, 2024
1 parent cd031e4 commit 68972c3
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 2 deletions.
8 changes: 8 additions & 0 deletions lib/src/phone_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,11 @@ class PhoneController extends ChangeNotifier {

changeNationalNumber(String? text) {
text = text ?? '';
final oldFormattedText = _value.formatNsn();
var newFormattedText = text;

bool isDeleting = text.length < oldFormattedText.length;

// if starts with + then we parse the whole number
final startsWithPlus =
text.startsWith(RegExp('[${AllowedCharacters.plus}]'));
Expand All @@ -51,6 +54,11 @@ class PhoneController extends ChangeNotifier {
_value = phoneNumber;
newFormattedText = _value.formatNsn();
}
} else if (isDeleting &&
text.startsWith(
RegExp('^\\([${AllowedCharacters.digits}]+(?!.*\\))'))) {
// Handle case where the phone number contains an area code such as (416), and user has begun to delete it, i.e. the text input is now (416.
// We need to skip parsing/formatting here, else the parentheses will be added back
} else {
final phoneNumber = PhoneNumber.parse(
text,
Expand Down
86 changes: 84 additions & 2 deletions test/phone_form_field_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:circle_flags/circle_flags.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_country_selector/flutter_country_selector.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:phone_form_field/phone_form_field.dart';
Expand Down Expand Up @@ -112,6 +113,86 @@ void main() {
expect(find.text('6 77 77 77 77'), findsOneWidget);
});

testWidgets('Can delete phone number', (tester) async {
final controller = PhoneController(
initialValue: PhoneNumber.parse('+64'),
);

await tester.pumpWidget(getWidget(controller: controller));
await tester.pump(const Duration(seconds: 1));
final phoneField = find.byType(PhoneFormField);
await tester.enterText(phoneField, '+64210000000');
await tester.pump(const Duration(seconds: 1));
expect(find.text('+ 64'), findsOneWidget);
expect(find.text('210 000 000'), findsOneWidget);

await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.pump();

expect(controller.value.nsn, equals(''));
});

testWidgets('Can delete phone number with area code in parentheses',
(tester) async {
final controller = PhoneController(
initialValue: PhoneNumber.parse('+1'),
);

await tester.pumpWidget(getWidget(controller: controller));
await tester.pump(const Duration(seconds: 1));
final phoneField = find.byType(PhoneFormField);
await tester.enterText(phoneField, '+14165555555');
await tester.pump(const Duration(seconds: 1));
expect(find.text('+ 1'), findsOneWidget);
expect(find.text('(416) 555-5555'), findsOneWidget);

// delete all digits up to the area code (416)
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);

// attempt to delete area code
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);

expect(find.text('(416'), findsOneWidget);

await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);
await tester.sendKeyEvent(LogicalKeyboardKey.backspace);

expect(find.text('(416)'), findsNothing);
expect(controller.value.nsn, equals(''));
});

testWidgets('Can enter phone number with area code', (tester) async {
final controller = PhoneController(
initialValue: PhoneNumber.parse('+1'),
);

await tester.pumpWidget(getWidget(controller: controller));
await tester.pump(const Duration(seconds: 1));
final phoneField = find.byType(PhoneFormField);

await tester.enterText(phoneField, '(416');

await tester.pump(const Duration(seconds: 1));

expect(find.text('+ 1'), findsOneWidget);
expect(find.text('(416)'), findsOneWidget);
});

testWidgets('Should show dial code when showDialCode is true',
(tester) async {
PhoneNumber phoneNumber = PhoneNumber.parse('+33');
Expand Down Expand Up @@ -250,10 +331,11 @@ void main() {
);
});

testWidgets('Should call onChange when countryCode updated', (tester) async {
testWidgets('Should call onChange when countryCode updated',
(tester) async {
bool changed = false;
PhoneNumber? phoneNumber =
PhoneNumber.parse('', destinationCountry: IsoCode.FR);
PhoneNumber.parse('', destinationCountry: IsoCode.FR);
void onChanged(PhoneNumber? p) {
changed = true;
phoneNumber = p;
Expand Down

0 comments on commit 68972c3

Please sign in to comment.