首页 > 解决方案 > 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 :)

标签: formsflutterdarttextformfieldflutter-textformfield

解决方案


我们需要满足两个标准,

  • 启用入口点
  • 禁用入口点

当我们展示 UI 时,我们需要在展示之前从存储中获取数据DatePicker。我更喜欢在initState. 最好禁用点击事件并hour: TextField readOnly放在第一位。

在里面stateClass我们有变量(最好可以为空)来从中获取选定的日期DatePicker Dialog。或者我们可以使用另一个bool _isNewEntry = false.

关闭后datePicker使用你的逻辑(只是比较 dd/MM/yyyy)来设置_isNewEntry truefalse设置 _timeController.text =MatchModelHour 里面setState()

文本字段<readOnly> 将是

TextField(
 readOnly: _isNewEntry,
 controller: _timeController,
)

对于按钮,您可以通过null禁用功能或只是一些逻辑,如显示 toast 消息或小吃栏。

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

但是在某些情况下,您可能不喜欢禁用样式并喜欢使用不同的样式然后使用其他功能,例如

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

推荐阅读