@@ -500,27 +500,13 @@ class PlanForm extends StatefulWidget {
500500class _PlanFormState extends State <PlanForm > {
501501 final _form = GlobalKey <FormState >();
502502
503- bool _onlyLogging = true ;
504503 GoalType _goalType = GoalType .meals;
505-
506- final _descriptionController = TextEditingController ();
507- final _startDateController = TextEditingController ();
508- final _endDateController = TextEditingController ();
509- final TextEditingController colorController = TextEditingController ();
510-
511504 GoalType ? selectedGoal;
512505
513506 @override
514507 void initState () {
515508 super .initState ();
516509
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- }
524510 if (widget._plan.hasAnyAdvancedGoals) {
525511 _goalType = GoalType .advanced;
526512 } else if (widget._plan.hasAnyGoals) {
@@ -530,17 +516,10 @@ class _PlanFormState extends State<PlanForm> {
530516 }
531517 }
532518
533- @override
534- void dispose () {
535- _descriptionController.dispose ();
536- _startDateController.dispose ();
537- _endDateController.dispose ();
538- colorController.dispose ();
539- super .dispose ();
540- }
541-
542519 @override
543520 Widget build (BuildContext context) {
521+ final dateFormat = DateFormat .yMd (Localizations .localeOf (context).languageCode);
522+
544523 return Form (
545524 key: _form,
546525 child: ListView (
@@ -551,7 +530,9 @@ class _PlanFormState extends State<PlanForm> {
551530 decoration: InputDecoration (
552531 labelText: AppLocalizations .of (context).description,
553532 ),
554- controller: _descriptionController,
533+ controller: TextEditingController (
534+ text: widget._plan.description,
535+ ),
555536 onSaved: (newValue) {
556537 widget._plan.description = newValue! ;
557538 },
@@ -560,10 +541,15 @@ class _PlanFormState extends State<PlanForm> {
560541 TextFormField (
561542 key: const Key ('field-start-date' ),
562543 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),
565552 ),
566- controller: _startDateController,
567553 readOnly: true ,
568554 onTap: () async {
569555 // Stop keyboard from appearing
@@ -579,11 +565,18 @@ class _PlanFormState extends State<PlanForm> {
579565
580566 if (pickedDate != null ) {
581567 setState (() {
582- _startDateController.text = dateToYYYYMMDD (pickedDate)! ;
583568 widget._plan.startDate = pickedDate;
584569 });
585570 }
586571 },
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+ },
587580 ),
588581 // End Date
589582 Row (
@@ -593,11 +586,28 @@ class _PlanFormState extends State<PlanForm> {
593586 key: const Key ('field-end-date' ),
594587 decoration: InputDecoration (
595588 labelText: AppLocalizations .of (context).endDate,
596- hintText: 'YYYY-MM-DD' ,
597589 helperText:
598590 '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! ),
599610 ),
600- controller: _endDateController,
601611 readOnly: true ,
602612 onTap: () async {
603613 // Stop keyboard from appearing
@@ -606,47 +616,30 @@ class _PlanFormState extends State<PlanForm> {
606616 // Open date picker
607617 final pickedDate = await showDatePicker (
608618 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 )),
616622 lastDate: DateTime (2100 ),
617623 );
618624
619625 if (pickedDate != null ) {
620626 setState (() {
621- _endDateController.text = dateToYYYYMMDD (pickedDate)! ;
622627 widget._plan.endDate = pickedDate;
623628 });
624629 }
625630 },
626631 ),
627632 ),
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- ),
639633 ],
640634 ),
641635 SwitchListTile (
642636 title: Text (AppLocalizations .of (context).onlyLogging),
643637 subtitle: Text (AppLocalizations .of (context).onlyLoggingHelpText),
644- value: _onlyLogging ,
638+ value: widget._plan.onlyLogging ,
645639 onChanged: (value) {
646640 setState (() {
647- _onlyLogging = ! _onlyLogging ;
641+ widget._plan.onlyLogging = value ;
648642 });
649- widget._plan.onlyLogging = value;
650643 },
651644 ),
652645 Row (
@@ -658,7 +651,7 @@ class _PlanFormState extends State<PlanForm> {
658651 const SizedBox (width: 8 ),
659652 Expanded (
660653 child: DropdownButtonFormField <GoalType >(
661- value : _goalType,
654+ initialValue : _goalType,
662655 items: GoalType .values
663656 .map (
664657 (e) => DropdownMenuItem <GoalType >(
@@ -766,9 +759,6 @@ class _PlanFormState extends State<PlanForm> {
766759 );
767760 }
768761 }
769-
770- // Saving was successful, reset the data
771- _descriptionController.clear ();
772762 },
773763 ),
774764 ],
0 commit comments