0

I have a situation where I need to restrict users from entering a value greater than or less than a value (say x <int> type).

Here is my input field

TextField(
  decoration: InputDecoration(
    labelText: 'Amount',
    border: OutlineInputBorder(),
    enabled: widget.biller.paymentAmountExactness != 'EXACT',
  ),
  keyboardType: TextInputType.numberWithOptions(decimal: true),
  controller: _amountFieldCtrl,
),

For understanding, let's consider the amount fetched from API is 400.00. Now, I have a condition which is also, coming from API where I need to check widget.biller.paymentAmountExactness key. If the value key is EXACT_UP then, the user can enter the value in the TextField 400.00 or more.

Similarly, if the value is EXACT_DOWN, the user should not be able to enter the value in the field more than 400.00.

I don't find any max or min parameter in the TextField() widget. How do I achieve such functionality?

Yashwardhan Pauranik
  • 5,370
  • 5
  • 42
  • 65
  • Have you tried on changed? but i still couldn't get what u meant. – Mahdi-Jafaree Oct 26 '20 at 14:37
  • @Mahdi-Jafaree I very simple terms, I want to restrict the user to not able to enter a value in the input field which is greater than 400.00. – Yashwardhan Pauranik Oct 26 '20 at 14:50
  • you can use either a TextFormField inside a form widget or the TextField with a error text below the text field. by textfield you can call setState (if u want a statefull widget) on every onChanged call and show your error. – Mahdi-Jafaree Oct 31 '20 at 04:44

1 Answers1

3

What you need is a TextEditingController, then check for value change in the TextField using the onChanged parameter. If you don't understand the TextPosition part you can follow this link, basically it's to avoid the cursor to jump to the start whenever you make a change.

Here is an example to what you want to achieve:

import 'package:flutter/material.dart';

main() {
  runApp(MaterialApp(home: MyApp()));
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int min = 5;
  int max = 100;
  TextEditingController _textEditingController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextField(
          controller: _textEditingController,
          onChanged: (String value) {
            print('Changed');
            int x;
            try {
              x = int.parse(value);
            } catch (error) {
              x = min;
            }
            if (x < min) {
              x = min;
            } else if (x > max) {
              x = max;
            }

            _textEditingController.value = TextEditingValue(
              text: x.toString(),
              selection: TextSelection.fromPosition(
                TextPosition(offset: _textEditingController.value.selection.baseOffset),
              ),
            );
          },
        ),
      ),
    );
  }

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

Note that it would be a very poor design to handle this only like this. You should display an error message if you change the value automatically. To achieve this easily I would use a FormField, use form.validation at each step, and put the logic here.

Lulupointu
  • 3,364
  • 1
  • 12
  • 28