mirror of
https://github.com/Iconica-Development/flutter_address_form.git
synced 2025-05-19 10:43:45 +02:00
Added simple validators
This commit is contained in:
parent
9b7cbf4d69
commit
38b0e0801c
3 changed files with 179 additions and 48 deletions
13
lib/src/address_controller.dart
Normal file
13
lib/src/address_controller.dart
Normal 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);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -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: [
|
||||||
_createField(
|
AddressFormTextField(
|
||||||
label: 'Postcode',
|
|
||||||
controller: _zipcodeController,
|
controller: _zipcodeController,
|
||||||
|
validator: (text) {
|
||||||
|
if (text.isEmpty) {
|
||||||
|
return 'Can\'t be empty';
|
||||||
|
}
|
||||||
|
if (!_zipcodeRegExp.hasMatch(text)) {
|
||||||
|
return 'Invalid zipcode';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
label: 'Postcode',
|
||||||
),
|
),
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
_createField(
|
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',
|
label: 'Huisnummer',
|
||||||
controller: TextEditingController(),
|
|
||||||
),
|
),
|
||||||
_createField(
|
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',
|
label: 'Toevoeging',
|
||||||
controller: TextEditingController(),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
_createField(
|
AddressFormTextField(
|
||||||
|
controller: _streetController,
|
||||||
|
validator: (text) {
|
||||||
|
if (text.isEmpty) {
|
||||||
|
return 'Can\'t be empty';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
label: 'Straatnaam',
|
label: 'Straatnaam',
|
||||||
controller: TextEditingController(),
|
|
||||||
),
|
),
|
||||||
_createField(
|
AddressFormTextField(
|
||||||
|
controller: _cityController,
|
||||||
|
validator: (text) {
|
||||||
|
if (text.isEmpty) {
|
||||||
|
return 'Can\'t be empty';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
label: 'Woonplaats',
|
label: 'Woonplaats',
|
||||||
controller: TextEditingController(),
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {},
|
||||||
|
child: Text('Test'),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _createField(
|
@override
|
||||||
{required String label, required TextEditingController controller}) {
|
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(
|
return Flexible(
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: const EdgeInsets.all(10),
|
margin: const EdgeInsets.all(10),
|
||||||
child: TextFormField(
|
child: TextField(
|
||||||
validator: (value) {
|
controller: widget.controller,
|
||||||
print(_zipcodeRegExp.hasMatch(value!));
|
|
||||||
},
|
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
label: Text(label),
|
label: Text(widget.label),
|
||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
),
|
errorText: _errorText),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
30
lib/src/models/address.dart
Normal file
30
lib/src/models/address.dart
Normal 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,
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in a new issue