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

A highly customizable and ready-to-use Flutter package for smart form fields, real-time text formatting, OTP widgets, and advanced validation.

example/lib/main.dart

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

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Form Tools Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const ExampleHomePage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Form Tools Showcase'),
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
          bottom: const TabBar(
            tabs: [
              Tab(icon: Icon(Icons.auto_awesome), text: 'Smart Fields'),
              Tab(
                icon: Icon(Icons.settings_input_component),
                text: 'Formatters',
              ),
              Tab(icon: Icon(Icons.password), text: 'OTP Widgets'),
            ],
          ),
        ),
        body: const TabBarView(
          children: [SmartFieldsTab(), RawFormattersTab(), OtpWidgetsTab()],
        ),
      ),
    );
  }
}

/// TAB 1: Demonstrates the ready-to-use Smart Form Fields.
class SmartFieldsTab extends StatefulWidget {
  const SmartFieldsTab({super.key});

  @override
  State<SmartFieldsTab> createState() => _SmartFieldsTabState();
}

class _SmartFieldsTabState extends State<SmartFieldsTab> {
  final _formKey = GlobalKey<FormState>();
  AutovalidateMode _autovalidateMode = AutovalidateMode.disabled;

  void _submit() {
    if (_formKey.currentState!.validate()) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('All Smart Fields are valid!')),
      );
    } else {
      setState(() {
        _autovalidateMode = AutovalidateMode.always;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      padding: const EdgeInsets.all(24.0),
      child: Form(
        key: _formKey,
        autovalidateMode: _autovalidateMode,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            const Text(
              'Smart Fields (Plug & Play)',
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),
            const Text('No controllers or manual validation logic needed.'),
            const SizedBox(height: 24),

            const FormToolsDateField(
              pattern: 'DD/MM/YYYY',
              futureDateOnly: true,
              decoration: InputDecoration(
                labelText: 'Fecha Futura Obligatoria',
                hintText: 'DD/MM/YYYY',
                border: OutlineInputBorder(),
              ),
              errorMessage: 'Ingrese una fecha válida en el futuro',
            ),
            const SizedBox(height: 16),

            const FormToolsDateField(
              pattern: 'YYYY-MM-DD',
              decoration: InputDecoration(
                labelText: 'Fecha (YYYY-MM-DD)',
                hintText: 'YYYY-MM-DD',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 16),

            const FormToolsTimeField(pattern: 'HH:MM:SS'),
            const SizedBox(height: 16),

            const FormToolsCapitalizationField(
              labelText: 'Nombre Completo (Title Case)',
            ),
            const SizedBox(height: 16),

            const FormToolsEmailField(),
            const SizedBox(height: 16),

            const FormToolsPasswordField(
              minLength: 6,
              requireSpecialChar: false,
              errorMessage:
                  'Mínimo 6 chars, requiere mayúscula, minúscula y número',
            ),
            const SizedBox(height: 24),

            ElevatedButton(
              onPressed: _submit,
              child: const Text('Validar Formulario Completo'),
            ),
          ],
        ),
      ),
    );
  }
}

/// TAB 2: Demonstrates how to use formatters on regular TextFields.
class RawFormattersTab extends StatefulWidget {
  const RawFormattersTab({super.key});

  @override
  State<RawFormattersTab> createState() => _RawFormattersTabState();
}

class _RawFormattersTabState extends State<RawFormattersTab> {
  final _formKey = GlobalKey<FormState>();
  final _dateController = TextEditingController();
  final _upperController = TextEditingController();
  final _lowerController = TextEditingController();
  bool _isValidDate = false;

