Added simple validators

This commit is contained in:
Thomas Klein Langenhorst 2022-10-14 15:32:08 +02:00
parent 9b7cbf4d69
commit 38b0e0801c
3 changed files with 179 additions and 48 deletions

View file

@ -0,0 +1,13 @@
import 'package:flutter/foundation.dart';
class AddressController extends ChangeNotifier {
final String zipcode;
final int houseNumber;
final String prefix;
final String street;
final String city;
AddressController(this.zipcode, this.houseNumber, this.prefix, this.street, this.city);
}

View file

@ -1,8 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter_address_form/src/models/address.dart';
class AddressForm extends StatefulWidget { class AddressForm extends StatefulWidget {
AddressForm({Key? key}) : super(key: key); const AddressForm({Key? key}) : super(key: key);
@override @override
State<AddressForm> createState() => _AddressFormState(); State<AddressForm> createState() => _AddressFormState();
@ -10,58 +10,146 @@ class AddressForm extends StatefulWidget {
class _AddressFormState extends State<AddressForm> { class _AddressFormState extends State<AddressForm> {
final TextEditingController _zipcodeController = TextEditingController(); final TextEditingController _zipcodeController = TextEditingController();
final TextEditingController _houseNumberController = TextEditingController();
final TextEditingController _prefixController = TextEditingController();
final TextEditingController _streetController = TextEditingController();
final TextEditingController _cityController = TextEditingController();
final RegExp _zipcodeRegExp = RegExp(r'^[1-9][0-9]{3}\s?[a-zA-Z]{2}$'); final RegExp _zipcodeRegExp = RegExp(r'^[1-9][0-9]{3}\s?[a-zA-Z]{2}$');
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Form( return Column(
child: Column( children: [
children: [ AddressFormTextField(
_createField( controller: _zipcodeController,
label: 'Postcode', validator: (text) {
controller: _zipcodeController, if (text.isEmpty) {
return 'Can\'t be empty';
}
if (!_zipcodeRegExp.hasMatch(text)) {
return 'Invalid zipcode';
}
return null;
},
label: 'Postcode',
),
Flexible(
child: Row(
children: [
AddressFormTextField(
controller: _houseNumberController,
validator: (text) {
if (text.isEmpty) {
return 'Can\'t be empty';
}
if (text.length >= 3 || int.tryParse(text) == null) {
return 'Invalid number';
}
return null;
},
label: 'Huisnummer',
),
AddressFormTextField(
controller: _prefixController,
validator: (text) {
if (text.isEmpty) {
return 'Can\'t be empty';
}
if (RegExp(r'/^[a-z]*$/').hasMatch(text) &&
text.length != 1) {
return 'Invalid prefix';
}
return null;
},
label: 'Toevoeging',
),
],
), ),
Flexible( ),
child: Row( AddressFormTextField(
children: [ controller: _streetController,
_createField( validator: (text) {
label: 'Huisnummer', if (text.isEmpty) {
controller: TextEditingController(), return 'Can\'t be empty';
), }
_createField( return null;
label: 'Toevoeging', },
controller: TextEditingController(), label: 'Straatnaam',
), ),
], AddressFormTextField(
), controller: _cityController,
), validator: (text) {
_createField( if (text.isEmpty) {
label: 'Straatnaam', return 'Can\'t be empty';
controller: TextEditingController(), }
), return null;
_createField( },
label: 'Woonplaats', label: 'Woonplaats',
controller: TextEditingController(), ),
) TextButton(
], onPressed: () {},
), child: Text('Test'),
)
],
); );
} }
Widget _createField( @override
{required String label, required TextEditingController controller}) { void dispose() {
return Flexible( _zipcodeController.dispose();
child: Container( _houseNumberController.dispose();
margin: const EdgeInsets.all(10), _prefixController.dispose();
child: TextFormField( _streetController.dispose();
validator: (value) { _cityController.dispose();
print(_zipcodeRegExp.hasMatch(value!)); super.dispose();
}, }
decoration: InputDecoration( }
label: Text(label),
border: const OutlineInputBorder(), class AddressFormTextField extends StatefulWidget {
), final String label;
), final TextEditingController controller;
), final String? Function(String) validator;
); AddressFormTextField({
Key? key,
required this.label,
required this.controller,
required this.validator,
}) : super(key: key);
@override
State<AddressFormTextField> createState() => _AddressFormTextFieldState();
}
class _AddressFormTextFieldState extends State<AddressFormTextField> {
final Address addressModel = Address();
String? get _errorText {
final text = widget.controller.value.text;
return widget.validator(text);
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return ValueListenableBuilder<TextEditingValue>(
valueListenable: widget.controller,
builder: (context, value, _) {
return Flexible(
child: Container(
margin: const EdgeInsets.all(10),
child: TextField(
controller: widget.controller,
decoration: InputDecoration(
label: Text(widget.label),
border: const OutlineInputBorder(),
errorText: _errorText),
),
),
);
});
} }
} }

View file

@ -0,0 +1,30 @@
class Address {
Address({
this.zipcode,
this.street,
this.housenumber,
this.suffix,
this.city,
});
final String? zipcode;
final String? street;
final int? housenumber;
final String? suffix;
final String? city;
Address copyWith({
String? zipcode,
String? street,
int? housenumber,
String? suffix,
String? city,
}) =>
Address(
zipcode: zipcode ?? this.zipcode,
street: street ?? this.street,
housenumber: housenumber ?? this.housenumber,
suffix: suffix ?? this.suffix,
city: city ?? this.city,
);
}