How to initialize a textfield in flutter - flutter

I am new to flutter and I’m trying to create a counter that begins from a user input and decrement but I can’t get an integer input from text field how can I initialize a user input to be an integer then add it to an int variable

That is quite simple, I will show you an example that you can follow.
Example:
class HomePage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return new HomePageState();
}
}
class HomePageState extends State<HomePage> {
// creating and initilizing a counter variable
int _counter = 0;
TextEditingController _controller = TextEditingController();
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new TextField(
controller: _controller,
decoration: new InputDecoration(labelText: "Enter your number"),
keyboardType: TextInputType.number,
),
FlatButton(
onPressed:(){
_counter = int.parse(_controller.text);
},
child: Text('Press Me!'),
)
],
));
}
}
At first, I created a counter and initialize it with '0' and then I created a controller which I will use for controlling the TextField. After that, I created a TextField widget and passed the _controller to it. I used the controller because I need to fetch data from the TextField so do we. We fetched data from the _controller via _controller.text which returns a string. Although we create the counter as an integer, we can't pass a string to it. So, I changed the data that we fetched from the _controller into an integer using int.parse(_controller.text) and then we passed it to the _counter variable.
Note: I had specified the keyboardType as TextInputType.number because we are dealing with numbers as you mentioned.

Related

Trying to get TextFormField data from another widget

