I have a textfield connected to its TextEditingController()
. Inside the onChanged:
callback I perform a text check to only allow for time input.
When running on iOS CupertinoTextfield
is used and it behaves as expected, at every input cursor moves so next digit is at the right position, so inputting 1000 will result in 10:00.
When running on web or Android Material Textfield
is used instead, the problem is that text is displayed backward as the cursor stays at first position so inputting 1000 will result in 00:01 ..
I tried enabling autofocus: true
, but doesn't help. I tried with textDirection: TextDirection.ltr,
but didn't fixit either. I also tried a solution from another post here grabbing the controller selection and reapplying it on the checked text but it didn't help either.
What am I missing to set for Material Textfield ?
As always thank you very much for your time and help.
This is the widget:
Expanded(
flex: 2,
child: kIsWeb
? TextField(
keyboardType: TextInputType.numberWithOptions(),
textDirection: TextDirection.ltr,
autofocus: true,
controller: monMorOp,
onChanged: (value) {
TextSelection previousSelection =
monMorOp.selection;
monMorOp.text = validateTimeFormat(value);
monMorOp.selection = previousSelection;
},
)
: Platform.isIOS
? CupertinoTextField(
keyboardType:
TextInputType.numberWithOptions(),
controller: monMorOp,
onChanged: (value) {
monMorOp.text = validateTimeFormat(value);
},
)
: TextField(
keyboardType:
TextInputType.numberWithOptions(),
controller: monMorOp,
onChanged: (value) {
monMorOp.text = validateTimeFormat(value);
},
),
),
an this is the text checking method :
String validateTimeFormat(String value) {
print('call back method called');
// String numb = event.text;
print('input text is $value');
String cleanNumb = value.replaceAll(RegExp(':'), '').substring(0);
print('cleaned input text is $cleanNumb');
RegExp isDigit = RegExp(r'^[\d]{1,4}$'); // is digit 1 to 4 characters
// RegExp isDigit = RegExp(r'^[\d]$'); // is digit
RegExp input;
String text;
int lenght;
String replaced;
if (isDigit.hasMatch(cleanNumb)) {
print('text is 1-4 digits');
text = cleanNumb;
lenght = text.length;
// print('lenght is $lenght');
if (lenght == 1) {
// first digit
//allow 0-2
input = RegExp(r'^[0-2]$');
input.hasMatch(text[0])
? print('text is : $text')
: print('text is: not valid');
return input.hasMatch(text[lenght - 1]) ? text : '';
} else if (lenght == 2) {
// second digit
int first = int.parse(text[0]);
print('firstDigit is $first');
if (first == 008 || first == 1) {
// allow 0-9
input = RegExp(r'^[0-9]$');
input.hasMatch(text[lenght - 1])
? print('text is : $text')
: print('text is : ${text.substring(0, lenght - 1)}');
return input.hasMatch(text[lenght - 1])
? text
: text.substring(0, lenght - 1);
} else {
// allow 0-3
input = RegExp(r'^[0-3]$');
input.hasMatch(text[lenght - 1])
? print('text is : $text')
: print('text is : ${text.substring(0, lenght - 1)}');
return input.hasMatch(text[lenght - 1])
? text
: text.substring(0, lenght - 1);
}
}
if (lenght == 3) {
//third digit
// add : at lenght-1
// allow 0-5
input = RegExp(r'^[0-5]$');
input.hasMatch(text[lenght - 1])
? replaced = text.replaceRange(2, lenght, ':${text.substring(2)}')
: replaced = text.substring(0, lenght - 1);
print('text is : $replaced');
return replaced;
}
if (lenght == 4) {
// fourth digit
// allow 0-9
input = RegExp(r'^[0-9]$');
input.hasMatch(text[lenght - 1])
? replaced = text.replaceRange(2, lenght, ':${text.substring(2)}')
: replaced = text.substring(0, lenght - 1);
print('text is : $replaced');
return replaced;
}
} else {
// discard extra digit
print('more than 4 digits');
lenght = cleanNumb.length;
replaced =
cleanNumb.replaceRange(2, lenght, ':${cleanNumb.substring(2, 4)}');
print('text is : $replaced');
return replaced;
}
}