2

I have the following below widget:

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

class BirthdayWidget extends StatefulWidget {
  final DateTime birthday;
  final ValueChanged<DateTime> onChangedBirthday;

  const BirthdayWidget({
    Key key,
    @required this.birthday,
    @required this.onChangedBirthday,
  }) : super(key: key);

  @override
  _BirthdayWidgetState createState() => _BirthdayWidgetState();
}

class _BirthdayWidgetState extends State<BirthdayWidget> {
  final controller = TextEditingController();
  final focusNode = FocusNode();

  @override
  void initState() {
    super.initState();

    setDate();
  }

  @override
  void didUpdateWidget(covariant BirthdayWidget oldWidget) {
    super.didUpdateWidget(oldWidget);

    setDate();
  }

  void setDate() => setState(() {
        controller.text = widget.birthday == null
            ? ''
            : DateFormat.yMd().format(widget.birthday);
      });

  @override
  Widget build(BuildContext context) => FocusBuilder(
        onChangeVisibility: (isVisible) {
          if (isVisible) {
            selectDate(context);
            //
          } else {
            FocusScope.of(context).requestFocus(FocusNode());
          }
        },
        focusNode: focusNode,
        builder: (hasFocus) => TextFormField(
          controller: controller,
          validator: (value) => value.isEmpty ? 'Is Required' : null,
          decoration: InputDecoration(
            prefixText: ' ',
            hintText: 'Your birthday',
            prefixIcon: Icon(Icons.calendar_today_rounded),
            border: OutlineInputBorder(),
          ),
        ),
      );

  Future selectDate(BuildContext context) async {
    final birthday = await showDatePicker(
      context: context,
      initialDate: widget.birthday ?? DateTime.now(),
      firstDate: DateTime(1950),
      lastDate: DateTime(2100),
    );

    if (birthday == null) return;

    widget.onChangedBirthday(birthday);
  }
}

class FocusBuilder extends StatefulWidget {
  final FocusNode focusNode;
  final Widget Function(bool hasFocus) builder;
  final ValueChanged<bool> onChangeVisibility;

  const FocusBuilder({
    @required this.focusNode,
    @required this.builder,
    @required this.onChangeVisibility,
    Key key,
  }) : super(key: key);

  @override
  _FocusBuilderState createState() => _FocusBuilderState();
}

class _FocusBuilderState extends State<FocusBuilder> {
  @override
  Widget build(BuildContext context) => GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTap: () => widget.onChangeVisibility(true),
        child: Focus(
          focusNode: widget.focusNode,
          onFocusChange: widget.onChangeVisibility,
          child: widget.builder(widget.focusNode.hasFocus),
        ),
      );
}

and I call this widget through the below code as I call it in a specific screen

Widget buildBirthday() => BirthdayWidget(
        birthday: user.dateOfBirth,
        onChangedBirthday: (dateOfBirth) =>
            setState(() => user = user.copy(dateOfBirth: dateOfBirth)),
      );

so for example I want hide the below Widget if the age below 18:

CustomTextFormField(
            onChanged: (passNo) => setState(
              () => user = user.copy(passportNumber: passNo),
            ),
            userValue: user.passportNumber,
            userFLName: 'Passport Number',
            keyBoardType: TextInputType.number,
          ),

I hope this could be clear enough :)..

Mahmoud Harooney
  • 3,001
  • 5
  • 18
  • 49

1 Answers1

2

Wrap the widget you want to hide inside a Visibility() widget and set the visible value to age>=18

Visibility(
      visible: (DateTime.now().difference(birthday).inDays/365)>=18,
      child: CustomTextFormField(
            onChanged: (passNo) => setState(
              () => user = user.copy(passportNumber: passNo),
            ),
            userValue: user.passportNumber,
            userFLName: 'Passport Number',
            keyBoardType: TextInputType.number,
          ),
),

Suggested Answer by OP:

Edited

So I have found it could be work with the Visibility Widget I have done as the below code:


            if ((DateTime.now().difference(user.dateOfBirth).inDays / 365) >=
                18)
              CustomTextFormField(
                validation: (value) {
                  if (value.isEmpty) {
                    return 'Please enter Passport Number';
                  }
                  return null;
                },
                onChanged: (passNo) => setState(
                  () => user = user.copy(passportNumber: passNo),
                ),
                userValue: user.passportNumber,
                userFLName: 'Passport Number',
                keyBoardType: TextInputType.number,
              ),
MindStudio
  • 402
  • 3
  • 12
  • So what is the syntax then for the `age>=18` how Could I do it :D – Mahmoud Harooney Mar 17 '21 at 17:20
  • I think doesn't work I am trying to solve it and I'll add my answer :) – Mahmoud Harooney Mar 17 '21 at 17:23
  • Please show an actual code snippet instead of a vague description of what the code should look like. This kind of answer isn't very helpful to most readers. – Abion47 Mar 17 '21 at 17:23
  • you would have to calculte the age from the birthday and the current date and store this in a variable – MindStudio Mar 17 '21 at 17:23
  • 1
    @MindStudio what what I am currently doing I think I find the answer here :) https://stackoverflow.com/questions/61249772/how-to-make-age-validation-in-flutter – Mahmoud Harooney Mar 17 '21 at 17:25
  • @MindStudio I need another widget to be hide :) not the calendar one – Mahmoud Harooney Mar 17 '21 at 17:31
  • @MahmoudHarooney Ah yeah sorry, may bad – MindStudio Mar 17 '21 at 17:32
  • @MindStudio need the `CustomTextFormField` :) – Mahmoud Harooney Mar 17 '21 at 17:33
  • @MindStudio I see the edit but the problem how can I refer the age one then :D – Mahmoud Harooney Mar 17 '21 at 17:34
  • @MindStudio I mean the age it's looks like this code `DateTime age;` – Mahmoud Harooney Mar 17 '21 at 17:43
  • 1
    @MahmoudHarooney Updated again. You should be able to access your `DateTime birthday` and from that calculate the age. – MindStudio Mar 17 '21 at 17:44
  • @MindStudio thanks a lot for your support :), but I have did something like this in visibility `visible: (DateTime.now().difference(user.dateOfBirth).inDays / 365) >= 18,`, but I found this error `The getter 'microsecondsSinceEpoch' was called on null. Receiver: null Tried calling: microsecondsSinceEpoch` :(, do. you have any Idea about this error :) – Mahmoud Harooney Mar 17 '21 at 19:06
  • @MahmoudHarooney you have to initialize `birthday` first. So when you just say `final DateTime birthday` it is just null. Do `DateTime birthday = new DateTime()` instead. – MindStudio Mar 17 '21 at 20:18
  • @MindStudio how about the argumeny in the DateTime it gonna give syntax error should be one argument – Mahmoud Harooney Mar 17 '21 at 20:55
  • @MahmoudHarooney Then you should provide a value. You have to initialize the variable with any value so that it is not null. you can use `DateTime.now()` instead of `DateTime()` but it looks like you want to display a value before it is there. – MindStudio Mar 17 '21 at 22:39
  • @MindStudio I see different error then when trying to select the birth of date from claendar :) `setState() or markNeedsBuild() called during build.` seems to beed needs await? – Mahmoud Harooney Mar 17 '21 at 22:52
  • @MindStudio thanks for your support I found the solution may be shall I edit your Answer to the right answer – Mahmoud Harooney Mar 17 '21 at 23:37