Home > Enterprise >  How to limit text field with a value in flutter?
How to limit text field with a value in flutter?

Time:06-09

I want to limit the value that user input not to over a expected value in flutter text field.

Example, If there is a value come from API is 10 and want to limit the input not over 10, if client type 11 or something over 10, want to show alert or make user not to type. How to control this?

TextFormField(
              style: TextStyle(fontSize: 20),
              onChanged: (value) {
                if (value != "") {
                  int _checkValue = int.parse(value);
                  if (_checkValue >
                      Provider.of<SaleProvider>(context, listen: false)
                              .remainNewQuantity(
                                  this.currentProductItemSelected.id)) {
                    return 'error';
                  } else {
                    setState(() {
                      this.qty = int.parse(value);
                      updateByQty();
                    });
                  }
                } else {
                  setState(() {
                    
                  });
                }
              },
            ),

This is my trying, but can't do that I want.

CodePudding user response:

Please check below method. I think this will resolve your issue. If still not work, please let me know

  Widget getTextField({required int maxValue}) {
    return TextFormField(
      controller: _textController,
      keyboardType: TextInputType.number,
      onChanged: (text) {
        if (int.parse(text) > maxValue) {
          // show popup here.
          _textController.text = validText;
          _textController.selection = TextSelection.fromPosition(TextPosition(offset: _textController.text.length));
        }else{
          validText = text;
        }
      },
    );
  }

CodePudding user response:

As an exercise for my own learning I gave it a go and came up with the following approach; creating a bespoke widget which admittedly looks like a lot of code for something so simple... but it appears to work as expected I think and one could modify, expand and integrate it with other elements in various ways.

Usage: const MaxIntField(max: 100),

Implementation:

class MaxIntField extends StatefulWidget {
  const MaxIntField({Key? key, this.max = 1}) : super(key: key);
  final int max;

  @override
  State<MaxIntField> createState() => _MaxIntFieldState();
}

class _MaxIntFieldState extends State<MaxIntField> {
  final TextEditingController _controller = TextEditingController();

  @override
  void initState() {
    super.initState();
    _controller.value.copyWith(text: '0');
    _controller.addListener(() {
      if (_controller.text.isNotEmpty && _controller.text != '0') {
        int intVal = int.parse(_controller.text);
        if (intVal > widget.max) {
          setState(() {
            _controller.value =
                _controller.value.copyWith(text: widget.max.toString());
            _showMyDialog();
          });
        } else if (_controller.text != intVal.toString()) {
          //remove leading '0'
          setState(() {
            _controller.value =
                _controller.value.copyWith(text: intVal.toString());
          });
        }
      }
    });
  }

// assuming using Material
  _showMyDialog() async {
    showDialog<String>(
      context: context,
      builder: (BuildContext context) => AlertDialog(
        title: const Text('AlertDialog Title'),
        content: Text('This field is limited to ${widget.max}'),
        actions: <Widget>[
          TextButton(
            onPressed: () => Navigator.pop(context, 'OK'),
            child: const Text('OK'),
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      controller: _controller,
      keyboardType: TextInputType.number,
    );
  }
}
  • Related