flutter-form

Flutter Form Validation

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "flutter-form" with this command: npx skills add flutter/skills/flutter-skills-flutter-form

Flutter Form Validation

Goal

Implements stateful form validation in Flutter using Form , TextFormField , and GlobalKey<FormState> . Manages validation state efficiently without unnecessary key regeneration and handles user input validation workflows. Assumes a pre-existing Flutter environment with Material Design dependencies available.

Decision Logic

When implementing form validation, follow this decision tree to determine the flow of state and UI updates:

  • User triggers submit action:

  • Call _formKey.currentState!.validate() .

  • Does validate() return true ?

  • Yes (Valid): Proceed with data processing (e.g., API call, local storage). Trigger success UI feedback (e.g., SnackBar , navigation).

  • No (Invalid): The FormState automatically rebuilds the TextFormField widgets to display the String error messages returned by their respective validator functions. Halt submission.

Instructions

Initialize the Stateful Form Container Create a StatefulWidget to hold the form. Instantiate a GlobalKey<FormState> exactly once within the State class to prevent resource-expensive key regeneration during build cycles.

import 'package:flutter/material.dart';

class CustomValidatedForm extends StatefulWidget { const CustomValidatedForm({super.key});

@override State<CustomValidatedForm> createState() => _CustomValidatedFormState(); }

class _CustomValidatedFormState extends State<CustomValidatedForm> { // Instantiate the GlobalKey once in the State object final _formKey = GlobalKey<FormState>();

@override Widget build(BuildContext context) { return Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ // Form fields will be injected here ], ), ); } }

Implement TextFormFields with Validation Logic Inject TextFormField widgets into the Form 's widget tree. Provide a validator function for each field.

TextFormField( decoration: const InputDecoration( hintText: 'Enter your email', labelText: 'Email', ), validator: (String? value) { if (value == null || value.isEmpty) { return 'Please enter an email address'; } if (!value.contains('@')) { return 'Please enter a valid email address'; } // Return null if the input is valid return null; }, onSaved: (String? value) { // Handle save logic here }, )

Implement the Submit Action and Validation Trigger Create a button that accesses the FormState via the GlobalKey to trigger validation.

Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: ElevatedButton( onPressed: () { // Validate returns true if the form is valid, or false otherwise. if (_formKey.currentState!.validate()) { // Save the form fields if necessary _formKey.currentState!.save();

    // Provide success feedback
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('Processing Data')),
    );
  }
},
child: const Text('Submit'),

), )

STOP AND ASK THE USER: Pause implementation and ask the user for the following context:

  • "What specific fields do you need in this form?"

  • "What are the exact validation rules for each field (e.g., regex patterns, minimum lengths)?"

  • "What action should occur upon successful validation (e.g., API payload submission, navigation)?"

Validate-and-Fix Loop After generating the form, verify the following:

  • Ensure _formKey.currentState!.validate() is null-checked properly using the bang operator (! ) or safe calls if the key might be detached.

  • Verify that every validator function explicitly returns null on success. Returning an empty string ("" ) will trigger an error state with no text.

Constraints

  • DO NOT instantiate the GlobalKey<FormState> inside the build method. It must be a persistent member of the State class.

  • DO NOT use a StatelessWidget for the form container unless the GlobalKey is being passed down from a stateful parent.

  • DO NOT use standard TextField widgets if you require built-in form validation; you must use TextFormField (which wraps TextField in a FormField ).

  • ALWAYS return null from a validator function when the input is valid.

  • ALWAYS ensure the Form widget is a common ancestor to all TextFormField widgets that need to be validated together.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

flutter-layout

No summary provided by upstream source.

Repository SourceNeeds Review
1.2K-flutter
General

flutter-performance

No summary provided by upstream source.

Repository SourceNeeds Review
1.2K-flutter
General

flutter-theming

No summary provided by upstream source.

Repository SourceNeeds Review
1.1K-flutter
General

flutter-animation

No summary provided by upstream source.

Repository SourceNeeds Review
1.1K-flutter