  void _validate() {
    if (_formKey.currentState!.validate()) {
      bool dateValid = FormToolsValidators.isValidDate(
        _dateController.text,
        'MM/YY',
      );
      if (dateValid) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Raw Formatters Validated Correctly!')),
        );
      } else {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Please enter a valid date.')),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      padding: const EdgeInsets.all(24.0),
      child: Form(
        key: _formKey,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            const Text(
              'Text Input Formatters',
              style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 8),
            const Text('Attach these to any TextField formatters list.'),
            const SizedBox(height: 24),

            TextFormField(
              controller: _dateController,
              decoration: InputDecoration(
                labelText: 'Date MM/YY',
                border: const OutlineInputBorder(),
                suffixIcon: Icon(
                  _isValidDate ? Icons.check_circle : Icons.error,
                  color: _isValidDate ? Colors.green : Colors.red,
                ),
              ),
              onChanged: (val) {
                setState(() {
                  _isValidDate = FormToolsValidators.isValidDate(val, 'MM/YY');
                });
              },
              inputFormatters: [FormToolsDateFormatter(pattern: 'MM/YY')],
              validator: (val) => _isValidDate ? null : 'Invalid date format',
            ),
            const SizedBox(height: 16),

            TextFormField(
              controller: _upperController,
              decoration: const InputDecoration(
                labelText: 'All Uppercase',
                border: OutlineInputBorder(),
              ),
              inputFormatters: [
                FormToolsCapitalizationFormatter(
                  type: CapitalizationType.allUpper,
                ),
              ],
              validator: (val) =>
                  val != null && val.isEmpty ? 'Required' : null,
            ),
            const SizedBox(height: 16),

            TextFormField(
              controller: _lowerController,
              decoration: const InputDecoration(
                labelText: 'All Lowercase',
                border: OutlineInputBorder(),
              ),
              inputFormatters: [
                FormToolsCapitalizationFormatter(
                  type: CapitalizationType.allLower,
                ),
              ],
              validator: (val) =>
                  val != null && val.isEmpty ? 'Required' : null,
            ),
            const SizedBox(height: 24),

            ElevatedButton(
              onPressed: _validate,
              child: const Text('Validate Fields'),
            ),
          ],
        ),
      ),
    );
  }
}

/// TAB 3: Demonstrates the various OTP Widget configurations.
class OtpWidgetsTab extends StatefulWidget {
  const OtpWidgetsTab({super.key});

  @override
  State<OtpWidgetsTab> createState() => _OtpWidgetsTabState();
}

class _OtpWidgetsTabState extends State<OtpWidgetsTab> {
  void _onOtpCompleted(String code, String type) {
    ScaffoldMessenger.of(
      context,
    ).showSnackBar(SnackBar(content: Text('OTP completado en $type: $code')));
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      padding: const EdgeInsets.all(24.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          const Text(
            'Dynamic OTP Widgets',
            style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
          ),
          const SizedBox(height: 8),
          const Text('Auto-focusing, customizable lengths and shapes.'),
          const SizedBox(height: 24),

          const Text('Length: 4 | Style: Underlined'),
          const SizedBox(height: 8),
          DynamicOTPWidget(
            length: 4,
            decorationStyle: OtpDecorationStyle.underlined,
            borderColor: Colors.deepPurple,
            onCompleted: (c) => _onOtpCompleted(c, 'Underlined 4'),
          ),
          const SizedBox(height: 32),

          const Text('Length: 6 | Style: Circular'),
          const SizedBox(height: 8),
          DynamicOTPWidget(
            length: 6,
            decorationStyle: OtpDecorationStyle.circular,
            borderColor: Colors.teal,
            onCompleted: (c) => _onOtpCompleted(c, 'Circular 6'),
          ),
          const SizedBox(height: 32),

          const Text('Length: 5 | Style: Square'),
          const SizedBox(height: 8),
          DynamicOTPWidget(
            length: 5,
            decorationStyle: OtpDecorationStyle.square,
            borderColor: Colors.blueGrey,
            onCompleted: (c) => _onOtpCompleted(c, 'Square 5'),
          ),
        ],
      ),
    );
  }
}
0
likes
160
points
179
downloads

Documentation

API reference

Publisher

verified publishergrandezsoft.com

Weekly Downloads

A highly customizable and ready-to-use Flutter package for smart form fields, real-time text formatting, OTP widgets, and advanced validation.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on form_tools