I want to restrict the TextFormField to only accept numbers separated by commas and sometimes with dashes but I don't want them to come consecutive to each other and also don't want the same character consecutive.
Ex:-
1,3-4,9-11
is correct1,,3--4,9-11
is wrong1,-3-4,9-11
is wrong1-,3-4,9-11
is wrong
To restrict things to only numbers, commas and dashes I'm using:-
FilteringTextInputFormatter(
RegExp("[0-9,-]"),
allow: true
)
But it is not restricting the consecutive behavior as shown in the wrong behavior in the examples.
So, how can I restrict my TextFormField to the correct behavior represented in the examples?
Thank you.
Update: I finally followed this approach for this problem.
CodePudding user response:
If you want to validate on submit, you might write the pattern as:
^[0-9] (?:[,-][0-9] )*$
If a negative lookahead is supported, you an exclude matching 2 times one of -
or ,
while validating on typing.
Note that this will allow ,
or -
at the end:
^(?!.*[,-][,-])[0-9,-]*
CodePudding user response:
For my problem above I finally combined FilteringTextInputFormatter with a custom TextInputFormatter specific to my case so I'm adding it below so that if anyone wants to do the same they can have a look at this approach:
class RangeTextInputFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue,
) {
TextSelection newSelection = newValue.selection;
String truncated = newValue.text;
int oldValueLength = oldValue.text.length;
int newValueLength = newValue.text.length;
// Blocks comma and dash at start.
if ((oldValue.text.isEmpty || oldValue.text == "") &&
(newValue.text[newValueLength - 1] == "," ||
newValue.text[newValueLength - 1] == "-")) {
truncated = oldValue.text;
newSelection = oldValue.selection;
}
// Allows numbers at start.
else if (oldValue.text.isEmpty || oldValue.text == "") {
truncated = newValue.text;
newSelection = newValue.selection;
} else {
// Blocks comma and dash after comma.
if (oldValue.text[oldValueLength - 1] == "," &&
(newValue.text[newValueLength - 1] == "," ||
newValue.text[newValueLength - 1] == "-")) {
truncated = oldValue.text;
newSelection = oldValue.selection;
}
// Blocks comma and dash after dash.
else if (oldValue.text[oldValueLength - 1] == "-" &&
(newValue.text[newValueLength - 1] == "," ||
newValue.text[newValueLength - 1] == "-")) {
truncated = oldValue.text;
newSelection = oldValue.selection;
}
// Blocks dash after number dash number. Ex: 48-58- <- this last dash is blocked
else if (oldValue.text.lastIndexOf('-') != -1) {
if (!(oldValue.text
.substring(oldValue.text.lastIndexOf('-'))
.contains(",")) &&
newValue.text[newValueLength - 1] == "-") {
truncated = oldValue.text;
newSelection = oldValue.selection;
}
}
}
return TextEditingValue(
text: truncated,
selection: newSelection,
composing: TextRange.empty,
);
}
}
Now use it just like FilteringTextInputFormatter
:
inputFormatters: [
FilteringTextInputFormatter(RegExp("[0-9,-]"), allow: true),
RangeTextInputFormatter(),
]