showModalDatePicker function

Future showModalDatePicker(
  1. BuildContext context,
  2. DateTime cd
)

Implementation

Future<dynamic> showModalDatePicker(BuildContext context, DateTime cd) async {
  Completer completer = new Completer();
  ValueNotifier<String> displayMonth = ValueNotifier("");
  ValueNotifier<String> displayYear = ValueNotifier("");
  ValueNotifier<String> displayDay = ValueNotifier("");
  ValueNotifier<String> displayDayName = ValueNotifier("");
  ValueNotifier<int> selectedIndex = ValueNotifier(-1);
  ValueNotifier<int> selectedMonth = ValueNotifier(-1);
  List<String> days = ["M", "T", "W", "T", "F", "S", "S"];
  DateTime currentDate = cd;
  bool isEditMode = false;
  final selectedDateController = TextEditingController(text: "");
  ValueNotifier<int> errorState = ValueNotifier(0);
  Color textDark = Color(0xff101F53);
  Color textLight = Color(0xff2F3D70);
  Color purple = Color(0xff8A7BFC);
  Color grayLight2 = Color(0xffF0F5F5);
  Color grayLight = Color(0xffB6C0C9);

  void initData() {
    displayYear.value = currentDate.year.toString();
    displayDay.value = currentDate.day.toString() + ". ";
    displayMonth.value = currentDate.getMonthString();
    selectedMonth.value = currentDate.month;
    displayDayName.value = currentDate.getDayOfTheWeekString();

    //calculate first day of month
    DateTime firstDayOfMonth = DateTime(currentDate.year, currentDate.month, 1);
    int ofSet = firstDayOfMonth.weekday - 1;
    days.clear();
    days = ["M", "T", "W", "T", "F", "S", "S"];
    for (int i = 0; i < ofSet; i++) {
      days.add("0");
    }

    //calculate days of month
    DateTime date = new DateTime(currentDate.year, currentDate.month, 0);
    selectedDateController.text = (currentDate.day < 10
            ? "0" + currentDate.day.toString()
            : currentDate.day.toString()) +
        "." +
        (currentDate.month < 10
            ? "0" + currentDate.month.toString()
            : currentDate.month.toString()) +
        "." +
        currentDate.year.toString();
    for (int i = 1; i <= date.day; i++) {
      days.add(i.toString());
    }
    selectedIndex.value = -1;
    selectedIndex.value = days.indexOf(currentDate.day.toString());
  }

  initData();

  showModalBottomSheet(
      context: context,
      isDismissible: true,
      isScrollControlled: true,
      shape: const RoundedRectangleBorder(
        // <-- SEE HERE
        borderRadius: BorderRadius.vertical(
          top: Radius.circular(20),
        ),
      ),
      builder: (builder) {
        return StatefulBuilder(
          builder: (context, setState) {
            if (isEditMode) {
              return Padding(
                padding: MediaQuery.of(context).viewInsets,
                child: Container(
                    height: MediaQuery.of(context).size.height * .4,
                    padding: EdgeInsets.all(30),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        Text("Pick a date",
                            textAlign: TextAlign.center,
                            style: TextStyle(
                                color: textDark,
                                fontSize: 20,
                                fontWeight: FontWeight.bold),
                            textDirection: TextDirection.ltr),
                        Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
                            Container(
                              padding: EdgeInsets.all(15),
                              width: MediaQuery.of(context).size.width * 0.83,
                              decoration: BoxDecoration(
                                  color: textDark,
                                  borderRadius: BorderRadius.only(
                                      topLeft: Radius.circular(15),
                                      topRight: Radius.circular(15))),
                              child: Row(
                                mainAxisAlignment:
                                    MainAxisAlignment.spaceBetween,
                                children: [
                                  Row(
                                    mainAxisAlignment: MainAxisAlignment.start,
                                    children: [
                                      ValueListenableBuilder(
                                        valueListenable: displayDayName,
                                        builder: (context, value, child) =>
                                            AutoSizeText(
                                                maxLines: 1,
                                                minFontSize: 12,
                                                softWrap: true,
                                                maxFontSize: 18,
                                                displayDayName.value,
                                                textAlign: TextAlign.left,
                                                style: TextStyle(
                                                    color: Colors.white,
                                                    fontSize: 18),
                                                textDirection:
                                                    TextDirection.ltr),
                                      ),
                                      ValueListenableBuilder(
                                          valueListenable: displayDay,
                                          builder: (context, value, child) =>
                                              Text(displayDay.value,
                                                  textAlign: TextAlign.left,
                                                  style: TextStyle(
                                                      color: Colors.white,
                                                      fontSize: 18),
                                                  textDirection:
                                                      TextDirection.ltr)),
                                      ValueListenableBuilder(
                                          valueListenable: displayMonth,
                                          builder: (context, value, child) =>
                                              Text(displayMonth.value,
                                                  textAlign: TextAlign.left,
                                                  style: TextStyle(
                                                      color: Colors.white,
                                                      fontSize: 18),
                                                  textDirection:
                                                      TextDirection.ltr))
                                    ],
                                  ),
                                  InkWell(
                                    onTap: () {
                                      setState(() {
                                        if (RegExp(
                                                '[0-9]{1,2}(/|-|.)[0-9]{1,2}(/|-|.)[0-9]{4}')
                                            .hasMatch(
                                                selectedDateController.text)) {
                                          DateTime parsedDate =
                                              new intl.DateFormat("dd.MM.yyyy")
                                                  .parse(selectedDateController
                                                      .text
                                                      .replaceAll("-", ".")
                                                      .replaceAll("/", "."));
                                          currentDate = parsedDate;
                                          initData();
                                        }
                                        isEditMode = false;
                                      });
                                    },
                                    child: Icon(Icons.calendar_today,
                                        color: Colors.white, size: 20),
                                  )
                                ],
                              ),
                            ),
                            Container(
                              decoration: BoxDecoration(
                                  color: grayLight2,
                                  borderRadius: BorderRadius.only(
                                      bottomRight: Radius.circular(15),
                                      bottomLeft: Radius.circular(15))),
                              padding: EdgeInsets.only(
                                  left: 15, right: 15, bottom: 10),
                              width: MediaQuery.of(context).size.width * 0.83,
                              child: ValueListenableBuilder(
                                  valueListenable: errorState,
                                  builder: (context, value, child) => Container(
                                      width: MediaQuery.of(context).size.width *
                                          0.83,
                                      margin: EdgeInsets.only(
                                          top: 20.0, bottom: 20),
                                      decoration: BoxDecoration(
                                          borderRadius:
                                              BorderRadius.circular(15),
                                          color: Colors.white,
                                          border: errorState.value == 1
                                              ? Border.all(
                                                  width: 1, color: Colors.red)
                                              : null),
                                      child: TextFormField(
                                        textInputAction: TextInputAction.next,
                                        style: TextStyle(
                                            color: textDark, fontSize: 14),
                                        textAlign: TextAlign.left,
                                        textAlignVertical:
                                            TextAlignVertical.center,
                                        keyboardType: TextInputType.text,
                                        decoration: InputDecoration(
                                          filled: true,
                                          fillColor: Colors.transparent,
                                          border: InputBorder.none,
                                          contentPadding: EdgeInsets.all(20),
                                          hintStyle:
                                              TextStyle(color: grayLight),
                                          floatingLabelBehavior:
                                              FloatingLabelBehavior.never,
                                        ),
                                        controller: selectedDateController,
                                      ))),
                            ),
                          ],
                        ),
                        Container(
                          width: MediaQuery.of(context).size.width * 0.83,
                          margin: EdgeInsets.only(top: 20),
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              FullwdithButton(
                                  width: MediaQuery.of(context).size.width * .4,
                                  onPressed: () {},
                                  backgroundColor: Colors.white,
                                  outlineColor: purple,
                                  child: Text("cancel",
                                      textAlign: TextAlign.center,
                                      style: TextStyle(
                                          color: purple, fontSize: 15),
                                      textDirection: TextDirection.ltr)),
                              FullwdithButton(
                                  width: MediaQuery.of(context).size.width * .4,
                                  onPressed: () {
                                    if (RegExp(
                                            '[0-9]{1,2}(/|-|.)[0-9]{1,2}(/|-|.)[0-9]{4}')
                                        .hasMatch(
                                            selectedDateController.text)) {
                                      completer.complete(selectedDateController
                                          .text
                                          .replaceAll("-", ".")
                                          .replaceAll("/", "."));
                                      Navigator.pop(context);
                                    } else
                                      errorState.value = 1;
                                  },
                                  backgroundColor: purple,
                                  child: Text("ok",
                                      textAlign: TextAlign.center,
                                      style: TextStyle(
                                          color: Colors.white, fontSize: 15),
                                      textDirection: TextDirection.ltr))
                            ],
                          ),
                        )
                      ],
                    )),
              );
            } else {
              return Container(
                  height: MediaQuery.of(context).size.height * .67,
                  padding: EdgeInsets.all(30),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      Text("Pick a date",
                          textAlign: TextAlign.center,
                          style: TextStyle(
                              color: textDark,
                              fontSize: 20,
                              fontWeight: FontWeight.bold),
                          textDirection: TextDirection.ltr),
                      Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: [
                          Container(
                            padding: EdgeInsets.all(15),
                            width: MediaQuery.of(context).size.width * 0.83,
                            decoration: BoxDecoration(
                                color: textDark,
                                borderRadius: BorderRadius.only(
                                    topLeft: Radius.circular(15),
                                    topRight: Radius.circular(15))),
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                              children: [
                                Row(
                                  mainAxisAlignment: MainAxisAlignment.start,
                                  children: [
                                    ValueListenableBuilder(
                                      valueListenable: displayDayName,
                                      builder: (context, value, child) =>
                                          AutoSizeText(
                                              maxLines: 1,
                                              minFontSize: 12,
                                              softWrap: true,
                                              maxFontSize: 18,
                                              displayDayName.value,
                                              textAlign: TextAlign.left,
                                              style: TextStyle(
                                                  color: Colors.white,
                                                  fontSize: 18),
                                              textDirection: TextDirection.ltr),
                                    ),
                                    ValueListenableBuilder(
                                        valueListenable: displayDay,
                                        builder: (context, value, child) =>
                                            Text(displayDay.value,
                                                textAlign: TextAlign.left,
                                                style: TextStyle(
                                                    color: Colors.white,
                                                    fontSize: 18),
                                                textDirection:
                                                    TextDirection.ltr)),
                                    ValueListenableBuilder(
                                        valueListenable: displayMonth,
                                        builder: (context, value, child) =>
                                            Text(displayMonth.value,
                                                textAlign: TextAlign.left,
                                                style: TextStyle(
                                                    color: Colors.white,
                                                    fontSize: 18),
                                                textDirection:
                                                    TextDirection.ltr))
                                  ],
                                ),
                                InkWell(
                                  onTap: () {
                                    setState(() {
                                      isEditMode = true;
                                    });
                                  },
                                  child: Icon(Icons.edit,
                                      color: Colors.white, size: 20),
                                )
                              ],
                            ),
                          ),
                          Container(
                            padding: EdgeInsets.only(top: 5, bottom: 5),
                            color: grayLight2,
                            width: MediaQuery.of(context).size.width * 0.83,
                            child: Row(
                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                              children: [
                                Row(
                                  mainAxisAlignment: MainAxisAlignment.start,
                                  children: [
                                    InkWell(
                                      onTap: () {
                                        currentDate = DateTime(
                                            currentDate.year,
                                            currentDate.month - 1,
                                            currentDate.day);
                                        initData();
                                      },
                                      child: Padding(
                                        padding: EdgeInsets.only(
                                            top: 10,
                                            bottom: 10,
                                            right: 5,
                                            left: 15),
                                        child: Icon(Icons.arrow_back_ios,
                                            size: 15),
                                      ),
                                    ),
                                    Container(
                                        child: ValueListenableBuilder(
                                            valueListenable: displayMonth,
                                            builder: (context, value, child) =>
                                                Text(displayMonth.value,
                                                    textAlign: TextAlign.left,
                                                    style: TextStyle(
                                                        color: textLight,
                                                        fontSize: 12),
                                                    textDirection:
                                                        TextDirection.ltr))),
                                    InkWell(
                                      onTap: () {
                                        currentDate = DateTime(
                                            currentDate.year,
                                            currentDate.month + 1,
                                            currentDate.day);
                                        initData();
                                      },
                                      child: Padding(
                                        padding: EdgeInsets.only(
                                            top: 10,
                                            bottom: 10,
                                            right: 15,
                                            left: 5),
                                        child: Icon(Icons.arrow_forward_ios,
                                            size: 15),
                                      ),
                                    )
                                  ],
                                ),
                                Row(
                                  children: [
                                    InkWell(
                                      onTap: () {
                                        currentDate = DateTime(
                                            currentDate.year - 1,
                                            currentDate.month,
                                            currentDate.day);
                                        initData();
                                      },
                                      child: Padding(
                                        padding: EdgeInsets.only(
                                            top: 10,
                                            bottom: 10,
                                            right: 5,
                                            left: 15),
                                        child: Icon(
                                          Icons.arrow_back_ios,
                                          size: 15,
                                          color: textDark,
                                        ),
                                      ),
                                    ),
                                    Container(
                                        child: ValueListenableBuilder(
                                            valueListenable: displayYear,
                                            builder: (context, value, child) =>
                                                Text(displayYear.value,
                                                    textAlign: TextAlign.left,
                                                    style: TextStyle(
                                                        color: textLight,
                                                        fontSize: 12),
                                                    textDirection:
                                                        TextDirection.ltr))),
                                    InkWell(
                                      onTap: () {
                                        currentDate = DateTime(
                                            currentDate.year + 1,
                                            currentDate.month,
                                            currentDate.day);
                                        initData();
                                      },
                                      child: Padding(
                                        padding: EdgeInsets.only(
                                            top: 10,
                                            bottom: 10,
                                            right: 15,
                                            left: 5),
                                        child: Icon(
                                          Icons.arrow_forward_ios,
                                          size: 15,
                                          color: textDark,
                                        ),
                                      ),
                                    )
                                  ],
                                ),
                              ],
                            ),
                          ),
                          Container(
                            decoration: BoxDecoration(
                                color: grayLight2,
                                borderRadius: BorderRadius.only(
                                    bottomRight: Radius.circular(15),
                                    bottomLeft: Radius.circular(15))),
                            padding: EdgeInsets.only(
                                left: 15, right: 15, bottom: 10),
                            width: MediaQuery.of(context).size.width * 0.83,
                            child: ValueListenableBuilder(
                              valueListenable: selectedIndex,
                              builder: (context, value, child) =>
                                  GridView.builder(
                                shrinkWrap: true,
                                itemCount: days.length,
                                itemBuilder: (context, index) {
                                  return InkWell(
                                    onTap: () {
                                      if (days[index] != "0" && index > 6) {
                                        selectedIndex.value = index;
                                        currentDate = DateTime(
                                            currentDate.year,
                                            currentDate.month,
                                            int.parse(days[index]));
                                        initData();
                                      }
                                    },
                                    child: Container(
                                      alignment: Alignment.center,
                                      decoration: index == selectedIndex.value
                                          ? BoxDecoration(
                                              color: Color(0xffC2E1E5),
                                              shape: BoxShape.circle,
                                            )
                                          : null,
                                      child: Text(
                                          days[index] == "0" ? "" : days[index],
                                          textAlign: TextAlign.center,
                                          style: TextStyle(
                                              color: index < 7
                                                  ? textDark
                                                  : textLight,
                                              fontSize: 12,
                                              fontWeight: index < 7
                                                  ? FontWeight.bold
                                                  : FontWeight.normal),
                                          textDirection: TextDirection.ltr),
                                    ),
                                  );
                                },
                                gridDelegate:
                                    SliverGridDelegateWithFixedCrossAxisCount(
                                        crossAxisCount: 7,
                                        childAspectRatio: 1.3),
                              ),
                            ),
                          ),
                        ],
                      ),
                      Container(
                        width: MediaQuery.of(context).size.width * 0.83,
                        margin: EdgeInsets.only(top: 20),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            FullwdithButton(
                                width: MediaQuery.of(context).size.width * .4,
                                onPressed: () {},
                                backgroundColor: Colors.white,
                                outlineColor: purple,
                                child: Text("cancel",
                                    textAlign: TextAlign.center,
                                    style:
                                        TextStyle(color: purple, fontSize: 15),
                                    textDirection: TextDirection.ltr)),
                            FullwdithButton(
                                width: MediaQuery.of(context).size.width * .4,
                                onPressed: () {
                                  completer.complete(
                                      "${displayDay.value.length < 2 ? "0${displayDay.value.trim()}" : displayDay.value.trim()}${selectedMonth.value < 10 ? "0${selectedMonth.value}" : selectedMonth.value}"
                                      ".${displayYear.value}");
                                  Navigator.pop(context);
                                },
                                backgroundColor: purple,
                                child: Text("ok",
                                    textAlign: TextAlign.center,
                                    style: TextStyle(
                                        color: Colors.white, fontSize: 15),
                                    textDirection: TextDirection.ltr))
                          ],
                        ),
                      )
                    ],
                  ));
            }
          },
        );
      });
  return completer.future;
}