Dynamic TextFormField within a DataCell => (PaginatedDataTable) - flutter

I have a problem that when I create a TextFormField inside a DataCell it does not support placing a controller, that is, if I put a controller or even a focusnode, all the TextFormField in the table, which in theory are the same, will be typed together or always take the last one, it varies a lot.
Look at the code I'm doing:
DataCell(
TextFormField(
autofocus: true,
inputFormatters: [
new LengthLimitingTextInputFormatter(6),
],
style: TextStyle(color: context.read<DadosAcesso>().color),
initialValue: row.quantidade,
keyboardType: TextInputType.number,
onChanged: (text) {
txt = text;
updateProdutoQtde(text, index, row.codbarras);
},
onEditingComplete: (){
context.read<DadosAcesso>().search = false;
context.read<DadosAcesso>().focusBusca.requestFocus();
},
),
),
I tried using the provider there to see if it helped but it stayed the same, I believe I would have to do something with the index of the table, like creating a TextFormField that contains the index, the key will not be possible to use the index, because the index is int.

Related

Retain focus on the Textfield when clicked the submit/next/done button in keyboard

How to retain the focus in the TextField after clicking submit/next/done in keyboard?
This is my TextField:
TextField(
autofocus: true,
readOnly: !isReady,
focusNode: qtyNode,
controller: qtyController,
textAlign: TextAlign.right,
textInputAction: TextInputAction.next,
keyboardType: TextInputType.number,
maxLength: 4,
onEditingComplete: () {},
onChanged: (s) {
try {
ref.read(qtyProvider.state).state = int.parse(s);
} catch (e) {
ScaffoldMessenger.of(context)
..hideCurrentSnackBar()
..showSnackBar(
SnackBar(
content: Text(e.toString()),
backgroundColor: Colors.red,
),
);
}
},
onSubmitted: (x) async {
ref
.read(formDataProvider.notifier)
.updateSelected(context, qtyController.text);
qtyNode.requestFocus();
},
maxLengthEnforcement: MaxLengthEnforcement.enforced,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly
],
);
When the onSubmitted callback is called, I update my provider(riverpod) wit the latest value of the QTY entered by user. Then I go to the next data in the ListView and mark the next data as the new selected item.
But when I go to the next record, I still want to remain focus on my TextField.
I tried adding this solution but the behavior is different. The keyboard is still shown but when I click the numbers, it wont reflect to my TextField.
Update
It seems like a flutter issue, I made an issue in github and got redirected in this thread. You can follow up there if you also experience the same issue.
You need to use FocusNode for this. It's documented here with examples.

I wanna limit value of a quantity that user put on the text field (Flutter)

I want a user can input no more than 100 in my textfield.
If a user put more than 100 --let's say 123--, the text will show 100 instead of 123.
here is my code
TextField(
controller: qtyController,
keyboardType: TextInputType.number,
onTap: () => qtyController.text = '',
inputFormatters: [FilteringTextInputFormatter. digitsOnly,
LengthLimitingTextInputFormatter(3),
],
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
)
You can use the onChanged callback to listen to the changes
TextField(
controller: qtyController,
keyboardType: TextInputType.number,
onTap: () => qtyController.text = '',
onChanged: (val){
if (val.isNotEmpty) {
if(int.parse(val)>=100) {
qtyController.text = "100";
}
}
},
inputFormatters: [
FilteringTextInputFormatter.digitsOnly,
LengthLimitingTextInputFormatter(3),
],
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white),
)
The simplest approach is to supply an onChanged() callback to a TextField or a TextFormField. Whenever the text changes, the callback is invoked.
A more powerful, but more elaborate approach, is to supply a TextEditingController as the controller property of the TextField or a TextFormField.
Details on here:https://docs.flutter.dev/cookbook/forms/text-field-changes
You can use the maxLength property to set the maximum characters allowed in the TextField. Read more about it here.

How do I use the credit card date format mm/yy in FLUTTER

