Resetting TextfieldController for all textfields, using provider - flutter

I'm having a problem trying to figuring out the proper way on how to do this. Basically in my app, I want to reset all the fields for "cleanup" by the user. I can reset everything, but the TextFields. The only way that I found to solve the problem is by using the if that you can see inside the Consumer. I don't think though it's the proper way on how to handle this type of thing.
I also thought to push inside my provider class all the controller and then reset them, but I think it's still too heavy. I'm trying to find the cleanest and lightest solution, even to learn what's the best practice in these situations.
Thanks in advance!
return Provider.of<Provider_Class>(context, listen: false).fields[_label] != null ? SizedBox(
height: 57.5,
child: Consumer<Provider_Class>(builder: (context, provider, child) {
if (provider.resetted == true) {
_controller.text = "";
}
return Material(
elevation: this.elev,
shadowColor: Colors.black,
borderRadius: new BorderRadius.circular(15),
animationDuration: new Duration(milliseconds: 500),
child: new TextField(
focusNode: _focusNode,
keyboardAppearance: Brightness.light,
style: Theme.of(context).textTheme.headline5,
controller: _controller,
keyboardType: TextInputType.number,
textAlign: TextAlign.end,
inputFormatters: <TextInputFormatter>[
LengthLimitingTextInputFormatter(8),
_whichLabel(widget.label),
],
decoration: new InputDecoration(
enabledBorder: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(15),
borderSide: new BorderSide(width: 1.2, color: CliniLiliac300),
),
focusedBorder: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(15),
borderSide: new BorderSide(width: 2.5, color: CliniLiliac300),
),
filled: true,
fillColor: Colors.white,
hintText: "0.0",
hintStyle: new TextStyle(fontSize: 15, color: Colors.black, fontFamily: "Montserrat"),
),
onChanged: (val) {
var cursorPos = _controller.selection;
val = val.replaceAll(",", ".");
if (val == "") {
provider.fields[_label] = 0.0;
} else if (double.parse(val) > provider.measure[_label] &&
provider.measure[_label] != 0) {
provider.fields[_label] % 1 == 0
? _controller.text = provider.fields[_label].toString().split(".")[0]
: _controller.text = provider.fields[_label].toString();
if (cursorPos.start > _controller.text.length) {
cursorPos = new TextSelection.fromPosition(
new TextPosition(offset: _controller.text.length),
);
}
_controller.selection = cursorPos;
} else {
provider.fields[_label] = double.parse(val);
}
provider.calculateResultRA();
},
),
);
}),
) : SizedBox();
}

Use TextFormField instead of TextField. TextFormField has several callbacks like validator, onSaved, onChanged, onEditingComplete, onSubmitted, ...
You can connect all your TextFormFields by wrapping it in a Form. This form should be given a GlobalKey so that you can identify the Form and call methods on FormState.
final _form = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
// ...
return Form(
key: _form,
child: // build Material with TextFormFields
);
}
Now to call onSaved on each TextFormField, you can call _form.currentState().save(). To reset every TextFormField you can call _form.currentState().reset().
You can get more information about how to build a Form and the functions you can call on FomState here:
https://flutter.dev/docs/cookbook/forms/validation
https://api.flutter.dev/flutter/widgets/FormState-class.html

Related

When tap on textfield, app crashes returns homepage

Hi I get an error when user focus textfield, app crashes and returns to homepage (see clip here https://www.screencast.com/t/yiJkCBsibcoY)
I've had this error for a while now and cannot seem to fix it, sometimes it happens on other textfields. I cannot replicate the issue only sent from users. Anyone experience this with flutter?
Widget searchBox() {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
border: Border.all(color: Color(0xff0F004E), width: 1.0),
),
child: SimpleAutoCompleteTextField(
key: keyAuto,
controller: textController,
suggestions: suggestions,
textChanged: (text) => searchProduct = text,
textSubmitted: (text) {
loadingBarActive = true;
_sendAnalyticsEvent(text, 'serach_food_action');
searchProduct = text.replaceAll(new RegExp(r'[^\w\s]+'), '');
print('searchProduct RegX $searchProduct');
newSearch = true;
_filterCategories(searchProduct);
_filterRecipes(searchProduct);
// reset search values to intial
usdaItems.clear();
usda!.clear();
perPage = perPageIntial;
present.value = 0;
loadingBarActive = false;
selectApi = <int, Widget>{
0: allProductTab(),
1: allProductTab(),
2: allProductTab(),
3: allProductTab(),
};
setState(() {
_loadUSDAlist = usdaFoodProductList();
_loadOpenList = openFoodProductList();
});
},
style: TextStyle(
fontFamily: 'Nunito', fontSize: 20.0, color: Color(0xff0F004E)),
decoration: InputDecoration(
border: InputBorder.none,
// contentPadding: EdgeInsets.only(top: 14.0),
hintText: 'Search',
hintStyle: TextStyle(
fontFamily: 'Nunito', fontSize: 16.0, color: Color(0xff0F004E)),
prefixIcon: Icon(Icons.search, color: Color(0xff0F004E)),
suffixIcon: IconButton(
icon: Icon(Icons.close, color: Color(0xff0F004E)),
onPressed: () {
textController.clear();
})),
),
);
}
I had exactly the same issue and was literally going crazy trying to find the solution. For me the error originated in my usage of the GetX state management library. For me the issue was solved by replacing this:
Get.to(ReservationDetails(res: Reservation.empty()))
?.then(((value) => setState(() {
//Reload the reservations for the new date from the server
_taskesFuture =
FetchReservation(setStatePublic: _setStatePublic)
.fetchReservation(_selectedDate);
})));
with:
Navigator.push(context,
MaterialPageRoute(
builder: ((context) =>
ReservationDetails(res: Reservation.empty()))))
.then((value) => setState(() {
//Reload the reservations for the new date from the server
_taskesFuture =
FetchReservation(setStatePublic: _setStatePublic)
.fetchReservation(_selectedDate);
}));
I suggest you have a look at how you are opening the page you are experiencing this issue.

