best_form_validator

pub package License

A comprehensive Flutter package designed to simplify form validation. It provides a robust set of validation functions for various form fields, including email, phone, password, name, and age. The package supports phone number validation according to different countries' phone number formats, making it versatile for international applications.

Features

Email Validation - Ensure that email addresses are in the correct format
Phone Number Validation - Validate phone numbers based on 50+ countries' formats
Password Validation - Flexible password validation with customizable criteria
Name Validation - Validate names to ensure proper formatting
Age Validation - Validate age from DateTime or string input
Date & Time Validation - Validate date and time formats
Localization Support - Built-in support for 25+ languages
Customizable Error Messages - Override default error messages
Null Safety - Built with sound null safety

Getting Started

Installation

Add the following to your pubspec.yaml:

dependencies:
  best_form_validator: ^1.1.0

Then run:

flutter pub get

Initialization

Important: For phone number validation, you must initialize the package at app startup:

import 'package:best_form_validator/best_form_validator.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Load phone regex patterns (required for phone validation)
  await Validators.loadPhoneRegex();
  
  runApp(MyApp());
}

Localization Setup

To enable localized error messages, add the FormLocalizations.delegate to your MaterialApp and set the locale in the builder.

import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:best_form_validator/best_form_validator.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // ... other properties
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        FormLocalizations.delegate, // Add this delegate
      ],
      supportedLocales: [
        Locale('en'), Locale('es'), Locale('fr'), Locale('de'),
        Locale('ar'), Locale('ur'), Locale('hi'), Locale('zh'),
        // ... and many more
      ],
      // Important: Update validator locale when app locale changes
      builder: (context, child) {
        final locale = Localizations.localeOf(context);
        Validators.setLocale(locale);
        return child!;
      },
      home: HomePage(),
    );
  }
}

Usage

Email Validation

Validates email addresses using standard email format rules.

import 'package:best_form_validator/best_form_validator.dart';

// Basic usage
String? error = Validators.validateEmail('[email protected]');
if (error != null) {
  print(error); // null if valid
}

// With custom error messages
String? error = Validators.validateEmail(
  'invalid-email',
  requiredError: 'Please enter your email',
  invalidError: 'Please enter a valid email address',
);

In a TextFormField:

TextFormField(
  decoration: InputDecoration(labelText: 'Email'),
  validator: (value) => Validators.validateEmail(value),
  keyboardType: TextInputType.emailAddress,
)

Phone Number Validation

Validates phone numbers based on country-specific formats. Supports 50+ countries.

import 'package:best_form_validator/best_form_validator.dart';

// Validate US phone number
String? error = Validators.validatePhone('+12025551234', 'US');

// Validate UK phone number
String? error = Validators.validatePhone('+447911123456', 'UK');

// Validate Pakistan phone number
String? error = Validators.validatePhone('+923001234567', 'PK');

Supported Countries:

US, CA, UK, FR, DE, IN, AU, BR, CN, JP, MX, RU, ZA, NG, EG, KE, GH, SA, AE, IT, ES, SE, NO, FI, DK, NL, BE, CH, AT, PT, GR, TR, IR, PK, BD, LK, TH, MY, SG, ID, PH, VN, KR, HK, TW, NZ, AF, AL, DZ, AR, AZ, BH

In a TextFormField:

TextFormField(
  decoration: InputDecoration(
    labelText: 'Phone Number',
    hintText: '+1234567890',
  ),
  validator: (value) => Validators.validatePhone(value, 'US'),
  keyboardType: TextInputType.phone,
)

Password Validation

Flexible password validation with multiple configurable criteria.

import 'package:best_form_validator/best_form_validator.dart';

// Basic validation (minimum 6 characters)
String? error = Validators.validatePassword('mypassword');

// Advanced validation with all criteria
String? error = Validators.validatePassword(
  'MyP@ssw0rd',
  checkLength: true,           // Check minimum length
  minLength: 8,                // Minimum 8 characters
  checkNumberAndLetter: true,  // Must contain letters and numbers
  checkSpecialCharacter: true, // Must contain special characters
  checkLowerCase: true,        // Must contain lowercase letters
  checkUpperCase: true,        // Must contain uppercase letters
);

