regexflutterdartflutter-textformfield

Why Regex expression not working in flutter as expected


In my app i validate form for age phone email and many more field and i am trying to validate all this field. but unable to do so I have regex expression for phone textformfield. I cant use inputFormatters for this as I have custom textformfield.

I want my what's app field should contain only 10 digit number and avoid all special characters and space.

how do I solve this problem?

here is my code:

    TextFormFieldCustom(                                
                                  hintText: "Mobile Number",
                                  enable: _mobileController.text.isEmpty,
                                  controller: _mobileController,
                                  keyboardType: TextInputType.number,
                                  inputTextFormatter: [
                                    
 FilteringTextInputFormatter.digitsOnly 
                                  ],
                                  validator: (value) {
                                    if (!isValidMobile(value!)) {
                                      return 'Please enter your correct mobile number';
                                    }
                                    return null;
                                  },
                                ),

this is my custom textfield which is i used for many areas in app:

class TextFormFieldCustom extends StatefulWidget {
  final String hintText;
  final String? labelText;
  final List<TextInputFormatter>? inputTextFormatter;
  final TextEditingController? controller;
  final Widget? prefixIcon;
  final String? Function(String?)? validator;
  final Function(String?)? onChanged;
  final TextInputType? keyboardType;
  final Function(String?)? onSubmitted;
  final int? maxLines;
  final int? lenth;
  final bool enable;
  final double height;
  final Color? color;
  const TextFormFieldCustom({
    Key? key,
    required this.hintText,
    this.labelText,
    this.controller,
    this.prefixIcon,
    this.height = 65,
    this.validator,
    this.onChanged,
    this.keyboardType,
    this.onSubmitted,
    this.lenth,
    this.maxLines = 1,
    this.enable = true,
    this.color, this.inputTextFormatter,
  }) : super(key: key);

  @override
  State<TextFormFieldCustom> createState() => _TextFormFieldCustomState();
}

class _TextFormFieldCustomState extends State<TextFormFieldCustom> {
  bool isValid = false;
  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: widget.height.h,
      child: TextFormField(
        controller: widget.controller,
        validator: (value) {
          String? valid;
          if (widget.validator != null) {
            valid = widget.validator!(value);
          }
          if (valid == null && value!.isNotEmpty) {
            setState(() {
              isValid = true;
            });
          } else {
            setState(() {
              isValid = false;
            });
          }
          return valid;
        },
        onChanged: widget.onChanged,
        maxLines: widget.maxLines,
        maxLength: widget.lenth,
        keyboardType: widget.keyboardType,
        inputFormatters: [FilteringTextInputFormatter.singleLineFormatter,],
        onFieldSubmitted: (String value) {
          //for hiding keyboard
          //FocusScope.of(context).requestFocus(FocusNode());

          if (widget.onSubmitted != null) {
            widget.onSubmitted!(value);
          }
        },
        style: TextStyle(
          color: Colors.black,
          fontSize: 14.sp,
          fontWeight: FontWeight.w500,
        ),
        autofocus: false,
        autocorrect: true,
        enabled: widget.enable,
        autovalidateMode: AutovalidateMode.disabled,
        decoration: InputDecoration(
          filled: true,
          fillColor: widget.color ?? CustomColors.peachColor,
          hintText: widget.hintText,
          labelText: widget.labelText,
          hintStyle: TextStyle(
            color: CustomColors.greyFont,
            fontSize: 14.sp,
            fontWeight: FontWeight.w500,
          ),
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(10.r),
            borderSide: BorderSide.none,
          ),
          contentPadding:
              EdgeInsets.symmetric(horizontal: 20.w, vertical: 10.h),
          focusedBorder: OutlineInputBorder(
            borderRadius: BorderRadius.circular(10.r),
            borderSide: const BorderSide(color: Colors.black),
          ),
          prefixIcon: widget.prefixIcon,
          suffixIcon: isValid
              ? const Icon(Icons.check_circle, color: Colors.green)
              : null,
        ),
      ),
    );
  }
}

this is happening in my app:


Solution

  • Simply add the inputFormatters parameter to TextFormField.

    import 'package:flutter/services.dart'; 
    import 'dart:io';
    
    TextFormField(
          controller: mobileController, // textfield controller
          keyboardType: Platform.isIOS
              ? const TextInputType.numberWithOptions(signed: true)
              : TextInputType.phone,
          inputFormatters: [
            FilteringTextInputFormatter.allow(RegExp("[0-9]")), // or FilteringTextInputFormatter.digitsOnly
          ],
          formValidator: (value) {
              //...your validation
          },
        )
    

    For an open numeric (Dial) keyboard.

    keyboardType: Platform.isIOS
              ? const TextInputType.numberWithOptions(signed: true)
              : TextInputType.phone,
    

    If you have custom Textfield Widget then used below snippet

    class AppTextField extends StatelessWidget {
    //... other parameter
    final List<TextInputFormatter>? inputTextFormatter;
    final TextInputType? keyboardType;
    
    const AppTextField({
        Key? key,
        //... other parameter
        this.inputTextFormatter,
        this.keyboardType,
     }) : super(key: key);
    
    @override
      Widget build(BuildContext context) {
        return TextFormField(
        inputFormatters: inputTextFormatter ??
              [FilteringTextInputFormatter.singleLineFormatter],
        keyboardType: keyboardType ?? TextInputType.emailAddress,
        );
      }
    }
    

    Here, is how to call it.

    AppTextField(
    /// ... other parameter
    keyboardType: isIOS
              ? const TextInputType.numberWithOptions(signed: true)
              : TextInputType.phone,
          inputTextFormatter: [
            FilteringTextInputFormatter.allow(RegExp("[0-9]")), // or FilteringTextInputFormatter.digitsOnly
          ],
     );