Skip to main content

bharatvalidator 1.0.1 copy "bharatvalidator: ^1.0.1" to clipboard
bharatvalidator: ^1.0.1 copied to clipboard

🇮🇳 India-first Flutter form validation package with 30+ validators. Covers Aadhaar, PAN, GST, IFSC, UPI, Driving License, Passport, Voter ID etc.

example/lib/main.dart

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

void main() => runApp(const BharatValidatorExampleApp());

class BharatValidatorExampleApp extends StatelessWidget {
  const BharatValidatorExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'BharatValidator Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: const Color(0xFFFF6B00),
          primary: const Color(0xFFFF6B00),
        ),
        useMaterial3: true,
        inputDecorationTheme: InputDecorationTheme(
          border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
          contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
        ),
      ),
      home: const ValidatorDemoPage(),
    );
  }
}

// ── Data Model ───────────────────────────────────────────────────────────────
class _ValidatorItem {
  final String label;
  final String hint;
  final String category;
  final TextInputType keyboard;
  final bool obscure;
  final String? Function(String?) validator;

  const _ValidatorItem({
    required this.label,
    required this.hint,
    required this.category,
    required this.validator,
    this.keyboard = TextInputType.text,
    this.obscure = false,
  });
}

// ── Main Page ────────────────────────────────────────────────────────────────
class ValidatorDemoPage extends StatefulWidget {
  const ValidatorDemoPage({super.key});

  @override
  State<ValidatorDemoPage> createState() => _ValidatorDemoPageState();
}

class _ValidatorDemoPageState extends State<ValidatorDemoPage> {
  final _formKey       = GlobalKey<FormState>();
  final _searchCtrl    = TextEditingController();
  BharatLocale _locale = BharatLocale.english;
  late BharatValidator _v;
  String _searchQuery  = '';
  bool _showSearch     = false;

  // Controllers map
  final Map<String, TextEditingController> _controllers = {};

  late List<_ValidatorItem> _allItems;

  @override
  void initState() {
    super.initState();
    _v = BharatValidator(locale: _locale);
    _buildItems();
  }

