У меня есть разные поля формы, и я хочу обрезать каждое значение поля формы по умолчанию до запуска метода validator.

Причина, по которой я хочу этого добиться, заключается в том, что если я запустил regex для входного значения при запуске метода validator, регулярное выражение вернет false в input_text.hasMatch из-за бесполезного пробела в конце входного значения.

Например. Приведенный ниже код alphaNumericText.hasMatch(val) вернет false из-за бесполезных символов пробела в конце входного значения.

final alphaNumericText = RegExp(r'^[a-zA-Z0-9]+$');

TextFormField(
                  keyboardType: TextInputType.text,
                  decoration: new InputDecoration(
                    labelText: 'Enter your nickname',
                  ),
                  validator: (val) {
                    if (val.isEmpty == true) {
                      return 'Nickname is required!';
                    }
                    if (alphaNumericText.hasMatch(val) == false) {
                      return 'Use alphanumeric characters only in nickname.';
                    }
                    return null;
                  },
                  onSaved: (val) => this.nickname = val,
                ),

Примечание . Я не хочу этого делать, изменяя alphaNumericText RegExp, чтобы добавить дополнительные пробелы в конце входного значения. Я не хочу этого достигать.

Я хочу, чтобы каждое значение во всех текстовых полях в форме было обрезано / trim() по умолчанию перед вызовом метода validator.

2
Muje 11 Фев 2020 в 14:35

3 ответа

Лучший ответ

Просто добавь

inputFormatters: [WhitelistingTextInputFormatter(RegExp(r'[a-zA-Z0-9]'))],

Как свойство для TextInputField, и пользователь даже не сможет набирать пробел или любые другие символы, кроме белого, и вы также можете удалить дополнительные проверки из валидатора

Полный пример

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Center(
            child: TextFormField(
              inputFormatters: [WhitelistingTextInputFormatter(RegExp(r'[a-zA-Z0-9]'))],
              keyboardType: TextInputType.text,
              decoration: new InputDecoration(
                labelText: 'Enter your nickname',
              ),
              validator: (val) {
                if (val.isEmpty == true) {
                  return 'Nickname is required!';
                }
                return null;
              },
              onSaved: (val) {},
            ),
          ),
        ),
      ),
    );
  }
}
4
Genchi Genbutsu 11 Фев 2020 в 12:24

Обрежьте текстовое значение при onChanged обратного вызова и назначьте его обратно контроллеру ,

1
Darish 11 Фев 2020 в 11:46

Как предложил @Darish, вот пример кода для него.

Однако, предостережение нужно выбрать в конце text, если оно обрезано. Это будет работать, только если пробелы между ними запрещены.

class _MyHomePageState extends State<MyHomePage> {
  final alphaNumericText = RegExp(r'^[a-zA-Z0-9]+$');
  final textController = TextEditingController();

  @override
  void dispose() {
    super.dispose();
    textController?.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextFormField(
          controller: textController,
          keyboardType: TextInputType.text,
          decoration: new InputDecoration(
            labelText: 'Enter your nickname',
          ),
          onChanged: (val) {
            final trimVal = val.trim();
            if (val != trimVal)
              setState(() {
                textController.text = trimVal;
                textController.selection = TextSelection.fromPosition(TextPosition(offset: trimVal.length));
              });
          },
          validator: (val) {
            if (val.isEmpty == true) {
              return 'Nickname is required!';
            }
            if (alphaNumericText.hasMatch(val) == false) {
              return 'Use alphanumeric characters only in nickname.';
            }
            return null;
          },
        ),
      ),
    );
  }
}
2
Harsh Bhikadia 11 Фев 2020 в 12:04