How to disable Flutter DatePicker?

645 Views Asked by At

I have an issue with DatePicker in my application. Here's a simple TextFormField that I've created in my app which will open up DatePicker whenever the user taps on it.

enter image description here

This widget is a part of a form where I also have specified the GlobalKey and TextController for it. The rightmost calendar icon uses the suffixIcon property of InputDecoration and it changes to a clear icon whenever the user selects a date.

Here's the code for the above widget.

       TextFormField(
          onTap: () => _selectStartDate(context),
          controller: _startDateTextController,
          keyboardType: TextInputType.datetime,
          readOnly: true,
          decoration: InputDecoration(
            suffixIcon: showClear ? IconButton(
              icon: Icon(Icons.clear),
              onPressed: _clearStartDate,
            ) : Icon(Icons.date_range),
            labelText: 'Start Date',
            labelStyle: TextStyle(
              fontSize: AppDimensions.font26,
              color: AppColors.paraColor
            ),
          ),
          validator: (value){
            if(value!.isEmpty) {
              return 'Please enter a date';
            }
          },
        ),

My goal is to let the user pick on a date, and clear it should they choose to do so.

Here's the code for the _selectStartDate and _clearStartDate functions as well as the necessary controller and key. I'm using the intl package to format the date.

  final _formKey = GlobalKey<FormState>();
  TextEditingController _startDateTextController = TextEditingController();
  DateTime selectedStartDate = DateTime.now();
  bool showClear = false;

  _selectStartDate(BuildContext context) async {
    final DateTime? newStartDate = await showDatePicker(
      context: context,
      initialDate: selectedStartDate,
      firstDate: DateTime(1900),
      lastDate: DateTime(2100),
      helpText: 'STARTING DATE'
    );
    if(newStartDate != null && newStartDate != selectedStartDate) {
      setState(() {
        selectedStartDate = newStartDate;
        _startDateTextController.text = DateFormat.yMMMd().format(selectedStartDate);
        showClear = true;
      });
    }
  }

  _clearStartDate() {
    _startDateTextController.clear();
    setState(() {
      showClear = !showClear;
    });
  }

When i run the app, the DatePicker pops up and I'm able to select a date. The date is then shown on the TextFormField like the image below.

enter image description here

As you can see the clear icon is displayed. However, when i clicked on it, the DatePicker still popped up. And when i clicked on cancel on the DatePicker window, the TextFormField is cleared as expected.

enter image description here

Here's the complete code.

class BookingForm extends StatefulWidget {
  const BookingForm({Key? key}) : super(key: key);

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

class _BookingFormState extends State<BookingForm> {

  final _formKey = GlobalKey<FormState>();
  TextEditingController _startDateTextController = TextEditingController();
  DateTime selectedStartDate = DateTime.now();
  bool showClear = false;

  _selectStartDate(BuildContext context) async {
    final DateTime? newStartDate = await showDatePicker(
      context: context,
      initialDate: selectedStartDate,
      firstDate: DateTime(1900),
      lastDate: DateTime(2100),
      helpText: 'STARTING DATE'
    );
    if(newStartDate != null && newStartDate != selectedStartDate) {
      setState(() {
        selectedStartDate = newStartDate;
        _startDateTextController.text = DateFormat.yMMMd().format(selectedStartDate);
        showClear = true;
      });
    }
  }

  _clearStartDate() {
    _startDateTextController.clear();
    setState(() {
      showClear = !showClear;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Container(
        margin: EdgeInsets.only(left: AppDimensions.width20, right: AppDimensions.width20),
        padding: EdgeInsets.all(AppDimensions.height20),
        decoration: BoxDecoration(
          color: Colors.white70,
          borderRadius: BorderRadius.circular(AppDimensions.radius20),
          boxShadow: [
            BoxShadow(
              color: Color(0xFFe8e8e8),
              blurRadius: 5.0,
              spreadRadius: 1.0,
              offset: Offset(2,2)
            ),
          ]
        ),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            TextFormField(
              onTap: () => _selectStartDate(context),
              controller: _startDateTextController,
              keyboardType: TextInputType.datetime,
              readOnly: true,
              decoration: InputDecoration(
                suffixIcon: showClear ? IconButton(
                  icon: Icon(Icons.clear),
                  onPressed: _clearStartDate,
                ) : Icon(Icons.date_range),
                labelText: 'Start Date',
                labelStyle: TextStyle(
                  fontSize: AppDimensions.font26,
                  color: AppColors.paraColor
                ),
              ),
              validator: (value){
                if(value!.isEmpty) {
                  return 'Please enter a date';
                }
              },
            ),
            ElevatedButton(
              style: ElevatedButton.styleFrom(
                padding: EdgeInsets.only(
                  top: AppDimensions.height10,
                  bottom: AppDimensions.height10,
                  left: AppDimensions.width45,
                  right: AppDimensions.width45
                ),
                primary: AppColors.mainColor2,
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(AppDimensions.radius20)
                )
              ),
              child: SmallText(
                text: 'Search',
                size: AppDimensions.font26,
                color: Colors.white,
              ),
              onPressed: (){
                if(_formKey.currentState!.validate()) {
                  _formKey.currentState!.save();
                }
              }
            ),
          ],
        ),
      ),
    );
  }
}

I'm not sure why this happens. Any help is greatly appreciated. Thank you

0

There are 0 best solutions below