  void _buildItems() {
    _allItems = [
      // 👤 Personal Info
      _ValidatorItem(label: 'Full Name',     hint: 'Rahul Sharma',              category: '👤 Personal Info',       validator: _v.name),
      _ValidatorItem(label: 'Username',      hint: 'rahul_123',                 category: '👤 Personal Info',       validator: _v.username),
      _ValidatorItem(label: 'Mobile Number', hint: '9876543210',                category: '👤 Personal Info',       validator: _v.phone,    keyboard: TextInputType.phone),
      _ValidatorItem(label: 'Landline',      hint: '02212345678',               category: '👤 Personal Info',       validator: _v.landline, keyboard: TextInputType.phone),
      _ValidatorItem(label: 'Email',         hint: 'rahul@gmail.com',           category: '👤 Personal Info',       validator: _v.email,    keyboard: TextInputType.emailAddress),
      _ValidatorItem(label: 'Password',      hint: 'Min 8 chars, A-z, 0-9, @', category: '👤 Personal Info',       validator: _v.password, obscure: true),
      _ValidatorItem(label: 'Date of Birth', hint: 'DD/MM/YYYY',               category: '👤 Personal Info',       validator: (v) => _v.dob(v, minAge: 18)),

      // 🪪 Government IDs
      _ValidatorItem(label: 'Aadhaar Number',  hint: '2345 6789 0123',   category: '🪪 Government IDs', validator: _v.aadhaar,        keyboard: TextInputType.number),
      _ValidatorItem(label: 'PAN Number',      hint: 'ABCDE1234F',       category: '🪪 Government IDs', validator: _v.pan),
      _ValidatorItem(label: 'Voter ID',        hint: 'ABC1234567',       category: '🪪 Government IDs', validator: _v.voterId),
      _ValidatorItem(label: 'Passport',        hint: 'A1234567',         category: '🪪 Government IDs', validator: _v.passport),
      _ValidatorItem(label: 'Driving License', hint: 'GJ0120200123456',  category: '🪪 Government IDs', validator: _v.drivingLicense),
      _ValidatorItem(label: 'Ration Card',     hint: 'GJ123456789012',   category: '🪪 Government IDs', validator: _v.rationCard),

      // 🏢 Tax & Business
      _ValidatorItem(label: 'GST Number',    hint: '27AAPFU0939F1ZV',      category: '🏢 Tax & Business', validator: _v.gst),
      _ValidatorItem(label: 'TAN Number',    hint: 'PDES03028F',           category: '🏢 Tax & Business', validator: _v.tan),
      _ValidatorItem(label: 'CIN Number',    hint: 'U67190TN2014PTC096978',category: '🏢 Tax & Business', validator: _v.cin),
      _ValidatorItem(label: 'FSSAI License', hint: '12345678901234',       category: '🏢 Tax & Business', validator: _v.fssai,  keyboard: TextInputType.number),
      _ValidatorItem(label: 'Udyam Number',  hint: 'UDYAM-MH-01-0012345', category: '🏢 Tax & Business', validator: _v.udyam),
      _ValidatorItem(label: 'RERA Number',   hint: 'UPRERAPRJ123456',      category: '🏢 Tax & Business', validator: _v.rera),

      // 🏦 Banking & Finance
      _ValidatorItem(label: 'IFSC Code',        hint: 'SBIN0001234',            category: '🏦 Banking & Finance', validator: _v.ifsc),
      _ValidatorItem(label: 'UPI ID',           hint: 'name@paytm',             category: '🏦 Banking & Finance', validator: _v.upi),
      _ValidatorItem(label: 'Bank Account',     hint: '1234567890',             category: '🏦 Banking & Finance', validator: _v.bankAccount,  keyboard: TextInputType.number),
      _ValidatorItem(label: 'Card Number',      hint: '4111 1111 1111 1111',    category: '🏦 Banking & Finance', validator: _v.cardNumber,   keyboard: TextInputType.number),
      _ValidatorItem(label: 'MICR Code',        hint: '400002009',              category: '🏦 Banking & Finance', validator: _v.micr,         keyboard: TextInputType.number),
      _ValidatorItem(label: 'EPF Account',      hint: 'MH/BAN/0012345/000/001', category: '🏦 Banking & Finance', validator: _v.epf),
      _ValidatorItem(label: 'SWIFT/BIC Code',   hint: 'SBININBB',               category: '🏦 Banking & Finance', validator: _v.swift),
      _ValidatorItem(label: 'Amount (₹)',        hint: '5000',                   category: '🏦 Banking & Finance', validator: (v) => _v.amount(v, min: 1, max: 1000000), keyboard: TextInputType.number),

      // 🏥 Health
      _ValidatorItem(label: 'ABHA Number', hint: '12345678901234 or name@abdm', category: '🏥 Health', validator: _v.abha),

      // 📍 Address & Vehicle
      _ValidatorItem(label: 'Pincode',        hint: '380001',     category: '📍 Address & Vehicle', validator: _v.pincode, keyboard: TextInputType.number),
      _ValidatorItem(label: 'Vehicle Number', hint: 'GJ01AB1234', category: '📍 Address & Vehicle', validator: _v.vehicle),

      // 📞 Others
      _ValidatorItem(label: 'Toll-free Number', hint: '1800-123-4567', category: '📞 Others', validator: _v.tollFree, keyboard: TextInputType.phone),
      _ValidatorItem(label: 'Website URL',      hint: 'https://example.com', category: '📞 Others', validator: _v.url, keyboard: TextInputType.url),
      _ValidatorItem(label: 'OTP (6-digit)',    hint: '123456',              category: '📞 Others', validator: (v) => _v.otp(v, length: 6), keyboard: TextInputType.number),
    ];

    // Init controllers
    for (final item in _allItems) {
      _controllers.putIfAbsent(item.label, () => TextEditingController());
    }
  }

  void _changeLocale(BharatLocale locale) {
    setState(() {
      _locale = locale;
      _v = BharatValidator(locale: locale);
      _buildItems();
    });
  }

  List<_ValidatorItem> get _filteredItems {
    if (_searchQuery.isEmpty) return _allItems;
    return _allItems.where((item) =>
    item.label.toLowerCase().contains(_searchQuery.toLowerCase()) ||
        item.category.toLowerCase().contains(_searchQuery.toLowerCase())
    ).toList();
  }

  Map<String, List<_ValidatorItem>> get _groupedItems {
    final map = <String, List<_ValidatorItem>>{};
    for (final item in _filteredItems) {
      map.putIfAbsent(item.category, () => []).add(item);
    }
    return map;
  }

