@@ -500,27 +500,13 @@ class PlanForm extends StatefulWidget {
500
500
class _PlanFormState extends State <PlanForm > {
501
501
final _form = GlobalKey <FormState >();
502
502
503
- bool _onlyLogging = true ;
504
503
GoalType _goalType = GoalType .meals;
505
-
506
- final _descriptionController = TextEditingController ();
507
- final _startDateController = TextEditingController ();
508
- final _endDateController = TextEditingController ();
509
- final TextEditingController colorController = TextEditingController ();
510
-
511
504
GoalType ? selectedGoal;
512
505
513
506
@override
514
507
void initState () {
515
508
super .initState ();
516
509
517
- _onlyLogging = widget._plan.onlyLogging;
518
- _descriptionController.text = widget._plan.description;
519
- _startDateController.text = dateToYYYYMMDD (widget._plan.startDate)! ;
520
- // ignore invalid enddates should the server gives us one
521
- if (widget._plan.endDate != null && widget._plan.endDate! .isAfter (widget._plan.startDate)) {
522
- _endDateController.text = dateToYYYYMMDD (widget._plan.endDate)! ;
523
- }
524
510
if (widget._plan.hasAnyAdvancedGoals) {
525
511
_goalType = GoalType .advanced;
526
512
} else if (widget._plan.hasAnyGoals) {
@@ -530,17 +516,10 @@ class _PlanFormState extends State<PlanForm> {
530
516
}
531
517
}
532
518
533
- @override
534
- void dispose () {
535
- _descriptionController.dispose ();
536
- _startDateController.dispose ();
537
- _endDateController.dispose ();
538
- colorController.dispose ();
539
- super .dispose ();
540
- }
541
-
542
519
@override
543
520
Widget build (BuildContext context) {
521
+ final dateFormat = DateFormat .yMd (Localizations .localeOf (context).languageCode);
522
+
544
523
return Form (
545
524
key: _form,
546
525
child: ListView (
@@ -551,7 +530,9 @@ class _PlanFormState extends State<PlanForm> {
551
530
decoration: InputDecoration (
552
531
labelText: AppLocalizations .of (context).description,
553
532
),
554
- controller: _descriptionController,
533
+ controller: TextEditingController (
534
+ text: widget._plan.description,
535
+ ),
555
536
onSaved: (newValue) {
556
537
widget._plan.description = newValue! ;
557
538
},
@@ -560,10 +541,15 @@ class _PlanFormState extends State<PlanForm> {
560
541
TextFormField (
561
542
key: const Key ('field-start-date' ),
562
543
decoration: InputDecoration (
563
- labelText: AppLocalizations .of (context).start,
564
- hintText: 'YYYY-MM-DD' ,
544
+ labelText: AppLocalizations .of (context).startDate,
545
+ suffixIcon: const Icon (
546
+ Icons .calendar_today,
547
+ key: Key ('calendarIcon' ),
548
+ ),
549
+ ),
550
+ controller: TextEditingController (
551
+ text: dateFormat.format (widget._plan.startDate),
565
552
),
566
- controller: _startDateController,
567
553
readOnly: true ,
568
554
onTap: () async {
569
555
// Stop keyboard from appearing
@@ -579,11 +565,18 @@ class _PlanFormState extends State<PlanForm> {
579
565
580
566
if (pickedDate != null ) {
581
567
setState (() {
582
- _startDateController.text = dateToYYYYMMDD (pickedDate)! ;
583
568
widget._plan.startDate = pickedDate;
584
569
});
585
570
}
586
571
},
572
+ validator: (value) {
573
+ if (widget._plan.endDate != null &&
574
+ widget._plan.endDate! .isBefore (widget._plan.startDate)) {
575
+ return 'End date must be after start date' ;
576
+ }
577
+
578
+ return null ;
579
+ },
587
580
),
588
581
// End Date
589
582
Row (
@@ -593,11 +586,28 @@ class _PlanFormState extends State<PlanForm> {
593
586
key: const Key ('field-end-date' ),
594
587
decoration: InputDecoration (
595
588
labelText: AppLocalizations .of (context).endDate,
596
- hintText: 'YYYY-MM-DD' ,
597
589
helperText:
598
590
'Tip: only for athletes with contest deadlines. Most users benefit from flexibility' ,
591
+ suffixIcon: widget._plan.endDate == null
592
+ ? const Icon (
593
+ Icons .calendar_today,
594
+ key: Key ('calendarIcon' ),
595
+ )
596
+ : IconButton (
597
+ icon: const Icon (Icons .clear),
598
+ tooltip: 'Clear end date' ,
599
+ onPressed: () {
600
+ setState (() {
601
+ widget._plan.endDate = null ;
602
+ });
603
+ },
604
+ ),
605
+ ),
606
+ controller: TextEditingController (
607
+ text: widget._plan.endDate == null
608
+ ? ''
609
+ : dateFormat.format (widget._plan.endDate! ),
599
610
),
600
- controller: _endDateController,
601
611
readOnly: true ,
602
612
onTap: () async {
603
613
// Stop keyboard from appearing
@@ -606,47 +616,30 @@ class _PlanFormState extends State<PlanForm> {
606
616
// Open date picker
607
617
final pickedDate = await showDatePicker (
608
618
context: context,
609
- // if somehow the server has an invalid end date, default to null
610
- initialDate: (widget._plan.endDate != null &&
611
- widget._plan.endDate! .isAfter (widget._plan.startDate))
612
- ? widget._plan.endDate!
613
- : null ,
614
- firstDate: widget._plan.startDate
615
- .add (const Duration (days: 1 )), // end must be after start
619
+ initialDate: widget._plan.endDate,
620
+ // end must be after start
621
+ firstDate: widget._plan.startDate.add (const Duration (days: 1 )),
616
622
lastDate: DateTime (2100 ),
617
623
);
618
624
619
625
if (pickedDate != null ) {
620
626
setState (() {
621
- _endDateController.text = dateToYYYYMMDD (pickedDate)! ;
622
627
widget._plan.endDate = pickedDate;
623
628
});
624
629
}
625
630
},
626
631
),
627
632
),
628
- if (_endDateController.text.isNotEmpty)
629
- IconButton (
630
- icon: const Icon (Icons .clear),
631
- tooltip: 'Clear end date' ,
632
- onPressed: () {
633
- setState (() {
634
- _endDateController.text = '' ;
635
- widget._plan.endDate = null ;
636
- });
637
- },
638
- ),
639
633
],
640
634
),
641
635
SwitchListTile (
642
636
title: Text (AppLocalizations .of (context).onlyLogging),
643
637
subtitle: Text (AppLocalizations .of (context).onlyLoggingHelpText),
644
- value: _onlyLogging ,
638
+ value: widget._plan.onlyLogging ,
645
639
onChanged: (value) {
646
640
setState (() {
647
- _onlyLogging = ! _onlyLogging ;
641
+ widget._plan.onlyLogging = value ;
648
642
});
649
- widget._plan.onlyLogging = value;
650
643
},
651
644
),
652
645
Row (
@@ -658,7 +651,7 @@ class _PlanFormState extends State<PlanForm> {
658
651
const SizedBox (width: 8 ),
659
652
Expanded (
660
653
child: DropdownButtonFormField <GoalType >(
661
- value : _goalType,
654
+ initialValue : _goalType,
662
655
items: GoalType .values
663
656
.map (
664
657
(e) => DropdownMenuItem <GoalType >(
@@ -766,9 +759,6 @@ class _PlanFormState extends State<PlanForm> {
766
759
);
767
760
}
768
761
}
769
-
770
- // Saving was successful, reset the data
771
- _descriptionController.clear ();
772
762
},
773
763
),
774
764
],
0 commit comments