Flutter Datepicker validation - how to solve the problem - flutter

In my class I have a date range picker and I have other fields I have used Form validation is working for other fields but I don't know how to declare the validation when the user submits the form if the dates are not chosen it should display the error like choose date.
Also, I wanted to check: let's say I have two class in main class I have declared the form and in sub class also I have declared but in second class I don't have button but in main class I have button how to refer?
Display the date choosen or else it will display the default text:
String _displayText(String begin, DateTime? date) {
if (date != null) {
return '$begin Date: ${date.toString().split(' ')[0]}';
} else {
return 'Press the button to show the picker';
}
}
Text will display:
Text(
_displayText('Start', startdate),
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 15,
color: Colors.black),
),
ShowDateRangepicker
void _show() async {
final DateTimeRange? result = await showDateRangePicker(
context: context,
firstDate: DateTime(DateTime.now().year - 10),
lastDate: DateTime(DateTime.now().year + 10),
currentDate: DateTime.now(),
saveText: 'Done.',
);
if (result != null) {
setState(() {
print(result.start);
startdate = result.start;
enddate = result.end;
_selectedDateRange = result;
});
}
}

Related

How can I remove a particular list entry from a list

DeleteStudent(BuildContext context) {
if (stuEnroll.isEmpty || stuName.isEmpty) {
const snackBar = SnackBar(
content: Text(
'Please enter all fields',
style: TextStyle(fontSize: 15, color: Color(0xffF36501)),
),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
} else {
print('Name=== $stuName');
print('Enroll==== $stuEnroll');
// DatabaseReference postListRef = FirebaseDatabase.instance.ref("Students");
// Future<void> newPostRef = postListRef.remove();
final recentPostsRef =
FirebaseDatabase.instance.ref('Students/').equalTo(stuEnroll);
print('RECENT POST REF === $recentPostsRef');
recentPostsRef.remove();
// newPostRef.remove();
Navigator.push(
context,
MaterialPageRoute(builder: (BuildContext context) => AlterStudent()),
);
StuNameController.text = '';
stuEnrollController.text = '';
setStuEnroll('');
setStuName('');
}
}
When I use this code, all items under the title Students get removed. However, I want only that particular list to get removed which has the student enrolment number equal to stuEnroll. How can I do that?
If you want you can apply the filter in this code. For this you can use
CollectionReference noticeCollection =
FirebaseFirestore.instance.collection('Students').where('enrollmentnumber', isNotEqualTo: stuEnroll);
Also if you want you can apply filter in view side as if enrollmentnumber equals stuEnroll, return null else return (Whatever view you want)

Validate date of birth in Flutter

I've created a form using Flutter which has date picker.
User is supposed to pick his/her date of birth using it to make sure if the user is 16 and above. How do I validate date of birth to age 16?
Here are the parts of the code:
class _WelcomeScreenState extends State<WelcomeScreen> {
TextEditingController dateinput = TextEditingController();
final formKey = GlobalKey<FormState>();
String name = "";
#override
void initState() {
dateinput.text = ""; //set the initial value of text field
super.initState();
}
--
GestureDetector(
child: TextField(
style: TextStyle(color: Colors.white),
controller:
dateinput, //editing controller of this TextField
decoration: InputDecoration(
labelStyle: TextStyle(color: Colors.white),
icon: Icon(Icons.calendar_today),
iconColor: Colors.white, //icon of text field
labelText: "Enter Date Of Birth" //label text of field
),
readOnly:
true, //set it true, so that user will not able to edit text
onTap: () async {
DateTime? pickedDate = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(
1900), //DateTime.now() - not to allow to choose before today.
lastDate: DateTime(2040));
if (pickedDate != null) {
print(
pickedDate); //pickedDate output format => 2021-03-10 00:00:00.000
String formattedDate =
DateFormat('dd-MM-yyyy').format(pickedDate);
print(
formattedDate); //formatted date output using intl package => 2021-03-16
//you can implement different kind of Date Format here according to your requirement
setState(() {
dateinput.text =
formattedDate; //set output date to TextField value.
});
} else {
print("Date is not selected");
}
},
),
),
A naive approach would be to just construct a DateTime object from the selected birth date and to then compute DateTime.now().difference(birthDate).inDays / 365. That doesn't account for leap days, and maybe it's close enough, but it's not how a human would compute age.
When attempting to solve a programming problem, one of the first things you usually should ask yourself is: How would you solve this without a computer?
To determine if someone is at least 16 years old, you would take the current date, subtract 16 from the year, use the same month and day1, and see if their birthday is on or before that date, ignoring the time. So just do that:
extension IsAtLeastYearsOld on DateTime {
bool isAtLeastYearsOld(int years) {
var now = DateTime.now();
var boundaryDate = DateTime(now.year - years, now.month, now.day);
// Discard the time from [this].
var thisDate = DateTime(year, month, day);
// Did [thisDate] occur on or before [boundaryDate]?
return thisDate.compareTo(boundaryDate) <= 0;
}
}
void main() {
// The results below were obtained with 2022-06-11 as the current date.
print(DateTime(2006, 6, 10).isAtLeastYearsOld(16)); // Prints: true
print(DateTime(2006, 6, 11).isAtLeastYearsOld(16)); // Prints: true
print(DateTime(2006, 6, 12).isAtLeastYearsOld(16)); // Prints: false
}
1 This should be fine even if the current date is a leap day since DateTime will convert February 29 into March 1 for non-leap years.
With a function for calculate :
class _WelcomeScreenState extends State<WelcomeScreen> {
TextEditingController dateinput = TextEditingController();
final formKey = GlobalKey<FormState>();
String name = "";
#override
void initState() {
dateinput.text = ""; //set the initial value of text field
super.initState();
}
int calculateAge(DateTime birthDate) {
DateTime currentDate = DateTime.now();
int age = currentDate.year - birthDate.year;
if (birthDate.month > currentDate.month) {
age--;
} else if (currentDate.month == birthDate.month) {
if (birthDate.day > currentDate.day) {
age--;
}
}
return age;
}
}
And in your TextField :
GestureDetector(
child: TextFormField(
style: TextStyle(color: Colors.white),
controller: dateinput, //editing controller of this TextField
decoration: InputDecoration(
labelStyle: TextStyle(color: Colors.white),
icon: Icon(Icons.calendar_today),
iconColor: Colors.white, //icon of text field
labelText: "Enter Date Of Birth" //label text of field
),
readOnly: true, //set it true, so that user will not able to edit text
validator: (value) {
if (calculateAge(DateTime.parse(value)) < 16 || value.isEmpty) {
return 'Please enter date.';
}
return null;
},
onTap: () async {
DateTime? pickedDate = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(1900), //DateTime.now() - not to allow to choose before today.
lastDate: DateTime(2040));
if (pickedDate != null) {
print(pickedDate); //pickedDate output format => 2021-03-10 00:00:00.000
String formattedDate = DateFormat('dd-MM-yyyy').format(pickedDate);
print(formattedDate); //formatted date output using intl package => 2021-03-16
//you can implement different kind of Date Format here according to your requirement
setState(() => dateinput.text = formattedDate);
} else {
print("Date is not selected");
}
},
),
),