  @override
  void dispose() {
    _searchCtrl.dispose();
    for (final c in _controllers.values) c.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: _showSearch
            ? TextField(
          controller: _searchCtrl,
          autofocus: true,
          style: const TextStyle(color: Colors.white),
          cursorColor: Colors.white,
          decoration: const InputDecoration(
            hintText: 'Search validators...',
            hintStyle: TextStyle(color: Colors.white70),
            border: InputBorder.none,
          ),
          onChanged: (v) => setState(() => _searchQuery = v),
        )
            : const Text('🇮🇳 BharatValidator Demo'),
        backgroundColor: Theme.of(context).colorScheme.primary,
        foregroundColor: Colors.white,
        actions: [
          IconButton(
            icon: Icon(_showSearch ? Icons.close : Icons.search),
            onPressed: () {
              setState(() {
                _showSearch = !_showSearch;
                if (!_showSearch) {
                  _searchCtrl.clear();
                  _searchQuery = '';
                }
              });
            },
          ),
          PopupMenuButton<BharatLocale>(
            icon: const Icon(Icons.language),
            tooltip: 'Change Language',
            onSelected: _changeLocale,
            itemBuilder: (_) => const [
              PopupMenuItem(value: BharatLocale.english,  child: Text('🇬🇧 English')),
              PopupMenuItem(value: BharatLocale.hindi,    child: Text('🇮🇳 Hindi')),
              PopupMenuItem(value: BharatLocale.gujarati, child: Text('🟠 Gujarati')),
            ],
          ),
        ],
      ),
      body: Column(
        children: [
          // Stats bar
          Container(
            color: Theme.of(context).colorScheme.primary.withOpacity(0.08),
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
            child: Row(
              children: [
                const Icon(Icons.verified, size: 16, color: Color(0xFFFF6B00)),
                const SizedBox(width: 6),
                Text(
                  '${_filteredItems.length} validators • 3 languages',
                  style: TextStyle(
                    fontSize: 12,
                    color: Theme.of(context).colorScheme.primary,
                    fontWeight: FontWeight.w500,
                  ),
                ),
              ],
            ),
          ),
          Expanded(
            child: Form(
              key: _formKey,
              child: ListView(
                padding: const EdgeInsets.all(16),
                children: [
                  ..._groupedItems.entries.map((entry) => Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      _SectionHeader(entry.key),
                      ...entry.value.map((item) => _ValidatorField(
                        item: item,
                        controller: _controllers[item.label]!,
                      )),
                      const SizedBox(height: 8),
                    ],
                  )),
                  const SizedBox(height: 16),
                  FilledButton.icon(
                    onPressed: () {
                      if (_formKey.currentState!.validate()) {
                        ScaffoldMessenger.of(context).showSnackBar(
                          const SnackBar(
                            content: Text('✅ All validations passed!'),
                            backgroundColor: Colors.green,
                          ),
                        );
                      }
                    },
                    icon: const Icon(Icons.check_circle_outline),
                    label: const Text('Validate All Fields', style: TextStyle(fontSize: 16)),
                    style: FilledButton.styleFrom(
                      padding: const EdgeInsets.symmetric(vertical: 16),
                      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
                    ),
                  ),
                  const SizedBox(height: 32),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

// ── Validator Field with Copy Button ─────────────────────────────────────────
class _ValidatorField extends StatelessWidget {
  final _ValidatorItem item;
  final TextEditingController controller;

  const _ValidatorField({required this.item, required this.controller});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 12),
      child: TextFormField(
        controller: controller,
        validator: item.validator,
        obscureText: item.obscure,
        keyboardType: item.keyboard,
        decoration: InputDecoration(
          labelText: item.label,
          hintText: item.hint,
          suffixIcon: item.obscure
              ? null
              : IconButton(
            icon: const Icon(Icons.copy, size: 18),
            tooltip: 'Copy hint',
            onPressed: () {
              Clipboard.setData(ClipboardData(text: item.hint));
              ScaffoldMessenger.of(context).showSnackBar(
                SnackBar(
                  content: Text('Copied: ${item.hint}'),
                  duration: const Duration(seconds: 1),
                  behavior: SnackBarBehavior.floating,
                ),
              );
            },
          ),
        ),
      ),
    );
  }
}

// ── Section Header ────────────────────────────────────────────────────────────
class _SectionHeader extends StatelessWidget {
  final String title;
  const _SectionHeader(this.title);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 12, top: 4),
      child: Row(
        children: [
          Container(
            width: 4,
            height: 20,
            decoration: BoxDecoration(
              color: Theme.of(context).colorScheme.primary,
              borderRadius: BorderRadius.circular(2),
            ),
          ),
          const SizedBox(width: 8),
          Text(
            title,
            style: Theme.of(context).textTheme.titleMedium?.copyWith(
              fontWeight: FontWeight.bold,
              color: Theme.of(context).colorScheme.primary,
            ),
          ),
        ],
      ),
    );
  }
}
3
likes
150
points
42
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

🇮🇳 India-first Flutter form validation package with 30+ validators. Covers Aadhaar, PAN, GST, IFSC, UPI, Driving License, Passport, Voter ID etc.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on bharatvalidator