flutterx_forms 1.0.10-dev flutterx_forms: ^1.0.10-dev copied to clipboard
Create, validate and manage all aspects of your forms in a new simple way. :D :D :D
// ignore_for_file: public_member_api_docs
import 'package:cross_file/cross_file.dart';
import 'package:flutter/material.dart' hide DialogRoute;
import 'package:flutterx_application/flutterx_application.dart';
import 'package:flutterx_application/flutterx_ui.dart';
import 'package:flutterx_drop_view/flutterx_drop_view.dart';
import 'package:flutterx_forms/flutterx_forms.dart';
class Labels extends LabelInterface {
const Labels() : super(const Locale('en', 'US'));
}
void main() => runApplication(
name: 'Flutterx Forms Demo',
initialize: (context) => MyApp.route,
locale: () => LocaleData(labels: {const Labels()}, onLabel: (_) {}),
routes: {MyApp.route});
class MyApp extends StatelessWidget {
static final ActivityRoute<void> route =
ActivityRoute(location: '/index', builder: (context, args) => const MyApp._());
const MyApp._();
@override
Widget build(BuildContext context) => MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutterx Forms Demo',
theme: ThemeData(primarySwatch: Colors.grey, useMaterial3: true).copyWith(
inputDecorationTheme: const InputDecorationTheme(
labelStyle: TextStyle(),
floatingLabelStyle: TextStyle(color: Colors.grey),
border: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: Colors.grey, width: 2)))),
home: const FormsExample());
}
class FormsExample extends StatefulWidget {
const FormsExample({super.key});
@override
State<FormsExample> createState() => _FormsExampleState();
}
class _FormsExampleState extends State<FormsExample> with FormController {
final XFormField<String> _name = XFormField(() => 'Name');
final XFormField<String> _surname = XFormField(() => 'Surname');
final XFormField<int> _age = XFormField(() => 'Age');
final XFormField<XFile> _id = XFormField(() => 'ID Card');
final XFormField<CaptchaStatus> _captcha = XFormField(() => 'Captcha');
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text('Forms example')),
body: ResponsiveScreenContent(
child: Card(
child: Padding(
padding: const EdgeInsets.all(m12),
child: Form(
key: formKey,
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
TextFormField(
key: _name.fieldKey,
validator: nonEmpty().validator,
textInputAction: TextInputAction.next,
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.words,
onFieldSubmitted: submitForm,
style: const TextStyle(fontSize: 16),
focusNode: _name.focusNode,
controller: _name.controller(),
decoration: InputDecoration(isDense: true, labelText: _name.label, hintText: 'Giuseppe'),
autovalidateMode: AutovalidateMode.onUserInteraction),
const SizedBox(height: m12),
TextFormField(
key: _surname.fieldKey,
validator: nonEmpty().validator,
textInputAction: TextInputAction.next,
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.words,
onFieldSubmitted: submitForm,
style: const TextStyle(fontSize: 16),
focusNode: _surname.focusNode,
controller: _surname.controller(),
decoration: InputDecoration(isDense: true, labelText: _surname.label, hintText: 'Simone'),
autovalidateMode: AutovalidateMode.onUserInteraction),
const SizedBox(height: m12),
NumberFormField(
key: _age.fieldKey,
validator: [nonNull(), gte(18)].validator,
focusNode: _age.focusNode,
textInputAction: TextInputAction.next,
controller: _age.controller(),
decoration: InputDecoration(isDense: true, labelText: _age.label, hintText: '18'),
autovalidateMode: AutovalidateMode.onUserInteraction),
const SizedBox(height: m12),
IntrinsicWidth(
child: ReCaptchaVerifier(
key: _captcha.fieldKey,
siteKey: '6LcgS-4gAAAAAOXzBuqrs1cBD9cyyy4g4bbAZXiR',
validator: (status) {
switch (status) {
case CaptchaStatus.init:
case CaptchaStatus.ready:
case CaptchaStatus.verifying:
case CaptchaStatus.error:
return ' - Verification failed';
case CaptchaStatus.expired:
return ' - Expired';
case CaptchaStatus.verified:
return null;
}
})),
const SizedBox(height: m12),
FileUploadFormField(
key: _id.fieldKey,
focusNode: _id.focusNode,
validator: _fileNonEmpty(_id.label).validator,
decoration: InputDecoration(
isDense: true,
labelText: _id.label,
hintText: 'Upload',
suffixIconConstraints:
const BoxConstraints(minHeight: 52, minWidth: kMinInteractiveDimension * 2)),
autovalidateMode: AutovalidateMode.onUserInteraction),
]))))),
floatingActionButton: FloatingActionButton(onPressed: submitForm, child: const Icon(Icons.add)));
@override
void onFormSubmit() {
DialogRoute(
location: '/result',
builder: (context, args) => AlertDialog(
actions: const [AlertDialogAction.positive()],
content: Text('Result: \n'
' name: ${_name.value}\n'
' surname: ${_surname.value}\n'
' age: ${_age.value!}\n'
' id: ${_id.value?.name}\n'
' captcha: ${_captcha.value}\n'),
)).open(context);
}
static ValidationParam<XFile?> _fileNonEmpty(String field) =>
ValidationParam((value) => value != null, message: 'Field $field required');
}