JS1
JS1

Reputation: 767

How to disable TextFormField according to conditions?

I have 2 TextFormField, the first one is a DatePicker, the second one is a classical TextFormField where you can enter the number of hours you spent on a particular task, if you enter"2" in this field and submit the form it will save in the DB as 2 hours spent on this particular task in the selected day from the DatePicker above :

enter image description here

Because you can already have hours saved in the DB for a particular day and task, I want that when the user pick a date in the DatePicker:

If there are already hours saved for this date :

If there are no hours saved for this date :

Here is the code of my form :

Form(
                  key: UniqueKey(),
                  child: Column(
                    children: [
                      Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Padding(
                            padding: EdgeInsets.only(right: 20),
                            child: 
                            InkWell(
                              onTap: () {
                              _selectDate(context);
                              },
                              child: Icon(BeoticIcons.calendar, size: 30),
                            ),
                          ),
                          InkWell(
                            onTap: () {
                              _selectDate(context);
                            },
                            child: Container(
                              width: 210,
                              height: 40,
                              child: TextFormField(
                                textAlign: TextAlign.center,
                                enabled: false,
                                keyboardType: TextInputType.text,
                                controller: _dateController,
                                decoration: InputDecoration(
                                  contentPadding: EdgeInsets.zero,
                                  hintText: DateFormat('dd/MM/yyyy').format(DateTime.now()),
                                  filled: true,
                                  fillColor: Colors.white
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                      SizedBox(
                        height: 20
                      ),
                      Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Padding(
                            padding: EdgeInsets.only(right:20),
                            child: Icon(BeoticIcons.clock, size: 30),
                          ),
                          Container(
                            //margin: EdgeInsets.only(left: 30),
                            width: 210,
                            height: 40,
                            child: TextFormField(
                              controller: _timeController,
                              textAlign: TextAlign.center,
                              enabled: true,
                              decoration: InputDecoration(
                                hintText: "0 h",
                                contentPadding: EdgeInsets.zero,
                                filled: true,
                                fillColor: Colors.white
                              ),
                            ),
                          )
                        ],
                      ),
                      SizedBox(
                        height: 20
                      ),
                      Row(
                        mainAxisAlignment: MainAxisAlignment.end,
                        children: [
                          Padding(
                            padding: EdgeInsets.only(right: 35),
                            child: ElevatedButton(
                              onPressed: () async {postTimes(await convertDate(selectedDate), convertTime(_timeController.text));},
                              child: Text("Enregistrer")
                            ),
                          )
                        ],
                      )
                    ],
                  ),
                ),

As for now I have no idea how to put a condition depending on external data for an enabled attribute of a TextFormField, and how to modify the hintText of the TextFormField depending and these data,

Any help will be welcomed :)

Upvotes: 0

Views: 1069

Answers (1)

Md. Yeasin Sheikh
Md. Yeasin Sheikh

Reputation: 63864

There are two criteria we need to meet,

  • enable entry point
  • disable entry point

While we present the UI, we need to fetch the data from storage before showing DatePicker. I would prefer fetching on initState. It would be better to disable click event and make hour: TextField readOnly on first place.

Inside stateClass we have variable(prefer nullable) to get selected date from DatePicker Dialog. Or we can use another bool _isNewEntry = false.

After closing the datePicker use your logic(just comparing dd/MM/yyyy) to set _isNewEntry true or false and set _timeController.text =MatchModelHour inside setState().

TextField <readOnly> will be

TextField(
 readOnly: _isNewEntry,
 controller: _timeController,
)

For the button, you can pass null to disable functionality or just some logic like showing toast messages or snackbar.

onPressed: _isNewEntry () async {...}: null,

But in some case you may don't like to have disabled style and like to use different style then use another function like

onPressed: _isNewEntry () async {...}: (){ //disable entry point snackbar etc},

Upvotes: 1

Related Questions