From 4b55176b9d7e6939f3439f90405e678ff899fed3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 19 Apr 2020 23:36:11 +0300 Subject: [PATCH] text validation and AppTextField --- lib/routes.dart | 2 +- .../patients/patient_search_screen.dart | 220 +++++------------- lib/util/extenstions.dart | 4 + lib/util/text_validator.dart | 37 +++ lib/widgets/patients/dynamic_elements.dart | 64 ++--- lib/widgets/shared/app_text_form_field.dart | 60 +++++ 6 files changed, 169 insertions(+), 218 deletions(-) create mode 100644 lib/util/text_validator.dart create mode 100644 lib/widgets/shared/app_text_form_field.dart diff --git a/lib/routes.dart b/lib/routes.dart index 9aacf6cb..72e09e56 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -28,7 +28,7 @@ const String MEDICINE_SEARCH = 'medicine-search'; const String SETTINGS = 'settings'; var routes = { - HOME: (_) => DashboardScreen(), + HOME: (_) => PatientSearchScreen(), INIT_ROUTE: (_) => Loginsreen(), MY_SCHEDULE: (_) => MyScheduleScreen(), PATIENT_SEARCH: (_) => PatientSearchScreen(), diff --git a/lib/screens/patients/patient_search_screen.dart b/lib/screens/patients/patient_search_screen.dart index 792e4789..d5a8cb33 100644 --- a/lib/screens/patients/patient_search_screen.dart +++ b/lib/screens/patients/patient_search_screen.dart @@ -1,18 +1,21 @@ - -import 'package:doctor_app_flutter/config/size_config.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_buttons_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart'; -import 'package:doctor_app_flutter/widgets/shared/rounded_container_widget.dart'; +import '../../config/size_config.dart'; +import '../../util/text_validator.dart'; +import '../../widgets/shared/app_buttons_widget.dart'; +import '../../widgets/shared/app_scaffold_widget.dart'; +import '../../widgets/shared/app_text_form_field.dart'; +import '../../widgets/shared/app_texts_widget.dart'; +import '../../widgets/shared/rounded_container_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; - import '../../lookups/patient_lookup.dart'; import '../../models/patient_model.dart'; -import '../../routes.dart'; import '../../widgets/patients/dynamic_elements.dart'; +// OWNER : Ibrahim albitar +// DATE : 19-04-2020 +// DESCRIPTION : Patient Search Screen. + class PatientSearchScreen extends StatefulWidget { @override _PatientSearchScreenState createState() => _PatientSearchScreenState(); @@ -22,7 +25,9 @@ class _PatientSearchScreenState extends State { String _selectedType = '1'; String _selectedLocation = '1'; - final _patientSearchForm = GlobalKey(); + final GlobalKey _formKey = GlobalKey(); + bool _autoValidate = false; + var _patientSearchFormValues = PatientModel( ProjectID: 12, ClinicID: 17, @@ -45,18 +50,18 @@ class _PatientSearchScreenState extends State { IsLoginForDoctorApp: true, PatientOutSA: false); - void _saveForm() { - _patientSearchForm.currentState.save(); - // Navigator.pushNamed(context,routeName) - print(_patientSearchFormValues.From); - print(_patientSearchFormValues.To); - - Navigator.of(context).pushNamed(PATIENTS, arguments: { - 'patientSearchForm': _patientSearchFormValues, - 'selectedType': _selectedType + void _validateInputs() { + if (_formKey.currentState.validate()) { +// If all data are correct then save data to out variables + _formKey.currentState.save(); + } else { +// If all data are not valid then start auto validation. + setState(() { + _autoValidate = true; }); } +} @override Widget build(BuildContext context) { @@ -75,7 +80,8 @@ class _PatientSearchScreenState extends State { padding: EdgeInsets.all(15), width: SizeConfig.screenWidth * 1, child: Form( - key: _patientSearchForm, + key: _formKey, + autovalidate: _autoValidate, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -143,127 +149,47 @@ class _PatientSearchScreenState extends State { SizedBox( height: 10, ), - TextFormField( - decoration: InputDecoration( - hintText: 'First Name', - hintStyle: TextStyle( - fontSize: SizeConfig.textMultiplier * 2), - enabledBorder: OutlineInputBorder( - borderRadius: - BorderRadius.all(Radius.circular(30)), - borderSide: - BorderSide(color: Color(0xff707070)), - ), - focusedBorder: OutlineInputBorder( - borderRadius: - BorderRadius.all(Radius.circular(30)), - borderSide: BorderSide( - color: Theme.of(context).primaryColor), - ) - //BorderRadius.all(Radius.circular(20)); - ), + AppTextFormField( + hintText: 'First Name', onSaved: (value) { _patientSearchFormValues.FirstName = value; }, validator: (value) { - if (value.isEmpty) { - return 'Please enter some text'; - } - return null; + return TextValidator().validateName(value); }, ), SizedBox( height: 10, ), - TextFormField( - decoration: InputDecoration( - hintText: 'Middle Name', - hintStyle: TextStyle( - fontSize: SizeConfig.textMultiplier * 2), - enabledBorder: OutlineInputBorder( - borderRadius: - BorderRadius.all(Radius.circular(30)), - borderSide: - BorderSide(color: Color(0xff707070)), - ), - focusedBorder: OutlineInputBorder( - borderRadius: - BorderRadius.all(Radius.circular(30)), - borderSide: BorderSide( - color: Theme.of(context).primaryColor), - ) - //BorderRadius.all(Radius.circular(20)); - ), - validator: (value) { - if (value.isEmpty) { - return 'Please enter some text'; - } - return null; - }, + AppTextFormField( + hintText: 'Middle Name', onSaved: (value) { _patientSearchFormValues.MiddleName = value; }, + validator: (value) { + return TextValidator().validateName(value); + }, ), SizedBox( height: 10, ), - TextFormField( - decoration: InputDecoration( - hintText: 'Last Name', - hintStyle: TextStyle( - fontSize: SizeConfig.textMultiplier * 2), - enabledBorder: OutlineInputBorder( - borderRadius: - BorderRadius.all(Radius.circular(30)), - borderSide: - BorderSide(color: Color(0xff707070)), - ), - focusedBorder: OutlineInputBorder( - borderRadius: - BorderRadius.all(Radius.circular(30.0)), - borderSide: BorderSide( - color: Theme.of(context).primaryColor), - ) - //BorderRadius.all(Radius.circular(20)); - ), - validator: (value) { - if (value.isEmpty) { - return 'Please enter some text'; - } - return null; - }, + AppTextFormField( + hintText: 'Last Name', onSaved: (value) { _patientSearchFormValues.LastName = value; }, + validator: (value) { + return TextValidator().validateName(value); + }, ), SizedBox( height: 10, ), - TextFormField( - keyboardType: TextInputType.number, - decoration: InputDecoration( - hintText: 'Phone Number', - hintStyle: TextStyle( - fontSize: SizeConfig.textMultiplier * 2), - enabledBorder: OutlineInputBorder( - borderRadius: - BorderRadius.all(Radius.circular(30)), - borderSide: - BorderSide(color: Color(0xff707070)), - ), - focusedBorder: OutlineInputBorder( - borderRadius: - BorderRadius.all(Radius.circular(30.0)), - borderSide: BorderSide( - color: Theme.of(context).primaryColor), - ) - //BorderRadius.all(Radius.circular(20)); - ), + AppTextFormField( + textInputType: TextInputType.number, + hintText: 'Phone Number', validator: (value) { - if (value.isEmpty) { - return 'Please enter some text'; - } - return null; + return TextValidator().validateMobile(value); }, onSaved: (value) { _patientSearchFormValues.PatientMobileNumber = @@ -273,67 +199,27 @@ class _PatientSearchScreenState extends State { SizedBox( height: 10, ), - TextFormField( - keyboardType: TextInputType.number, - decoration: InputDecoration( - hintText: 'Patiant ID', - hintStyle: TextStyle( - fontSize: SizeConfig.textMultiplier * 2), - enabledBorder: OutlineInputBorder( - borderRadius: - BorderRadius.all(Radius.circular(30)), - borderSide: - BorderSide(color: Color(0xff707070)), - ), - focusedBorder: OutlineInputBorder( - borderRadius: - BorderRadius.all(Radius.circular(30.0)), - borderSide: BorderSide( - color: Theme.of(context).primaryColor), - ) - //BorderRadius.all(Radius.circular(20)); - ), + AppTextFormField( + textInputType: TextInputType.number, + hintText: 'Patiant ID', validator: (value) { - if (value.isEmpty) { - return 'Please enter some text'; - } - return null; + return TextValidator().validateIdNumber(value); }, onSaved: (value) { _patientSearchFormValues.PatientID = - int.parse(value); + 89000; }), SizedBox( height: 10, ), - TextFormField( - keyboardType: TextInputType.number, - decoration: InputDecoration( - hintText: 'Patiant File', - hintStyle: TextStyle( - fontSize: SizeConfig.textMultiplier * 2), - enabledBorder: OutlineInputBorder( - borderRadius: - BorderRadius.all(Radius.circular(30)), - borderSide: - BorderSide(color: Color(0xff707070)), - ), - focusedBorder: OutlineInputBorder( - borderRadius: - BorderRadius.all(Radius.circular(30.0)), - borderSide: BorderSide( - color: Theme.of(context).primaryColor), - ) - //BorderRadius.all(Radius.circular(20)); - ), + AppTextFormField( + textInputType: TextInputType.number, + hintText: 'Patiant File', validator: (value) { - if (value.isEmpty) { - return 'Please enter some text'; - } - return null; + return TextValidator().validateIdNumber(value); }, onSaved: (value) { - // _patientSearchFormValues. = value; + //_patientSearchFormValues. = value; }, ), (!(_selectedType == '3' || _selectedType == '5')) @@ -432,7 +318,7 @@ class _PatientSearchScreenState extends State { title: "Search", color: Color(0xff58434F), onPressed: () { - print("Tapped Me"); + _validateInputs(); }, ), ], diff --git a/lib/util/extenstions.dart b/lib/util/extenstions.dart index 26e49670..1c79f01c 100644 --- a/lib/util/extenstions.dart +++ b/lib/util/extenstions.dart @@ -1,3 +1,7 @@ +// OWNER : Ibrahim albitar +// DATE : 19-04-2020 +// DESCRIPTION : Extension for all classes objects. + extension Extension on Object { bool isNullOrEmpty() => this == null || this == ''; diff --git a/lib/util/text_validator.dart b/lib/util/text_validator.dart new file mode 100644 index 00000000..1fe21c9e --- /dev/null +++ b/lib/util/text_validator.dart @@ -0,0 +1,37 @@ + import '../util/extenstions.dart'; + + class TextValidator{ + +// OWNER : Ibrahim albitar +// DATE : 19-04-2020 +// DESCRIPTION : Text Validator. + + String validateName(String value) { + if (value.isNullOrEmpty()||value.length < 3) + return 'Name must be more than 2 charater'; + else + return null; + } + + String validateMobile(String value) { + if (value.isNullOrEmpty()||value.length != 10) + return 'Mobile Number must be of 10 digit'; + else + return null; + } + + String validateIdNumber(String value) { + if (value.isNullOrEmpty()) + return 'Please input valid number'; + else + return null; + } + + String validateDate(String value) { + if (value.isNullOrEmpty()) + return 'Please input valid date'; + else + return null; + } + + } \ No newline at end of file diff --git a/lib/widgets/patients/dynamic_elements.dart b/lib/widgets/patients/dynamic_elements.dart index e181e03b..269cfc69 100644 --- a/lib/widgets/patients/dynamic_elements.dart +++ b/lib/widgets/patients/dynamic_elements.dart @@ -1,10 +1,11 @@ import 'package:doctor_app_flutter/models/patient_model.dart'; +import 'package:doctor_app_flutter/widgets/shared/app_text_form_field.dart'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; +import '../../util/text_validator.dart'; import 'package:intl/intl.dart'; class DynamicElements extends StatefulWidget { - PatientModel _patientSearchFormValues; + final PatientModel _patientSearchFormValues; DynamicElements(this._patientSearchFormValues); @override _DynamicElementsState createState() => _DynamicElementsState(); @@ -40,39 +41,21 @@ class _DynamicElementsState extends State { Widget build(BuildContext context) { return LayoutBuilder( builder: (ctx, constraints) { - var smallScreenSize = 660; - bool isSmallScreen = constraints.maxWidth <= smallScreenSize; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox( height: 10, ), - TextFormField( - keyboardType: TextInputType.number, + AppTextFormField( + textInputType: TextInputType.number, + hintText: 'From', controller: _fromDateController, - decoration: InputDecoration( - hintText: 'From', - hintStyle: TextStyle( - fontSize: - isSmallScreen ? 14 : constraints.maxWidth * 0.024), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(30)), - borderSide: BorderSide(color: Color(0xff707070)), - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(30.0)), - borderSide: - BorderSide(color: Theme.of(context).primaryColor), - ) - //BorderRadius.all(Radius.circular(20)); - ), + onChanged: (value){ + + }, validator: (value) { - if (value.isEmpty) { - return 'Please enter some text'; - } - return null; + return TextValidator().validateDate(value); }, onTap: () { _presentDatePicker('_selectedFromDate'); @@ -85,39 +68,20 @@ class _DynamicElementsState extends State { SizedBox( height: 10, ), - TextFormField( - keyboardType: TextInputType.number, + AppTextFormField( + textInputType: TextInputType.number, + hintText: 'TO', controller: _toDateController, - decoration: InputDecoration( - hintText: 'TO', - hintStyle: TextStyle( - fontSize: - isSmallScreen ? 14 : constraints.maxWidth * 0.024), - enabledBorder: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(30)), - borderSide: BorderSide(color: Color(0xff707070)), - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.all(Radius.circular(30.0)), - borderSide: - BorderSide(color: Theme.of(context).primaryColor), - ) - //BorderRadius.all(Radius.circular(20)); - ), onTap: () { _presentDatePicker('_selectedToDate'); }, validator: (value) { - if (value.isEmpty) { - return 'Please enter some text'; - } - return null; + return TextValidator().validateDate(value); }, onSaved: (value) { widget._patientSearchFormValues.To = value; }, ), - ], ); }, diff --git a/lib/widgets/shared/app_text_form_field.dart b/lib/widgets/shared/app_text_form_field.dart new file mode 100644 index 00000000..97a23098 --- /dev/null +++ b/lib/widgets/shared/app_text_form_field.dart @@ -0,0 +1,60 @@ +import 'package:doctor_app_flutter/config/size_config.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +// OWNER : Ibrahim albitar +// DATE : 19-04-2020 +// DESCRIPTION : Custom Text Form Field for app. + +class AppTextFormField extends FormField { + + AppTextFormField({ + FormFieldSetter onSaved, + FormFieldValidator validator, + ValueChanged onChanged, + GestureTapCallback onTap, + TextEditingController controller, + bool autovalidate = true, + TextInputType textInputType, + String hintText + }) : super( + onSaved: onSaved, + validator: validator, + autovalidate: autovalidate, + builder: (FormFieldState state) { + return Column( + children: [ + TextFormField( + keyboardType: textInputType, + onChanged: onChanged?? (value){ + state.didChange(value); + }, + decoration: InputDecoration( + hintText: hintText, + hintStyle: TextStyle(fontSize: SizeConfig.textMultiplier * 2), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(30)), + borderSide: BorderSide(color: Color(0xff707070)), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.all(Radius.circular(30)), + ) + //BorderRadius.all(Radius.circular(20)); + ), + onTap: onTap, + controller: controller, + + ), + state.hasError? + Text( + state.errorText, + style: TextStyle( + color: Colors.red + ), + ) : + Container() + ], + ); + } + ); +}