MAA
MAA

Reputation: 1355

maxLength property on TextFormField works only on numbers

I noticed that when I have a TextFormField with a set maxLength property, the text field respects this limit when the input type is: keyboardType: TextInputType.phone. But when the input type is keyboardType: TextInputType.text, the text field does not respects this limit.

The questions about this issue, does not address this odd behavior. Many of the answers say that another two properties of the text should be used, maxLengthEnforced and inputFormatters, but neither change anything. The text fields still accepts more characters than the chosen max length (while showing the red error).

TextFormField(
            textAlign: TextAlign.center,
            maxLength: 2,  --> Textfield does not respect this limit
            // maxLengthEnforced: true,  --> No difference
            // inputFormatters: [LengthLimitingTextInputFormatter(2)],  --> no difference
            controller: _licenseLetters,
            focusNode: _licenseLettersNode,
            keyboardType: TextInputType.text,
            decoration: InputDecoration(
              border: OutlineInputBorder(borderRadius: BorderRadius.circular(15)),
              filled: true,
              fillColor: Colors.black.withOpacity(0.05),
            ),
            onEditingComplete: () => _licenseNumbersNode.requestFocus(),
          ),

This text form field below respects the maxLength where the input type is keyboardType: TextInputType.phone

TextFormField(

      maxLength: 9,
      controller: _landlineController,
      focusNode: _landlineNode,
      validator: validateLandlineNumber,
      keyboardType: TextInputType.phone,
      decoration: InputDecoration(
        border: OutlineInputBorder(borderRadius: BorderRadius.circular(15)),
        filled: true,
        fillColor: Colors.black.withOpacity(0.05),
      ),
      onEditingComplete: () => _mobileNode.requestFocus(),
    ),

The documents states that

After maxLength characters have been input, additional input is ignored, unless maxLengthEnforced is set to false. The text field enforces the length with a LengthLimitingTextInputFormatter, which is evaluated after the supplied inputFormatters, if any.

but I did not find this to be true.

Any advise on setting the max length on letters to only two?

Upvotes: 1

Views: 4919

Answers (2)

bytesizedwizard
bytesizedwizard

Reputation: 6033

There is already an issue filed regarding this on GitHub, you can check it out.

It has been fixed in the flutter master channel now, and you should expect it to be available in stable channel the upcoming releases.

Meanwhile, as a workaround you can simulate similar behavior using either of the below methods -

  1. Using the onChange callback -

    You can use the onChange callback for the TextFormField to enforce length limiting.

    Example -

    onChanged: (value) { 
        String result = value; 
        // Here replace 4 by your maxLength value
        if (result.length > 4) {
            result = result.substring(0, 4); 
        }
        _textFieldController.text = result;
        _textFieldController.selection = TextSelection.fromPosition(
            TextPosition(offset: result.length),
        ); 
    }
    
  2. Using your own custom LengthLimitingInputFormatter -

    You can use your own LengthLimitingInputFormatter to enforce maximum length.

    Example -

    import 'package:characters/characters.dart';
    import 'package:flutter/services.dart';
    
    /// TextInputFormatter that fixes the regression.
    /// https://github.com/flutter/flutter/issues/67236
    ///
    /// Remove it once the issue above is fixed.
    class LengthLimitingTextFieldFormatterFixed extends LengthLimitingTextInputFormatter {
    
       LengthLimitingTextFieldFormatterFixed(int maxLength) : super(maxLength);
    
       @override
       TextEditingValue formatEditUpdate( TextEditingValue oldValue, TextEditingValue newValue, ) {
          if (maxLength != null && maxLength > 0 && newValue.text.characters.length > maxLength) {
          // If already at the maximum and tried to enter even more, keep the old value.
          if (oldValue.text.characters.length == maxLength) {
              return oldValue;
          }
          // ignore: invalid_use_of_visible_for_testing_member
          return LengthLimitingTextInputFormatter.truncate(newValue, maxLength);
        }
    
        return newValue;
      }
    }
    
    

Upvotes: 2

Talaal_M
Talaal_M

Reputation: 125

Try using the input formatter this way..

inputFormatters: [
  LengthLimitingTextInputFormatter(9) //or any number you want
],

I know you said you have used the input formatters but you did not specify how and when I went through the same issue before and used it on my textfield it worked.

Upvotes: 0

Related Questions