Aller au contenu principal

AsTextFormField

A form field component that wraps AsTextField with built-in validation support, form state management, and automatic error display.

Import

import 'package:alphasow_ui/alphasow_ui.dart';

Basic Usage

AsTextFormField(
label: 'Email',
hintText: 'example@domain.com',
validator: (value) {
if (value == null || value.isEmpty) {
return 'Email is required';
}
return null;
},
)

With Form Integration

class MyForm extends StatefulWidget {
@override
_MyFormState createState() => _MyFormState();
}

class _MyFormState extends State<MyForm> {
final _formKey = GlobalKey<FormState>();

@override
Widget build(BuildContext context) {
return AsForm(
formKey: _formKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: Column(
children: [
AsTextFormField(
label: 'Username',
hintText: 'Enter username',
validator: (value) {
if (value == null || value.isEmpty) {
return 'Username is required';
}
if (value.length < 3) {
return 'Username must be at least 3 characters';
}
return null;
},
),
AsButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
// Form is valid
}
},
child: Text('Submit'),
),
],
),
);
}
}

Email Validation

AsTextFormField(
type: Type.email,
label: 'Email Address',
hintText: 'you@example.com',
description: 'We will never share your email.',
validator: (value) {
if (value == null || value.isEmpty) {
return 'Email is required';
}
if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(value)) {
return 'Please enter a valid email';
}
return null;
},
)

Password Validation

AsTextFormField(
type: Type.password,
label: 'Password',
hintText: 'Enter your password',
description: 'Must be at least 8 characters with uppercase and number.',
validator: (value) {
if (value == null || value.isEmpty) {
return 'Password is required';
}
if (value.length < 8) {
return 'Password must be at least 8 characters';
}
if (!RegExp('(?=.*[A-Z])').hasMatch(value)) {
return 'Password must contain an uppercase letter';
}
if (!RegExp('(?=.*[0-9])').hasMatch(value)) {
return 'Password must contain a number';
}
return null;
},
)

With Controller

class ControlledFormField extends StatefulWidget {
@override
_ControlledFormFieldState createState() => _ControlledFormFieldState();
}

class _ControlledFormFieldState extends State<ControlledFormField> {
final _emailController = TextEditingController();

@override
void dispose() {
_emailController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Column(
children: [
AsTextFormField(
controller: _emailController,
label: 'Email',
validator: (value) {
if (value == null || value.isEmpty) {
return 'Email is required';
}
return null;
},
),
AsButton(
onPressed: () {
_emailController.clear();
},
child: Text('Clear'),
),
],
);
}
}

With Prefix and Suffix

AsTextFormField(
label: 'Search',
hintText: 'Search users...',
prefix: Icon(Icons.search),
suffix: Icon(Icons.clear),
validator: (value) => null, // Optional validation
)

API Reference

Properties

PropertyTypeDefaultDescription
controllerTextEditingController?nullControls the text being edited
labelString?nullLabel text displayed above the field
hintTextString?nullHint text displayed when field is empty
descriptionString?nullDescription text displayed below the field
typeType?nullPreset input type (email, password)
validatorString? Function(String?)?nullForm validation function
onSavedvoid Function(String?)?nullCalled when form is saved
initialValueString?nullInitial value (cannot be used with controller)
autovalidateModeAutovalidateMode?nullWhen to automatically validate
enabledbool?nullWhether the field is enabled
prefixWidget?nullWidget displayed before the input
suffixWidget?nullWidget displayed after the input
obscureTextbool?nullWhether to hide the text
maxLinesint?1Maximum number of lines
onChangedValueChanged<String>?nullCalled when text changes

Inherited from AsTextField

All properties from AsTextField are also available.

Validation Examples

Required Field

validator: (value) {
if (value == null || value.isEmpty) {
return 'This field is required';
}
return null;
}

Minimum Length

validator: (value) {
if (value == null || value.isEmpty) {
return 'This field is required';
}
if (value.length < 6) {
return 'Must be at least 6 characters';
}
return null;
}

Pattern Matching

validator: (value) {
if (value == null || value.isEmpty) {
return 'This field is required';
}
if (!RegExp(r'^[a-zA-Z0-9_]+$').hasMatch(value)) {
return 'Only letters, numbers and underscores allowed';
}
return null;
}

Confirm Password

final passwordController = TextEditingController();

// Password field
AsTextFormField(
controller: passwordController,
type: Type.password,
label: 'Password',
validator: (value) {
if (value == null || value.isEmpty) {
return 'Password is required';
}
return null;
},
)

// Confirm password field
AsTextFormField(
type: Type.password,
label: 'Confirm Password',
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please confirm your password';
}
if (value != passwordController.text) {
return 'Passwords do not match';
}
return null;
},
)

Platform Differences

Material (Android/Web)

  • Uses TextFormField with Material styling
  • Error text displayed below field in red
  • Material Design input decoration
  • Material focus and error states

Cupertino (iOS/macOS)

  • Uses CupertinoTextField wrapped in FormField
  • Error text displayed below field
  • iOS-style input styling
  • Native iOS keyboard behavior

Best Practices

  1. Always provide validation for required fields
  2. Use descriptive error messages that tell users how to fix the issue
  3. Use autovalidateMode for real-time feedback
  4. Dispose controllers in the dispose method
  5. Use Type.email or Type.password for automatic keyboard and behavior configuration

See Also