0

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

Alv
  • 55
  • 2
  • 6
  • Does this answer your question? [Flutter: Conflict between TextField's onTap and prefixIcon's onPressed](https://stackoverflow.com/questions/68845904/flutter-conflict-between-textfields-ontap-and-prefixicons-onpressed) – eamirho3ein Aug 17 '22 at 13:39
  • Can remove all padding and try tapping on button point. failed to get the issue, Also what do you mean by disabling the date picker, for me tapping suffixIcon doesnt pop up the dialog – Md. Yeasin Sheikh Aug 17 '22 at 13:42
  • @eamirho3ein I tried the solution on that question, but the datepicker is totally disabled. But I'm not sure if i implemented the focus node correctly. – Alv Aug 17 '22 at 13:54
  • @YeasinSheikh what i want to achieve is to disable the onTap of the TextFormField temporarily whenever the suffixIcon (which is wrapped in IconButton) is clicked, is it possible to do that? – Alv Aug 17 '22 at 13:56
  • Yes, I think, you like to disable the tap event after getting date? also tapping on suffix Icon is not opening the dialog on my test case – Md. Yeasin Sheikh Aug 17 '22 at 13:59

0 Answers0