I have created a function which return 4 textfields in column and I have called that function from 4 different containers, now how do I know from which container textfields are being changed because all the textfields are common to different containers. Thanks in advance.
in general you can handle the changes in Textfield in two way
1- Using onChanged() callback
TextField(
onChanged: (text) {
print('First text field: $text');
},
),
2- Using a TextEditingController
you create a controller
final myController = TextEditingController();
Connect the TextEditingController to a text field.
TextField(
controller: myController,
),
Create a function to print the latest value.
void _printLatestValue() {
print('Second text field: ${myController.text}');
}
Listen to the controller for changes.
#override
void initState() {
super.initState();
// Start listening to changes.
myController.addListener(_printLatestValue);
}
in your case you can pass controllers to your function and listen to it
What about using keys. You can choose unique keys for each of the different textfields(maybe you can generate keys when you programmatically generate the textfields). Alternatively, you can assign unique keys to the containers as well.
flutter textfield has onChanged property, you can do inside onChanged
Related
How to get more than 2 inputs from user and perform calculation and display the result in flutter application without using any library.
I wanna create a calculator without using any library, and want to do calculations like multiply, add subtract, division 2+6?/3-1 like this. I know how to do calculation for 2 digits but don't know how to do for more inputs. Should i use regex for this??if yes then how.
God to know:
You need TextFormField. In order to show results of the calculations to the client immediately, you should use setState method on TextFormField property onChanged.
TextEditingController _controllerFrom = TextEditingController();
String? valueFrom;
Example:
TextFormField(
onTap: () {},
controller: _controllerFrom ,
onChanged: (String value) {
if (value.isNotEmpty) {
setState(() {
valueFrom = value;
});
}
}
Also, you must dispose this controller when leaving this page on this way:
void dispose() {
// clean up the controller when the widget is disposed
_controllerFrom.dispose();
super.dispose();}
As you know, it is a basic requirement that; after the user makes an entry in an Autocomplete field (either by entering a new value or selecting an existing value from the dropdown list) and then press a 'Submit' button or 'Delete' button (say, to update the database); the old entry in the TextFormField should be cleared automatically for the next entry.
How can this be programmatically done in a simple way (for example, like Autocomplete.TextFormField.clear ) in Flutter?
I have tried several ways, but am unable to access/ modify the TextEditingController from an outside function.
Thank you in advance for any advice, please!
I am posting this for the benefit of whoever who reads this post, having a similar requirement.
A solution lies with flutter_typeahead widget, found here:
https://pub.dev/packages/flutter_typeahead
It could be used instead of RawAutocomplete or Autocomplete widgets.
You can use a RawAutocomplete to access the text editing controller from outside the Autocomplete. The RawAutocomplete is similar to Autocomplete, but it also provides the textEditingController and focusNode properties.
Note that if you pass in a textEditingController, you must also provide a non-null focusNode and fieldViewBuilder.
An example of modifying the textEditingController from outside the Autocomplete can be seen below.
final _controller = TextEditingController();
final _focusNode = FocusNode();
Widget build(BuildContext context) {
return RawAutocomplete<String>(
textEditingController: _controller,
focusNode: _focusNode,
fieldViewBuilder: (context, textEditingController, focusNode, onFieldSubmitted) =>
TextFormField(controller: _controller),
...
)};
//Then in your outside function
setState(() {
_controller.clear();
};
This might be not technical question,however, I read that whenever you want to change StatefullWidget state you need to call setState() function. i gave a test for EditText() widget and use the EditingTextController as widget controller, i called the controller.text = "some text"from user-defined function without calling setState() function and the value of the EditText() changed to be some text !
i would like to know how this done? i read the documentation and it says EditingTextController will change the value of the widget but we already know that in order to change
State Full Widget state you need to call setState()
Kind of this is true. But to change the state in Flutter you have other options, and setState(() {}); is only one of them. Another option is to create Notifier -> listener, then set the listener to listen for the Notifier, like this TextFormField(controller: _controller,...) so any update on the Notifier(controller), will notify the listener(TextFormField) to update itself.
e.g:
//...
final _controller = TextEditingController();
//...
child: TextFormField(
controller: _controller,
decoration: InputDecoration(border: OutlineInputBorder()),
),
in this example:
_controller: is a ChangeNotifier.
TextFormField: is a listener to this ChangeNotifier(_controller).
and once you call this _controller.text=.. the _controller (which is consider as ChangeNotifier see this.) "will notify all the listeners of this TextEditingController that they need to update", so it will give you same result as using setState(() {}); or Stream/StreamBuilder or Future/FutureBuilder...etc.
TextFormField has it's own property to perform actions, called "onFieldSubmited".
But i want to get the value from the TextFormField, when i press a RaisedButton or something.
How can i do it?
All you need is a TextEditingController
There is a cookbook for this in flutter's own website. Wonder how you missed it.
Use TextEditingController to get the value of a specific TextField.
https://flutter.dev/docs/cookbook/forms/text-field-changes
[...]
TextEditingController controllername = TextEditingController();
[...]
TextField(
controller: controllername, //...Rest of the code
)
Use the controllername.value to get the current value of a Textfield for that particular moment.
I have a TextField which has a default text in it from the beginning. I want the cursor to be placed at the end of the existing text when the TextField receives focus (possibly with the condition that the text should not have already been modified from the default text).
I've tried setting the controller.selection which didn't work. I also tried using a FocusNode:
focusNode: FocusNode()..addListener((){
if( !record.isCommentModified )
record.textEditingController.selection = TextSelection.collapsed(offset: record.comment.length);
})
It does work, but one side effect is that multiple textfields look like they have focus at the same time. How can I prevent this? Or even better, is there a better way of achieving what I want?
If there's a value set on a TextField, by default the cursor is positioned at the end of the text/value when focused. Let me know if the behavior you've encountered was different.
TextFields need to have individual FocusNode. Since you're using a single FocusNode for multiple, once one TexField is focused it appears that there are multiple TextFields in focus.
As for tracking which TextField contains text, individual TextEditingController is needed as well. What I can suggest is to create a List of FocusNode and TextEditingController for the TextFields.
late List<FocusNode> focusNodeList;
late List<TextEditingController> textController;
#override
void initState() {
super.initState();
// Initialize both List
textController = List<TextEditingController>.generate(
length, (index) => TextEditingController());
focusNodeList = List<FocusNode>.generate(length, (index) {
var focusNode = FocusNode();
focusNode.addListener(() {
// Do something
});
return focusNode;
});
}
and set them on your TextField
TextField(
controller: textController[0],
focusNode: focusNodeList[0],
),
TextField(
controller: textController[1],
focusNode: focusNodeList[1],
),
...