【问题标题】:Allow only specific input in TextFormField without validation in Flutter在 Flutter 中仅允许 TextFormField 中的特定输入而无需验证
【发布时间】:2022-01-06 08:07:13
【问题描述】:

我想让用户最多只能输入 1 到 10.000 之间的 5 个数字,但这个 TextFormField 不是必需的,也不应该通过 Form 验证提交,但我想让用户知道他是否正在添加此字段,即他不能超过 10.000,并且他只能输入 1 到 10.000 之间的数字。 TextFormField的代码:

TextFormField(
                                keyboardType: TextInputType.number,
                                controller: _number,
                                inputFormatters: <TextInputFormatter>[
                                  FilteringTextInputFormatter.digitsOnly //I have set this so the input is only numbers/digits
                                ],
                                decoration: kTextFieldDecoration.copyWith(
                                  hintText: 'Enter number between 1 and 10.000',
                                  labelText: 'Number from 1 to 10.000',
                                ),
                              ),

我不确定如何实现这一点,我对其余字段使用了正则表达式验证,但由于此字段不是必需的,因此我无法通过Form 验证对其进行验证。任何形式的帮助表示赞赏。提前致谢!

【问题讨论】:

标签: flutter mobile flutter-textformfield


【解决方案1】:

可以试试下面的代码,供你参考https://stackoverflow.com/a/68072967/7972633

更新版本 1

class NumericalRangeFormatter extends TextInputFormatter {
  final double min;
  final double max;

  NumericalRangeFormatter({required this.min, required this.max});

  @override
  TextEditingValue formatEditUpdate(
    TextEditingValue oldValue,
    TextEditingValue newValue,
  ) {

    if (newValue.text == '') {
      return newValue;
    } else if (int.parse(newValue.text) < min) {
      return TextEditingValue().copyWith(text: min.toStringAsFixed(5));
    } else {
      return int.parse(newValue.text) > max ? oldValue : newValue;
    }
  }
}

keyboardType: TextInputType.numberWithOptions(),
inputFormatters: [
   LengthLimitingTextInputFormatter(5) // only allow 5 digit number
],

【讨论】:

  • 是的,但我还是想告诉用户,他不能超过10.000,我仍然可以输入,比如说55.000,数量限制是5,但限制数量还很远。
  • @GrandMagusi 更新了我的答案,试试看
  • 我测试过,确实有效,你只能输入一个5位数字,即10k,但1-9999之间的任何数字都可以。感谢您提供的详细研究和信息。
  • 如果有机会通知用户输入的限制是什么,我还需要一件事。
【解决方案2】:

您可以通过这种方式将验证器用于非必填字段:

validator: (value) {
    if (value == null || value.isEmpty) {
      return null;
    }else {
      double? num = double.tryParse(value);
      if(num == null)
         return 'Invalid value';
      else if(num < 1 || num > 10)
         return 'Please enter value between 1 and 10.000';
    }
    return null;
},

因此,这样,如果 value 为 null 或为空,则我们可以跳过检查,否则执行所需的检查。

【讨论】:

  • 就像我在上面的问题中所说,我需要这个来限制用户而不使用验证,因为在填充的Form 中不需要此字段。
  • 是的,这就是为什么我添加了一个 return null 以防用户没有填写此字段的输入
  • 好的,这个答案也是正确的,我只是在多个选项中对其进行了测试,效果很好,但我想我会选择@HeIsDying 的答案,因为它限制用户不超过这些数字开始。老实说,我希望我能接受这两个答案!再次感谢队友!
  • 我也觉得@HelsDying 的答案更加紧凑,你应该完全接受它。感谢您的善意工作,祝您工作顺利。
【解决方案3】:

请试试下面的正则表达式

它只允许 1 到 10,000 之间的数字,并且您可以使用 TextFormField 中提供的 ma​​xLength 属性来限制输入

int validateNumber(String numberVal) {
    String patttern = r'^[1-9]([0-9]{0,1})([.][0-9]{1,3})?$';
    RegExp regExp = new RegExp(patttern);
    if (numberVal.isEmpty || numberVal.length == 0) {
      return 1;
    } else if (!regExp.hasMatch(numberVal)) {
      return 2;
    } else {
      return 0;
    }
  }

TextFormField(
                    autovalidateMode: AutovalidateMode.onUserInteraction,
                    /* autovalidate is disabled */
                    controller: numController,
                    keyboardType: TextInputType.numberWithOptions(
                      decimal: true,
                    ),
                    maxLength: 6,
                    onChanged: (val) {},
                    maxLines: 1,
                    validator: (value) {
                      int res = validateNumber(value);
                      if (res == 1) {
                        return "Please fill this required field";
                      } else if (res == 2) {
                        return "Please enter valid number between 1 to 10.000";
                      } else {
                        return null;
                      }
                    },
                    focusNode: numFocus,
                    autofocus: false,
                    decoration: InputDecoration(
                      errorMaxLines: 3,
                      counterText: "",
                      filled: true,
                      fillColor: Colors.white,
                      focusedBorder: OutlineInputBorder(
                        borderRadius: BorderRadius.all(Radius.circular(4)),
                        borderSide: BorderSide(
                          width: 1,
                          color: Color(0xffE5E5E5),
                        ),
                      ),
                      disabledBorder: OutlineInputBorder(
                        borderRadius: BorderRadius.all(Radius.circular(4)),
                        borderSide: BorderSide(
                          width: 1,
                          color: Color(0xffE5E5E5),
                        ),
                      ),
                      enabledBorder: OutlineInputBorder(
                        borderRadius: BorderRadius.all(Radius.circular(4)),
                        borderSide: BorderSide(
                          width: 1,
                          color: Color(0xffE5E5E5),
                        ),
                      ),
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.all(Radius.circular(4)),
                        borderSide: BorderSide(
                          width: 1,
                        ),
                      ),
                      errorBorder: OutlineInputBorder(
                          borderRadius: BorderRadius.all(Radius.circular(4)),
                          borderSide: BorderSide(
                            width: 1,
                            color: Colors.red,
                          )),
                      focusedErrorBorder: OutlineInputBorder(
                        borderRadius: BorderRadius.all(Radius.circular(4)),
                        borderSide: BorderSide(
                          width: 1,
                          color: Colors.red,
                        ),
                      ),
                      hintText: "Enter number between 1 to 10.000" ?? "",
                    ),
                  ),

【讨论】:

    猜你喜欢
    • 2020-10-01
    • 2022-10-21
    • 1970-01-01
    • 2018-05-03
    • 2020-09-05
    • 1970-01-01
    • 2019-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多