From 1e1a8c38cb2dbeaab66ff71e9317889e5b5ebbfd Mon Sep 17 00:00:00 2001 From: Maximilian Betz <Maximilian.Betz@awi.de> Date: Fri, 11 Mar 2022 12:42:45 +0100 Subject: [PATCH] enhanced input validation --- lib/addevent.dart | 182 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 142 insertions(+), 40 deletions(-) diff --git a/lib/addevent.dart b/lib/addevent.dart index b937338..8a15494 100644 --- a/lib/addevent.dart +++ b/lib/addevent.dart @@ -20,8 +20,6 @@ class _AddEventPageState extends State<AddEvent> { late String alt = ""; late double accuracy = 0.0; late StreamSubscription<Position> streamHandler; //For canceling GNSS stream on dispose - bool _labelValidate = false; - bool _descriptionValidate = false; Future startGNSS() async { debugPrint("Check Location Permission"); @@ -100,13 +98,58 @@ class _AddEventPageState extends State<AddEvent> { super.dispose(); } + bool _validateLatitude(value){ + if (value == ""){ + return true; //Empty string is valid + } + var number = num.tryParse(value); + if(number != null){ + if (number >= -90.0 && number <= 90.0){ + return true; // Latitude valid + } + } + return false; + } + + bool _validateLongitude(value){ + if (value == ""){ + return true; //Empty string is valid + } + var number = num.tryParse(value); + if(number != null){ + if (number >= -180.0 && number <= 180.0){ + return true; // Longitude valid + } + } + return false; + } + + bool _validateElevation(value){ + if (value == ""){ + return true; //Empty string is valid + } + var number = num.tryParse(value); + if(number != null){ + return true; // Any numerical value is valid for elevation + } + return false; + } + bool _validateInput(){ final EventStoreInstance eventsStore = EventStoreInstance(); if (RegExp(r'^[a-z A-Z . \- 0-9 , ( ) + - _ :]+$').hasMatch( eventsStore.currentEvent.label)) { if (RegExp(r'^[a-z A-Z . \- 0-9 , ( ) + - _ :]+$').hasMatch( eventsStore.currentEvent.description)) { - return true; + if(_validateLatitude(eventsStore.currentEvent.latitude)){ + if(_validateLongitude(eventsStore.currentEvent.longitude)){ + if(_validateElevation(eventsStore.currentEvent.elevation)){ + debugPrint('All inputs valid'); + return true; + + } + } + } } } return false; @@ -185,11 +228,8 @@ class _AddEventPageState extends State<AddEvent> { validator: (value) { if (!RegExp(r'^[a-z A-Z . \- 0-9 , ( ) + - _ :]+$').hasMatch( value!)) { - _labelValidate = false; return "Only: a-z , A-Z , _ , 0-9 , ,(Comma) , ( , ) , + , - , . , :"; } else { - _labelValidate = true; - //eventsStore.currentEvent.label = value; return null; // Entered Text is valid } }, @@ -249,10 +289,8 @@ class _AddEventPageState extends State<AddEvent> { validator: (value) { if (!RegExp(r'^[a-z A-Z . \- 0-9 , ( ) + - _ :]+$').hasMatch( value!)) { - _descriptionValidate = false; return "Only: a-z , A-Z , _ , 0-9 , ,(Comma) , ( , ) , + , - , . , :"; } else { - _descriptionValidate = true; //eventsStore.currentEvent.label = value; return null; // Entered Text is valid } @@ -302,46 +340,102 @@ class _AddEventPageState extends State<AddEvent> { ), const SizedBox(height: 15.0), TextFormField( - readOnly: false, - enabled: !syncGNSSData, - controller: TextEditingController( - text: eventsStore.currentEvent.latitude.toString()), - decoration: const InputDecoration( - labelText: 'Latitude', - border: OutlineInputBorder(), - ), - onChanged: (value) { - eventsStore.currentEvent.latitude = value; + readOnly: false, + enabled: !syncGNSSData, + keyboardType: TextInputType.number, + autovalidateMode: AutovalidateMode.onUserInteraction, + controller: TextEditingController( + text: eventsStore.currentEvent.latitude.toString()), + decoration: const InputDecoration( + labelText: 'Latitude', + border: OutlineInputBorder(), + ), + onChanged: (value) { + eventsStore.currentEvent.latitude = value; + }, + onFieldSubmitted: (value){ + if (!syncGNSSData) { + setState(() {}); + } + }, + validator: (value) { + if (value == "") { + return null; // Empty value is allowed + } + final number = num.tryParse(value!); + if (number != null){ + if (number >= -90.0 && number <= 90.0){ + return null; // Latitude valid + } } + return "-90 => Latitude <= +90"; + }, ), const SizedBox(height: 15.0), TextFormField( - readOnly: false, - enabled: !syncGNSSData, - controller: TextEditingController( - text: eventsStore.currentEvent.longitude.toString()), - decoration: const InputDecoration( - labelText: 'Longitude', - border: OutlineInputBorder(), + readOnly: false, + enabled: !syncGNSSData, + keyboardType: TextInputType.number, + autovalidateMode: AutovalidateMode.onUserInteraction, + controller: TextEditingController( + text: eventsStore.currentEvent.longitude.toString()), + decoration: const InputDecoration( + labelText: 'Longitude', + border: OutlineInputBorder(), - ), - onChanged: (value) { - eventsStore.currentEvent.longitude = value; + ), + onChanged: (value) { + eventsStore.currentEvent.longitude = value; + }, + onFieldSubmitted: (value){ + if (!syncGNSSData) { + setState(() {}); + } + }, + validator: (value) { + if (value == "") { + return null; // Empty value is allowed } + final number = num.tryParse(value!); + if (number != null){ + if (number >= -180.0 && number <= 180.0){ + return null; // Longitude valid + } + } + return "-180 => Longitude <= +180"; + }, + ), const SizedBox(height: 15.0), TextFormField( - readOnly: false, - enabled: !syncGNSSData, - controller: TextEditingController( - text: eventsStore.currentEvent.elevation.toString()), - decoration: const InputDecoration( - labelText: 'Elevation', - border: OutlineInputBorder(), - ), - onChanged: (value) { - eventsStore.currentEvent.elevation = value; + readOnly: false, + enabled: !syncGNSSData, + keyboardType: TextInputType.number, + autovalidateMode: AutovalidateMode.onUserInteraction, + controller: TextEditingController( + text: eventsStore.currentEvent.elevation.toString()), + decoration: const InputDecoration( + labelText: 'Elevation', + border: OutlineInputBorder(), + ), + onChanged: (value) { + eventsStore.currentEvent.elevation = value; + }, + onFieldSubmitted: (value){ + if (!syncGNSSData) { + setState(() {}); + } + }, + validator: (value) { + if (value == "") { + return null; // Empty value is allowed } + final number = num.tryParse(value!); + if (number != null){ + return null; // Elevation valid + } + return "Only numerical values for elevation in [m]"; + }, ), ] ), @@ -368,8 +462,13 @@ class _AddEventPageState extends State<AddEvent> { child: _validateInput() ? FloatingActionButton( onPressed: () { - _storeCurrentEvent(); - HapticFeedback.vibrate(); + if (_validateInput()) { + _storeCurrentEvent(); + HapticFeedback.vibrate(); + } + else { + setState(() {}); + } }, tooltip: 'Add Event', child: const Icon(Icons.check), @@ -378,6 +477,9 @@ class _AddEventPageState extends State<AddEvent> { enableFeedback: false, backgroundColor: Colors.grey, onPressed: () { + setState(() { + //refresh the UI + }); }, tooltip: 'Correct Inputs before adding the Event', //child: const Icon(Icons.check), -- GitLab