TootsieRockNRoll
TootsieRockNRoll

Reputation: 3288

Validate and allow only Date and hyphens in TextField -- MaskTextInputFormatter doesn't work for manually updating text

I need to make a TextField that has a date filter (dd-mm-yyyy), I managed to create the filter using the dependency mask_text_input_formatter: ^1.0.6 like so

final TextEditingController _controller = TextEditingController();
var maskFormatter = new MaskTextInputFormatter(mask: '##-##-####');
...
child: TextField(
  controller: _controller,
  keyboardType: TextInputType.number,
  inputFormatters: [maskFormatter],
  onChanged: (text) {
    //
  },

so since I couldn't find a good way to mask the text to be a valid date (e.g. no 31-02-9299), I decided to do it manually in onChanged callback and update the text at some point, but just testing with a basic _controller.text = "1234"; shows the text "1234" and not "12-34".

what could be the issue?

Upvotes: 3

Views: 1893

Answers (1)

om-ha
om-ha

Reputation: 3592

Solution

For your specific use case, here's a solution you can try:

TextField(
    inputFormatters: [
        WhitelistingTextInputFormatter(RegExp(r"^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]|(?:Jan|Mar|May|Jul|Aug|Oct|Dec)))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2]|(?:Jan|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)(?:0?2|(?:Feb))\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9]|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep))|(?:1[0-2]|(?:Oct|Nov|Dec)))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$")),
    ],
);

Explanation

You can't validate the text like you want with mask_text_input_formatter pub as it performs comparison char by char. So you can only validate each individual char using regex.

To perform manual validation of the text of TextField or TextFormField`, then you need to use TextInputFormatter. More specifically using either BlacklistingTextInputFormatter or WhitelistingTextInputFormatter. For another example different from your question, here's How to restrict two dots.

Regex expression is taken from this answer, test cases for this particular regex can be found here.

Automatically inserting hyphens

If you want to automatically insert hyphens then you'll need to work within onChanged. Here's a simple example for doing this.

If you're going for this approach, you can validate the text within onChanged but you'll also have to reset the recently-changed invalid text with valid one since onChanged is called AFTER the text has already been changed. So this is lazy validation unlike BlacklistingTextInputFormatter or WhitelistingTextInputFormatter which offer eager validation before the text is even modified.

Upvotes: 4

Related Questions