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/widgets.dart';
import 'package:flutter_address_form/src/models/address.dart';
class AddressForm extends StatefulWidget {
AddressForm({Key? key}) : super(key: key);
const AddressForm({Key? key}) : super(key: key);
@override
State<AddressForm> createState() => _AddressFormState();
@ -10,58 +10,146 @@ class AddressForm extends StatefulWidget {
class _AddressFormState extends State<AddressForm> {
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}$');
@override
Widget build(BuildContext context) {
return Form(
child: Column(
children: [
_createField(
label: 'Postcode',
controller: _zipcodeController,
return Column(
children: [
AddressFormTextField(
controller: _zipcodeController,
validator: (text) {
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(
children: [
_createField(
label: 'Huisnummer',
controller: TextEditingController(),
),
_createField(
label: 'Toevoeging',
controller: TextEditingController(),
),
],
),
),
_createField(
label: 'Straatnaam',
controller: TextEditingController(),
),
_createField(
label: 'Woonplaats',
controller: TextEditingController(),
)
],
),
),
AddressFormTextField(
controller: _streetController,
validator: (text) {
if (text.isEmpty) {
return 'Can\'t be empty';
}
return null;
},
label: 'Straatnaam',
),
AddressFormTextField(
controller: _cityController,
validator: (text) {
if (text.isEmpty) {
return 'Can\'t be empty';
}
return null;
},
label: 'Woonplaats',
),
TextButton(
onPressed: () {},
child: Text('Test'),
)
],
);
}
Widget _createField(
{required String label, required TextEditingController controller}) {
return Flexible(
child: Container(
margin: const EdgeInsets.all(10),
child: TextFormField(
validator: (value) {
print(_zipcodeRegExp.hasMatch(value!));
},
decoration: InputDecoration(
label: Text(label),
border: const OutlineInputBorder(),
),
),
),
);
@override
void dispose() {
_zipcodeController.dispose();
_houseNumberController.dispose();
_prefixController.dispose();
_streetController.dispose();
_cityController.dispose();
super.dispose();
}
}
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,
);
}