forms - 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 :
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 :
- the number of hours shows in the second TextFormField
- the second TextFormField is disabled
- the submit button is disabled
If there are no hours saved for this date :
- classical functionning
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 :)
解决方案
我们需要满足两个标准,
- 启用入口点
- 禁用入口点
当我们展示 UI 时,我们需要在展示之前从存储中获取数据DatePicker
。我更喜欢在initState
. 最好禁用点击事件并hour: TextField readOnly
放在第一位。
在里面stateClass
我们有变量(最好可以为空)来从中获取选定的日期DatePicker Dialog
。或者我们可以使用另一个bool _isNewEntry = false
.
关闭后datePicker
使用你的逻辑(只是比较 dd/MM/yyyy)来设置_isNewEntry
true
或false
设置 _timeController.text =MatchModelHour
里面setState()
。
文本字段<readOnly>
将是
TextField(
readOnly: _isNewEntry,
controller: _timeController,
)
对于按钮,您可以通过null
禁用功能或只是一些逻辑,如显示 toast 消息或小吃栏。
onPressed: _isNewEntry () async {...}: null,
但是在某些情况下,您可能不喜欢禁用样式并喜欢使用不同的样式然后使用其他功能,例如
onPressed: _isNewEntry () async {...}: (){ //disable entry point snackbar etc},
推荐阅读
- java - ConstraintLayout 内的 CardView 重叠边缘
- git - 如何列出提交中不包含在任何分支中的所有标签?
- unity3d - Unity - 玩家跌倒从搅拌机导入的物体
- distributed - 为什么 Raft 领导者在选举时发送空的 AppendEntries RPC
- javascript - 如何使用过滤器和匹配来获取内容?
- javascript - 在 div 外部单击时,其他 div 必须使用 jquery 删除其类
- javascript - 为什么在循环体内声明的变量不被视为重新声明?
- matlab - 如何在 MATLAB 中从 TID2013 数据集中读取特定图像?
- javascript - MongoDB 将 JSON 响应映射为字符串
- r - 使用标准分析 R 中的栅格堆栈