Hopefully someone can help me on this. I have this scenario where my textfield has been set an error text since user click continue without choosing value. Supposedly, when i tap on the textfield, a dialog will show with a list of data that i should choose. When done choosing, the value is set to the textfield and the error text is reset to null. But currently the error text is not reset to null and it's still shown along the value that i chose. I'm thinking maybe it's because i need to rebuild MySearchList class by calling setstate. But i am not sure how to do this. Hope anyone can advise me on what is the best way to do this. Thanks in advance.
import 'package:flutter/material.dart';
// ignore: must_be_immutable
class MySearchList extends StatefulWidget {
MySearchList(
{required this.label,
required this.controller,
required this.dataList,
this.errorText});
final String label;
final TextEditingController controller;
final List<String> dataList;
String? errorText;
@override
_MySearchListState createState() => _MySearchListState();
}
class _MySearchListState extends State<MySearchList> {
@override
Widget build(BuildContext context) {
return Material(
child: TextField(
decoration: InputDecoration(
labelText: widget.label,
errorText: widget.errorText,
),
readOnly: true,
controller: widget.controller,
onTap: () {
showDialog(
context: context,
builder: (BuildContext context) {
return MySearchListDialog(
label: widget.label,
controller: widget.controller,
dataList: widget.dataList,
);
});
}),
);
}
}
// ignore: must_be_immutable
class MySearchListDialog extends StatefulWidget {
MySearchListDialog(
{required this.label,
required this.controller,
required this.dataList,
this.errorText});
final String label;
final TextEditingController controller;
final List<String> dataList;
String? errorText;
@override
_MySearchListDialogState createState() => _MySearchListDialogState();
}
class _MySearchListDialogState extends State<MySearchListDialog> {
TextEditingController _textController = TextEditingController();
List<String> _mainDataList = [];
List<String> _newDataList = [];
@override
void initState() {
super.initState();
_mainDataList = widget.dataList;
_newDataList = List.from(_mainDataList);
}
@override
void dispose() {
_textController.dispose();
super.dispose();
}
onItemChanged(String value) {
setState(() {
_newDataList = _mainDataList
.where((string) => string.toLowerCase().contains(value.toLowerCase()))
.toList();
});
}
@override
Widget build(BuildContext context) {
return Dialog(
child: Container(
constraints: BoxConstraints(
minHeight: 300.0,
maxHeight: 400.0,
),
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(12.0, 10.0, 12.0, 0.0),
child: MyTextField(
hintLabel: "Search",
controller: _textController,
onChanged: onItemChanged,
errorText: widget.errorText,
),
),
Expanded(
child: ListView(
padding: EdgeInsets.all(12.0),
children: _newDataList.map((data) {
return ListTile(
title: Text(data),
onTap: () {
//this setstate will not rebuild class MySearchList
setState(() {
widget.errorText = null; //reset error on textfield
widget.controller.text = data.toString(); //set value to textfield
Navigator.pop(context); //close dialog
});
});
}).toList(),
),
)
],
),
));
}
}