child: new TextFormField(
maxLength:5,
controller:
TextEditingController(text: donation.date),
onChanged: (value) {
donation.date = value;
},
decoration: InputDecoration(
suffixText: '',
suffixStyle: TextStyle(
color: Color(0xffde0486),
),
labelText: 'Expiry Date',
border: OutlineInputBorder(),
),
keyboardType: TextInputType.number,
textInputAction: TextInputAction.done,
style: TextStyle(color: Colors.white),
autofocus: true,
),
I have this piece of code for a credit card that I am implementing in Flutter. I want to put the mm/yy format on the textfield. When the user has entered the month, the text field should automatically show the '/'. How do I do this?
You can achieve your result using the onChange method. You can check the length of the input and insert a '/' into the text if it is 2 i.e. dd
You need to store the controller in a seperate variable, because we want to use it later for inserting '/':
var _controller = new TextEditingController(text: donation.date);
Add this _controller and onChange callback to your TextFormField:
TextFormField(
controller: _controller, //<-- Add controller here
onChanged: (value) {
if(value.length == 2) _controller.text += "/"; //<-- Automatically show a '/' after dd
donation.date = value;
},
...
),
Yo can try this package flutter_multi_formatter to format the Expiration Date field as well as the credit card number field.
Update !
I just found a package: flutter_masked_text2 that can help you solve the problem!
var controller = new MaskedTextController(mask: '00/00');

in flutter form? can TextFormField and ListTile work together

in writing forms
is it good to put TextFormField inside ListTile in subtitle argument or besides each other
what the best way to write forms that need many inputs type if I want to keep the layout look like a list
[![enter image description here][1]][1]
[exampleListTile(
title: Text('Event Name'),
subtitle: TextFormField(
decoration:
InputDecoration(labelText: 'Event Name Here'),
keyboardType: TextInputType.text,
validator: (value) {
if (value.isEmpty) {
return 'Invalid Text!';
}
},
onSaved: (value) {
print(value);
},
),
),][1]
ListTile is more used in a context of a list with items os same type, but there's no rule against using the way you are doing. Like most things in flutter it's a question of preference

Changing focus from one text field to the next in Flutter

I have two textFormField widgets. Once the user has completed the first text field I would like to focus on the next textField. Is there a way to do this in Flutter? Currently, the done button just closes the keyboard. I was guessing the focusNode class might be the answer to this but not really sure how that works does anyone have any good examples of focusNode class? Thanks in advance.
Yes, FocusNode and the onFieldSubmitted from a TextFormField are probably the way to go.
FocusScope.of(context).requestFocus(focusNode);
Here is an example that may help:
FocusNode textSecondFocusNode = new FocusNode();
TextFormField textFirst = new TextFormField(
onFieldSubmitted: (String value) {
FocusScope.of(context).requestFocus(textSecondFocusNode);
},
);
TextFormField textSecond = new TextFormField(
focusNode: textSecondFocusNode,
);
// render textFirst and textSecond where you want
You may also want to trigger FocusScope.of() from a button rather than onFieldSubmitted, but hopefully the above example gives you enough context to construct an appropriate solution for your use case.
Screenshot:
No need to use FocusNode
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: [
TextField(
decoration: InputDecoration(hintText: 'First Name'),
textInputAction: TextInputAction.next,
onEditingComplete: () => FocusScope.of(context).nextFocus(),
),
TextField(
decoration: InputDecoration(hintText: 'Last Name'),
textInputAction: TextInputAction.done,
onSubmitted: (_) => FocusScope.of(context).unfocus(),
),
],
),
);
}
There's a similar method like in Android.
Add
textInputAction
parameter to the TextFormField Widget, then add the property as;
TextInputAction.next
This is how I did it:
var _focusNodes = List.generate(6, (index) => FocusNode()));
And in the TextFormField:
TextFormField(
focusNode: _focusNodes[i],
maxLines: 1,
textInputAction: TextInputAction.next,
onChanged: (text) {
if (i < _controllers.length) {
if (text.isEmpty)
_focusNodes[i - 1].requestFocus();
else
_focusNodes[i + 1].requestFocus();
}
},
),