As described in the title, how to implement text mask in Flutter.
I am just writing a one below but not that suitable, since it can't display the mask to the user when typing, for example, when the text mask is 'MM/HH', if we do not display the slash during the user's typing, the user will typing the slash '/' themself, as they do not know the slash will auto-fill the input. There is a example here that can explain what am I said (It's a web implementation, not Flutter), so how to implement the mask-like in this link in Flutter?
This is my current implementation.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class MaskedTextInputFormatter extends TextInputFormatter {
final String mask;
final String separator;
MaskedTextInputFormatter({
@required this.mask,
@required this.separator,
}) {
assert(mask != null);
assert(separator != null);
}
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
if (newValue.text.length > 0) {
if (newValue.text.length > oldValue.text.length) {
if (newValue.text.length > mask.length) return oldValue;
if (newValue.text.length < mask.length &&
mask[newValue.text.length - 1] == separator) {
return TextEditingValue(
text:
'${oldValue.text}$separator${newValue.text.substring(newValue.text.length - 1)}',
selection: TextSelection.collapsed(
offset: newValue.selection.end + 1,
),
);
}
}
}
return newValue;
}
}
Any help are appreciated!
PS: I searched a Flutter package mask_text_input_formatter, seems it also can't display the mask when typing, see issue.
you can achieve text mask using mask_text_input_formatter package.
Create mask formatter:
var maskFormatter = new MaskTextInputFormatter(mask: '+# (###) ###-##-##', filter: { "#": RegExp(r'[0-9]') });
Set it to text field:
TextField(inputFormatters: [maskFormatter])
Get value
Get masked text:
print(maskFormatter.getMaskedText()); // -> "+0 (123) 456-78-90"
Get unmasked text:
print(maskFormatter.getUnmaskedText()); // -> 01234567890
Change the mask You can use the updateMask method to change the mask after the formatter was created:
var textEditingController = TextEditingController(text: "12345678");
var maskFormatter = new MaskTextInputFormatter(mask: '####-####', filter: { "#": RegExp(r'[0-9]') });
TextField(controller: textEditingController, inputFormatters: [maskFormatter]) // -> "1234-5678"
textEditingController.value = maskFormatter.updateMask("##-##-##-##"); // -> "12-34-56-78"
try by adding extra condition for modifying text value
add 1 extra condition.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class MaskedTextInputFormatter extends TextInputFormatter {
final String mask;
final String separator;
MaskedTextInputFormatter({
@required this.mask,
@required this.separator,
}) {
assert(mask != null);
assert(separator != null);
}
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue, TextEditingValue newValue) {
if (newValue.text.length > 0) {
if (newValue.text.length > oldValue.text.length) {
if (newValue.text.length > mask.length) return oldValue;
if (newValue.text.length < mask.length &&
mask[newValue.text.length - 1] == separator &&
newValue.text.substring(newValue.text.length - 1) != separator) {
return TextEditingValue(
text:
'${oldValue.text}$separator${newValue.text.substring(newValue.text.length - 1)}',
selection: TextSelection.collapsed(
offset: newValue.selection.end + 1,
),
);
}
}
}
return newValue;
}
}
by using regex depending your need.
FilteringTextInputFormatter(r"[A-za-z][A-Za-z]\/[A-za-z][A-Za-z]", allow: false);
OR
FilteringTextInputFormatter(r"[A-za-z0-9][A-Za-z0-9]\/[A-za-z0-9][A-Za-z0-9]", allow: false);
example as below allow parameter is for if you want to allow particular pattern to be accepted or not
Textfield(
label: "CardNumber",
hint: "CardNumber",
focusNode: cardNumberFocus,
textInputFormatter: [
MaskedTextInputFormatter(mask: 'xxxx xxxx xxxx xxxx', separator: ' '),
FilteringTextInputFormatter(r"[A-za-z0-9][A-Za-z0-9]\/[A-za-z0-9][A-Za-z0-9]", allow: true);
],
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With