Flutter get date format from locale to show as hint text

I have a form text field for which on tap I'm showing the flutter's datepicker. Currently I'm showing the hint text with hard coded value.
But now I have decided to format the date based on the selected locale and hence I'm passing the local information to ShowDatePicker. How can I show the date format based on the selected locale as hint text in the text field by removing hard coded value?
Ex:
#override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
child: TextField(
label: label,
hintText: 'MM-dd-yyyy', //Get the format based on selected local to show as hint
controller: selectedDate,
onTap: () async {
final DateTime? pickedDate = await _getSelectedDate(context);
if (pickedDate != null) {
selectedDate?.text = DateFormat('MM-dd-yyyy')
.format(pickedDate)
.toString();
}
},
),
),
],
);
}
Future<DateTime?> _getSelectedDate(BuildContext context) {
return showDatePicker(
context: context,
locale: context.currentLocale, // Selected locale being passed to showDatePicker
initialDate: DateTime.now(),
firstDate: firstDate,
lastDate: lastDate,
}
First of all get the package for it:
intl: ^0.17.0
import
import 'package:intl/intl.dart';
Define a variable like this:
final DateFormat formatter = DateFormat('MM-dd-yyyy');
hintText:"${formatter.format(DateTime.now())}"
This will show date as hint like this:
02-22-2022(mm-dd-yyyy)

Reuse Datepicker for different field values

I'm trying to make my datepicker reusable, as I need three datepickers, that change different values that are stored in the same class, lets call it _object.date1 , date 2, date 3
To reuse my datepicker I tried the following and passed the variable to the datepicker that shall be changed. But then the field value isn't changed or stored and nothing happens, also no error. If I don't pass the value to _showAndroidDatePicker() and use the line in setState that I commented out below, it works properly. The Datepicker ist linked to the onTap of a TextFormField in a Form.
Can anyone explain to me what I'm missing here? It would be really great to make this reusable.
Many thanks!
void _showAndroidDatePicker(value) {
showDatePicker(
context: context,
builder: (BuildContext context, Widget child) {
return Theme(
data: ThemeData.light().copyWith(
primaryColor: Theme.of(context).primaryColor,
accentColor: Theme.of(context).primaryColor,
colorScheme:
ColorScheme.light(primary: Theme.of(context).primaryColor),
buttonTheme: ButtonThemeData(textTheme: ButtonTextTheme.primary),
),
child: child,
);
},
initialDate: DateTime.now(),
locale: Locale('de'),
firstDate: DateTime(1900),
helpText: 'Bitte wähle ein Datum aus',
lastDate: DateTime.now(),
).then<DateTime>(
(DateTime newDate) {
if (newDate != null) {
setState(() {
value = newDate.toIso8601String();
//Below code works if value isn't passed to datepicker, but I want it variable to avoid boilerplate
// _object.date1 =newDate.toIso8601String();
});
}
return;
},
);
}
Many thanks for your help!
You could pass it the controller and the focus node for the text field. Something like this:
datePickerListener(node, controller) {
if (node.hasFocus) {
node.unfocus();
showDatePicker(your setup).then((date){
var formatter = DateFormat('dd/MM/yyyy');
var formatted = formatter.format(date).toString();
controller.text = formatted;
});
}
}
Then:
FocusNode yourNode = FocusNode();
#override
void initState(){
yourNode.addListener(){
datePickerListener(yourNode, yourController);
};
}
TextFormField(
focusNode: yourNode,
controller: yourController,
)
Something like that. Just adjust to your needs.

Is there any way to print all selected dates in date-range-picker instead of it first and last dates in flutter?

I'm trying to print all selected dates in date range picker, is there anyway to do it?
here is my code
import 'package:flutter/material.dart';
import 'package:date_range_picker/date_range_picker.dart' as DateRagePicker;
class TryCalendar extends StatefulWidget {
#override
_TryCalendarState createState() => _TryCalendarState();
}
class _TryCalendarState extends State<TryCalendar> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
),
body: new MaterialButton(
color: Color(0xFFED7D31),
onPressed: () async {
final List<DateTime> picked = await DateRagePicker.showDatePicker(
context: context,
initialFirstDate: new DateTime.now(),
initialLastDate: (new DateTime.now()).add(new Duration(days: 7)),
firstDate: new DateTime(2015),
lastDate: new DateTime(2020)
);
if (picked != null && picked.length == 2) {
print(picked);
}
},
child: new Text("Pick date range")
)
);
}
}
I need to print all selected dates instead of first and last selected dates. Thank you!
List<DateTime> getDaysInBeteween(DateTime startDate, DateTime endDate) {
List<DateTime> days = [];
for (int i = 0; i <= endDate.difference(startDate).inDays; i++) {
days.add(startDate.add(Duration(days: i)));
}
return days;
}
picked is list of DateTime , so you should iterate every date in list then print
if (picked != null && picked.length >= 2) {
picked.forEach((date) {
print(date.toString());
});
}