I am building an app that generates form fields from JSON data.
the Form widget is declared in the custom_form.dart
child: Form(
key: _globalKey,
child: Column(
children: [
SizedBox(
height: 10,
),
Text("Register Form: "),
SizedBox(
height: 3,
),
for (var i = 0; i < this.widget.widgetList.length; i++)
generateWidgetFromType(this.widget.widgetList[i]),
I'm using that generateWidgetFrom Type to generate the widgets
Widget generateWidgetFromType(Mywidget mywidget) {
switch (mywidget.type) {
case "CheckBox":
return GenerateCheckBox(mywidget);
case "Input":
return CustomGeneratedWidget(mywidget,
onSaved: (value) => widget.test = value);
case "DatePicker":
return GenerateDatePicker(mywidget);
}
return Text("This type is not supported yet");
}
The TextFormField is declared in the CustomGeneratedWidget
child: TextFormField(
controller: textEditingController,
obscureText: isPasswordField(this.widget.mywidget.key),
keyboardType: customType(this.widget.mywidget.key),
decoration: InputDecoration(
labelText: this.widget.mywidget.label,
border: OutlineInputBorder()),
validator: (value) {
I want to retrieve data from TextFormField in the CustomGeneratedWidget when I click on the Add button in the custom_form.dart
One way might be to add a method called getValue() on to your CustomGeneratedWidget class:
class CustomGeneratedWidget extends Mywidget {
TextEditingController textEditingController = TextEditingController();
...
String getValue() {
return textEditingController.text;
}
...
#override
Widget build(BuildContext context) {
...
}
}
I'm guessing, based on what you're building, that you'll want to eventually get data not just from TextFormField / CustomGeneratedWidget instances, but also instances of GenerateCheckBox and GenerateDatePicker as well. With that being the case, if it were me, I would add an abstract method to Mywidget that you override in its subclasses, perhaps called getValue(). So, Mywidget might look like:
abstract class Mywidget extends Widget {
...
// this method is purposefully unimplemented, and is therefore an "abstract" method
dynamic getValue();
...
}
In your subclasses, such as CustomGeneratedWidget, you would "override" this method by redefining it / implementing it, and therefore making it "concrete":
class CustomGeneratedWidget extends Mywidget {
TextEditingController textEditingController = TextEditingController();
...
#override
String getValue() {
return textEditingController.text;
}
#override
Widget build(BuildContext context) {
return Container(
child: TextFormField(
controller: textEditingController
...
)
);
}
}
Back in custom_form.dart, in your handler for your 'Add' button, you could go through the list of created Mywidget instances and call getValue() on each.

How to show and use textformfield under each post in flutter?

I have a Posts screen where list of posts are displayed. I want to add a textformfield at the bottom area of each post so that users can enter their comments on particular post. As we know that we cannot create a TextEditingController for multiple textformfields.
How can I create, show and use textformfield with the each post for entering users comments?
I am sure there are multiple ways to do this, but here is one fairly simple approach.
Create a Map where the key is a TextFormField and the value is a TextEditingController.
Map<TextFormField, TextEditingController> fields = new Map<TextFormField, TextEditingController>();
Create a new controller and text field for each post and add them to the Map.
fields[text] = controller;
When you want to get the values, you can pass the text field into a method that gets the controller for that field from the Map.
Here is a very basic example of how this can work:
import 'package:flutter/material.dart';
class DynamicTextFieldsWithControllers extends StatefulWidget {
#override
State<StatefulWidget> createState() => DynamicTextFieldsWithControllersState();
}
class DynamicTextFieldsWithControllersState extends State<DynamicTextFieldsWithControllers> {
Map<TextFormField, TextEditingController> fields = new Map<TextFormField, TextEditingController>();
#override
Widget build(BuildContext context) {
List<Widget> widgets = [];
for(int i = 0; i < 5; i++) {
TextEditingController controller = new TextEditingController();
TextFormField text = TextFormField(
controller: controller,
);
fields[text] = controller;
widgets.add(Container(
margin: EdgeInsets.symmetric(horizontal: 8.0, vertical: 15.0),
child: Column(children: [
text,
FlatButton(
color: Colors.blue,
child: Text("Submit", style: TextStyle(color: Colors.white)),
onPressed: () {
getTextValue(text);
},
)
],)
));
}
return Scaffold(
body: Column(children: widgets),
);
}
getTextValue(TextFormField text) {
TextEditingController controller = fields[text];
String value = controller.text;
print(value);
return value;
}
}

Initial value for FlutterQuill editor

I'm trying to insert an initial value to the flutter_quill flutter text editor with no success. Link to package https://pub.dev/packages/flutter_quill . From a normal TextField I would have done something like below using the controller.
class _FooState extends State<Foo> {
TextEditingController _controller;
#override
void initState() {
super.initState();
_controller = new TextEditingController(text: 'Initial value');
}
#override
Widget build(BuildContext context) {
return new Column(
children: <Widget>[
new TextField(
// The TextField is first built, the controller has some initial text,
// which the TextField shows. As the user edits, the text property of
// the controller is updated.
controller: _controller,
),
],
);
}
}
I appreciate your help.

Flutter/Dart - How to Save State when Navigating back to a Form with Textfields?

Currently, when a user fills in a TextField the text is lost if they navigate away and then return. How can I get the text to stay in the field upon their return?
Here's the stateful widget I'm using;
class _EditPageState extends State<EditPage> {
final _formKey = GlobalKey<FormState>();
String audiotitle;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Form(
key: _formKey,
child: Container(
child: TextField(
decoration: new InputDecoration(
hintText: widget.oldaudiotitle,
),
keyboardType: TextInputType.text,
onChanged: (titleText) {
setState(() {
this.audiotitle = titleText;
});
},
),
),
),
);
}
}
What am I doing wrong here?
you have two ways :
store the Data of the text field and set the data in init method
(use sharedpreferences or any other database as per your requirements)
TextEditingController controller = TextEditingController();
#override
void initState() {
// TODO: implement initState
// retrive the Data
if(data != null) {
controller = new TextEditingController(text: data);
}
}
or if the first screen is navigating in the second Screen than just pop that screen
Navigator.pop(context);

Get Instance of controller attached to a TextField in a loop

I am trying to create a page with more than one TextField widgets in flutter. Number of textfields to display are determined at runtime. while creating those textfields a controller from the controller array is attached to each textfield.
Everything is working as expected. but doen't matter which textfield i click, i always get the callback of all the textfields in a single onChanged function.
Therefore, i am not able to detect that value of which textfield is changed.
Please refer to code for more insight.
In-Short, i just want to know how to get the instance of textfield controller which is currently active.
Could somebody please let me know what i am doing wrong.
Thanks
List<TextEditingController> _controllers = <TextEditingController>[];
int controllersAttached = -1;
#override
Widget build(BuildContext context) {
controllersAttached += 1;
for (int i = 0;i < fibProvider.quesTextList.length;i++) ...<dynamic>[
TextField(
autofocus: false,
cursorColor: const Color(0xFFD8D8D8),
maxLines: 1,
textAlign: TextAlign.center,
controller: _controllers[controllersAttached %fibProvider.numberOfBlanks],
onChanged: (String data) {
// here i can distinguish between the controllers depending upon the text
entered in them. but if there are 3 textfields and the same data is
entered in all the three then this code only returns the first
controller with the matched value.
final int index = _controllers.indexWhere(TextEditingController item) {
return data.compareTo(
item.text.toString()) == 0;
});
},
),
]
}
You can just pass i variable to onChanged callback inside collection-for:
class _MyHomePageState extends State<MyHomePage> {
final int _fields = 10;
List<TextEditingController> controllers;
#override
void initState() {
super.initState();
controllers = List.generate(_fields, (i) => TextEditingController());
}
#override
void dispose() {
controllers.forEach((c) => c.dispose());
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title)
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
for (int i = 0; i < _fields; i++)
TextField(
controller: controllers[i],
onChanged: (value) {
final controller = controllers[i];
print('Current field index is $i and new value is $value');
},
),
],
),
)
);
}
}