How to set Visibility function in flutter to show or hide Text Form Field?

I want to set an option in my Trivia game to the user set a Text Field in specific question ID.
for now I trying to use Visibility widget but its only take the bool _visibleText value,
And does not get the value from void validateText.
any idea what I missing?
this is my code:
class _QuestionCardState extends State<QuestionCard> {
bool _visibleText = false;
void validateText() => setState(() {
if (widget.question.id == 1) {
_visibleText = false;
} else {
if (widget.question.id == 2) {
_visibleText = true;
}
}
});
and the widget:
Visibility(
visible: (_visibleText),
child: Container(
width: 320.0,
alignment: Alignment.center,
child: TextFormField(
textAlign: TextAlign.center,
decoration: InputDecoration(
enabledBorder: const OutlineInputBorder(
borderSide:
const BorderSide(color: Color(0xFFCBA583), width: 2.0),
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
filled: true,
fillColor: Colors.white,
hintText: widget.question.text,
hintStyle: TextStyle(
fontSize: 16.0,
color: Color(0xFF067751),
fontFamily: 'Calibri',
letterSpacing: 2,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
),
),
),
),
),
Solved by using this function:
bool validateText() {
if (widget.question.id == 2) {
return true;
}
return false;
}
If you need to continuously toggle visibility during the game, please use streambuilder and leave your validatetext function inside streambuilder's sink method. Then streamcontroller will continuously change your UI dynamically.
If you don't understand at all, then please mention that , I will try to add the full codebase.
Thank You.
validateText is never called.
Change the function to this :
bool validateText() {
if (widget.question.id == 1) return false;
if (widget.question.id == 2) return true;
}
And in your build method :
visible: validateText(),
The validateText function is never called. If you have a button that toggles this then call it in it's onTap event.

Flutter focusnode problem not working - only by clicking it works

iam using a device that scans barcode , I want after each read the focus to return the TextFormFiled - the code below do the work and I see the cursor is focused on the TextFormFiled but when I read next time its show nothing , I need to manually just click by my finger on the textfiled to activate the focus ,can somebody help me ( the device returned LF after each read)
TextFormField(
decoration: new InputDecoration(
border: new OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
),
filled: true,
hintStyle: new TextStyle(
color: Colors.grey[800]),
hintText: "Read BarCode",
fillColor: Colors.white70),
focusNode: myFocusNode,
controller: search,
autofocus: true,
maxLines: null,
validator: (value) {
// print(value.toString().runes);
if (value.toString().contains("\n")) {
fetchProducts(value!);
search.text = "";
} else {}
},
),
Use your myFocusNode to activate the focus on textField.
void function(){
/// after scanning is complete call this
focusNode.requestFocus()
}
I pass for this and did solve it like this:
_addItem() {
final isValid = _formKey.currentState?.validate() ?? false;
if (!isValid) {
return;
}
final ean = int.parse(_eanController.text);
listaEan.add(ean);
_eanController.text = '';
setState(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
_eanFocus.requestFocus();
});
});
}
but in physical scan device, did works fine. without use the addPostFramaCallback.

Flutter save text in textfielf

I am trying to create a kind of forum using text fields. The thing is that when you fill in the blacks and press next and than you go back again, the text field will appear empty as if you have no value in it but its actually saved. I want it so that you can see what you entered inside even if you go forward and than back. I will attach some photos so you can understand better what i mean.
Here is the photo of the text field:
https://gyazo.com/9ceb0ef4f27db1be842cbdfac885fc01
In this photo i fill in the blanks:
https://gyazo.com/6365ab3fcc9d8167a1c9163563fbf3d7
Than i go forward:
https://gyazo.com/8490115e74b57e96cd1f3a9486db5fad
And when i go back again, the text field looks empty but the value is not empty, i want it so that i can still see the value inside:
https://gyazo.com/07eec4c58149641926d7f037bb0f949c
Here i will put the code of the TextFIeld:
Container(
margin: EdgeInsets.only(top: 20),
width: 360,
child:
Form(
autovalidateMode: AutovalidateMode.always,
onChanged: () {
Form.of(primaryFocus.context).save();
},
child: TextFormField(
decoration: new InputDecoration(
labelText: "Event Name",
fillColor: Colors.white,
border: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(25.0),
borderSide: new BorderSide(),
),
//fillColor: Colors.green
),
validator: (val) {
if (val.length == 0) {
return "Event Name cannot be empty";
} else {
return null;
}
},
onSaved: (String value) {
eventname = value;
},
style: new TextStyle(
fontFamily: "Poppins",
))))
add an initial value to your textformfield by loading the saved value

Flutter Why my textfield lose the value when I dont focus on it?

I made a class and it has a controller and a widget that includes a padding within a textfield.
Now when I change the focus from the textfield to something else it lose the value.
this is my code.
`
class RxInput {
final String hindText;
final bool obscureText;
Widget widget;
final TextEditingController controller = new TextEditingController ();
String get value => controller.text;
RxInput (this.hindText,context,{this.obscureText = false}) {
widget = Padding (
padding: const EdgeInsets.all(20.0),
child: Material(
borderRadius: BorderRadius.circular(20.0),
shadowColor: Colors.blue.shade200,
elevation: 5.0,
child:TextField(
controller: controller,
decoration: InputDecoration(
hintText: hindText,
border: InputBorder.none,
alignLabelWithHint: true,
),
obscureText: obscureText,
)
),
);
}
}
`
I solved this question. You should initialize your variable in the initState instead of build.