Password Requirements:

  • ✅ Minimum length (configurable, default: 6)
  • ✅ Contains both letters and numbers
  • ✅ Contains special characters (!@#$%^&*(),.?":{}|<>)
  • ✅ Contains lowercase letters
  • ✅ Contains uppercase letters
  • ✅ No spaces allowed

In a TextFormField:

TextFormField(
  decoration: InputDecoration(labelText: 'Password'),
  obscureText: true,
  validator: (value) => Validators.validatePassword(
    value,
    checkLength: true,
    minLength: 8,
    checkNumberAndLetter: true,
    checkSpecialCharacter: true,
    checkLowerCase: true,
    checkUpperCase: true,
  ),
)

Name Validation

Validates names to ensure proper formatting without special characters or numbers.

import 'package:best_form_validator/best_form_validator.dart';

// Basic usage
String? error = Validators.validateName('John Doe'); // null (valid)
String? error = Validators.validateName('John123');  // Invalid

// With custom error messages
String? error = Validators.validateName(
  'John Doe',
  requiredError: 'Please enter your name',
  invalidError: 'Name can only contain letters',
);

Name Rules:

  • ✅ Only alphabetic characters allowed
  • ✅ Spaces allowed between names
  • ❌ No leading or trailing spaces
  • ❌ No multiple consecutive spaces
  • ❌ No special characters or numbers

In a TextFormField:

TextFormField(
  decoration: InputDecoration(labelText: 'Full Name'),
  validator: (value) => Validators.validateName(value),
  keyboardType: TextInputType.name,
)

Age Validation

Validates age from DateTime or string input with configurable minimum age requirement.

import 'package:best_form_validator/best_form_validator.dart';

// Validate with DateTime
DateTime birthDate = DateTime(2000, 1, 15);
String? error = Validators.validateAge(birthDate, 18); // Minimum 18 years

// Validate with string (yyyy-MM-dd format)
String? error = Validators.validateAge('2000-01-15', 18);

// With custom error messages
String? error = Validators.validateAge(
  '2010-01-15',
  18,
  requiredError: 'Please enter your birth date',
  invalidError: 'You must be at least 18 years old',
);

In a TextFormField:

TextFormField(
  decoration: InputDecoration(
    labelText: 'Birth Date',
    hintText: 'yyyy-MM-dd',
  ),
  validator: (value) => Validators.validateAge(value, 18),
  keyboardType: TextInputType.datetime,
)

Date Validation

Validates date strings can be properly parsed.

import 'package:best_form_validator/best_form_validator.dart';

String? error = Validators.validateDate('2024-01-15'); // null (valid)
String? error = Validators.validateDate('invalid');    // Error

// With custom error messages
String? error = Validators.validateDate(
  '2024-01-15',
  requiredError: 'Please select a date',
  invalidError: 'Please enter a valid date',
);

Time Validation

Validates time format strings.

import 'package:best_form_validator/best_form_validator.dart';

String? error = Validators.validateTime('14:30:00'); // null (valid)
String? error = Validators.validateTime('25:00:00'); // Error

// With custom error messages
String? error = Validators.validateTime(
  '14:30:00',
  requiredError: 'Please select a time',
  invalidError: 'Please enter a valid time',
);

Complete Form Example

Here's a complete example of a registration form using all validators:

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

class RegistrationForm extends StatefulWidget {
  @override
  _RegistrationFormState createState() => _RegistrationFormState();
}

class _RegistrationFormState extends State<RegistrationForm> {
  final _formKey = GlobalKey<FormState>();
  final _nameController = TextEditingController();
  final _emailController = TextEditingController();
  final _phoneController = TextEditingController();
  final _passwordController = TextEditingController();
  final _birthDateController = TextEditingController();

  @override
  void dispose() {
    _nameController.dispose();
    _emailController.dispose();
    _phoneController.dispose();
    _passwordController.dispose();
    _birthDateController.dispose();
    super.dispose();
  }

  void _submitForm() {
    if (_formKey.currentState!.validate()) {
      // Form is valid, proceed with registration
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Registration Successful!')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Registration')),
      body: Form(
        key: _formKey,
        child: ListView(
          padding: EdgeInsets.all(16),
          children: [
            // Name Field
            TextFormField(
              controller: _nameController,
              decoration: InputDecoration(
                labelText: 'Full Name',
                border: OutlineInputBorder(),
              ),
              validator: (value) => Validators.validateName(
                value,
                requiredError: 'Please enter your name',
                invalidError: 'Name can only contain letters',
              ),
              keyboardType: TextInputType.name,
            ),
            SizedBox(height: 16),

            // Email Field
            TextFormField(
              controller: _emailController,
              decoration: InputDecoration(
                labelText: 'Email',
                border: OutlineInputBorder(),
              ),
              validator: (value) => Validators.validateEmail(
                value,
                requiredError: 'Please enter your email',
                invalidError: 'Please enter a valid email',
              ),
              keyboardType: TextInputType.emailAddress,
            ),
            SizedBox(height: 16),

            // Phone Field
            TextFormField(
              controller: _phoneController,
              decoration: InputDecoration(
                labelText: 'Phone Number',
                hintText: '+1234567890',
                border: OutlineInputBorder(),
              ),
              validator: (value) => Validators.validatePhone(value, 'US'),
              keyboardType: TextInputType.phone,
            ),
            SizedBox(height: 16),

            // Password Field
            TextFormField(
              controller: _passwordController,
              decoration: InputDecoration(
                labelText: 'Password',
                border: OutlineInputBorder(),
                helperText: 'Min 8 chars, uppercase, lowercase, number, special char',
              ),
              obscureText: true,
              validator: (value) => Validators.validatePassword(
                value,
                checkLength: true,
                minLength: 8,
                checkNumberAndLetter: true,
                checkSpecialCharacter: true,
                checkLowerCase: true,
                checkUpperCase: true,
              ),
            ),
            SizedBox(height: 16),

            // Birth Date Field
            TextFormField(
              controller: _birthDateController,
              decoration: InputDecoration(
                labelText: 'Birth Date',
                hintText: 'yyyy-MM-dd',
                border: OutlineInputBorder(),
              ),
              validator: (value) => Validators.validateAge(
                value,
                18,
                invalidError: 'You must be at least 18 years old',
              ),
              keyboardType: TextInputType.datetime,
            ),
            SizedBox(height: 24),

            // Submit Button
            ElevatedButton(
              onPressed: _submitForm,
              child: Padding(
                padding: EdgeInsets.all(16),
                child: Text('Register', style: TextStyle(fontSize: 16)),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

API Reference

Validators Class

The main class providing all validation methods.

Methods

Method Parameters Returns Description
validateEmail String? value, {String? requiredError, String? invalidError} String? Validates email format
validatePhone String? value, String isoCode String? Validates phone number for specific country
validatePassword String? value, {bool? checkLength, int minLength, bool? checkNumberAndLetter, bool? checkSpecialCharacter, bool? checkLowerCase, bool? checkUpperCase} String? Validates password with configurable criteria
validateName String? value, {String? requiredError, String? invalidError} String? Validates name format
validateAge dynamic value, int minimumAge, {String? requiredError, String? invalidError} String? Validates age meets minimum requirement
validateDate String? value, {String? requiredError, String? invalidError} String? Validates date format
validateTime String? value, {String? requiredError, String? invalidError} String? Validates time format
loadPhoneRegex None Future<void> Loads phone validation patterns (call at app startup)
setLocale Locale locale void Sets the global locale for validation messages

Error Messages

All validators return null if validation passes, or a String error message if validation fails.

Default Error Messages

  • Email: "Email is required" / "Enter a valid email"
  • Phone: "Phone number is required" / "Enter a valid phone number for {country}"
  • Password: Various messages based on failed criteria
  • Name: "Name is required" / "Name is invalid"
  • Age: "Invalid date format" / "Age must be at least {minimumAge} years old"
  • Date: "Date is required" / "Enter a valid date"
  • Time: "Time is required" / "Enter a valid time"

All error messages can be customized using the optional parameters.

Platform Support

  • ✅ Android
  • ✅ iOS
  • ✅ Web
  • ✅ Windows
  • ✅ macOS
  • ✅ Linux

Requirements

  • Dart SDK: >=3.0.0 <4.0.0
  • Flutter: >=3.0.0

Dependencies

  • intl: ^0.20.2 - For date formatting and parsing

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

Issues and Feedback

Please file issues, bugs, or feature requests in our issue tracker.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Author

GreeLogix

Changelog

See CHANGELOG.md for a detailed list of changes.

Additional Resources


Made with ❤️ by GreeLogix

Libraries

best_form_validator
A comprehensive Flutter package for form validation.