TextField click changes Switch in flutter - dart

As soon as a TextField gets focused, an object which stores if it's enabled changes so that the TextField gets disabled immediately. This also happens when another TextField above gets focused.
The TextField is placed inside a StatefulWidget and a Category object contains another object called Goal which contains a bool variable if it's enabled or disabled. This variable is also used to enable or disable the TextField.
TextField(
controller: _goalAmountController,
enabled: widget.category.goal.enabled,
decoration: InputDecoration(
labelText: "Goal Amount",
border: OutlineInputBorder(),
),
onChanged: (value) {
try {
widget.category.goal.amount = double.parse(value);
} on Exception {
//TODO display error message
print("Invalid Goal-Amount");
}
},
),
There's also a switch below the TextField to enable or disable the Goal by setting it's enabled variable.
SwitchListTile(
value: widget.category.goal.enabled,
title: Text("Enable Goal"),
onChanged: (value) {
setState(
() {
widget.category.goal.enabled = value;
},
);
},
),
I found out that it seems as if the click on a TextField would replace the Goal object with a new one which has false as the default value for enabled.

Try to use FocusNodes instead :
FocusNode textNode = FocusNode();
TextField(
focusNode: textNode,
controller: _goalAmountController,
enabled: widget.category.goal.enabled,
decoration: InputDecoration(
labelText: "Goal Amount",
border: OutlineInputBorder(),
),
later when you want to disable this textField when the user interact with another widget you can call:
textNode.unfocus() ;

Related

How to add done button on numeric keyboard in ios flutter

I am using Textformfield in flutter it is working fine in android but not in IOS , in IOS need done button . I want to display a numeric keyboard with done button in IOS.
Here is my code ..
TextFormField(
controller: inputminsto1,
style: TextStyle(color: Color(0xFF070A28).withOpacity(0.50),fontFamily: 'OpenSans', fontSize:14),
decoration: InputDecoration(
//icon of text field
//labelText: 'Mins',labelStyle: TextStyle(color: Color(0xFF070A28).withOpacity(0.50),fontFamily: 'OpenSans', fontSize:14), //label text of field
filled: true,
fillColor: Color(0xFFF6F6F6),
border: InputBorder.none,
hintText: 'Mins',
hintStyle: TextStyle(color: Color(0xFF070A28).withOpacity(0.50),fontFamily: 'OpenSans', fontSize:14),
),
validator: (value) {
if (value!.isEmpty) {
return 'Required *';
}
return null;
},
textInputAction: TextInputAction.done,
inputFormatters: <TextInputFormatter>[
LengthLimitingTextInputFormatter(3),
FilteringTextInputFormatter.digitsOnly,
FilteringTextInputFormatter.deny(
RegExp(r'\s'))
], // Only numbers can be entered
),
You just need to add
keyboardType: TextInputType.numberWithOptions(signed: true, decimal: true)
I think the code below is the only solution for that:
keyboardType:TextInputType.numberWithOptions(signed: true, decimal: true)

Use keyboard arrows to move to next textformfield

I have created a contact form with a few textformfields. When I'm using the keyboard I want to also use the the arrows at the top of the keyboard to move to next textformfield. I have already implemented TextInputAction.next so that when clicking on "return" you go to next textformfield, but I also want to include the arrows to do the same to go up/down.
The image below shows the arrows I want to include action on.
This is my current textformfield code:
Widget _createTextField(controller, keyboardType, int maxLength, int maxLines, String hintText, double screenWidth) {
return Expanded(
child: TextFormField(
scrollPadding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
textCapitalization: TextCapitalization.sentences,
textInputAction: TextInputAction.next,
style: TextStyle(fontSize: (screenWidth > maxMobileScreenWidth) ? 16 : 12),
controller: controller,
keyboardType: keyboardType,
maxLength: maxLength,
maxLines: maxLines,
validator: (value) {
if (value!.isEmpty) {
return '* Required field';
}
return null;
},
decoration: InputDecoration(
counterText: "",
filled: true,
hintText: hintText,
hintStyle: const TextStyle(color: Colors.black45),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(10.0)),
fillColor: const Color(0xff9ccb40),
),
),
);
}
You must use the Form() widget, on top of all your TextFromField.
you can use Form(child:Column(children:[])
suggest you to read this article

how to set initial(default) value in dropdownButton?

How to set initial value from cache to dropdown button?
have submitted button, if click submits button should add to drop-down button value. Now it's working. I need to add initial value to the drop-down button. and If add initial value and when click to submit button without selecting a value in dropdown selecting value should ant to pass
Container(
child: ButtonTheme(
alignedDropdown: true,
child: DropdownButton<WorkSource>(
isExpanded: true,
value: _workSources,
items: workSources.map((WorkSource value) {
return DropdownMenuItem<WorkSource>(
value: value,
child: Text(
value.description,
overflow: TextOverflow.ellipsis,
),
);
}).toList(),
onChanged: (value) => setState(() {
workSourceIndex = value.id;
_workSources = value;
}),
style: Theme.of(context).textTheme.title,
_workSources in your code should be the initial value. Just assign value to that in initState().

How to use onKeyUp event in TextField in flutter

I am using flutter to make a simple application.
In the below code, when TextBox changed event is fired then I call the method named updateTitle().
But I have to call the same method updateTitle(), when key is up, as we use in javascript and other languages too.
TextField(
controller: titleController,
style: textStyle,
onChanged: (value) => updateTitle(),
decoration: InputDecoration(
labelText: "Title",
labelStyle: textStyle,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
)),
),
For your use case, the onChangedworks just like onkyeup would work. Everytime that the user tap a new character in the textfield, it is fired.
In order to enable/disable a button you should listen to this event, do the test to see if the field isn't empty, modify a variable that will handle the button state, and call setState().
This is just a sample code. Not tested, but should work as is.
class _SoAnswerState extends State<SoAnswer> {
bool _buttonActive = false;
#override
Widget build(BuildContext context) {
...
TextField(
controller: titleController,
style: textStyle,
onChanged: (value) => updateButtonState(value), // onChanged return the value of the field
decoration: InputDecoration(
labelText: "Title",
labelStyle: textStyle,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
)
),
),
...
}
void updateButtonState(String text){
// if text field has a value and button is inactive
if(text != null && text.length > 0 && !_buttonActive){
setState(() {
_buttonActive = true;
}
}else if((text == null || text.length == 0) && _buttonActive){
setState(() {
_buttonActive = false;
}
}
}
Edit: add more information about the events
In JavaScript, the onkeyup event handler fires when the user releases a key that was previously pressed. When the user press and release a key inside a text field, the text field value changes. The onChanged listener in Flutter fires when the text field value changes. When working with a typing interface, where the user uses a tradicional keyboard, it is not a good idea to listen to all the changes of a text field, because the user can press and hold a key, leading the application to repeat the onchanged event too many times, once for every character repetition. That's not the case with a mobile interface, where the user (usually) can't press and hold a key.

How do I change Text Input Action Button (return/enter key) on Keyboard in Flutter?

In Android and iOS it is possible to change the enter/return key of the keyboard to e.g. a "Go" button (and other options).
On top, we can see the regular "Return" button on both systems, which is the one you get by default with no modifications in both Android & iOS native and Flutter.
Below that, there is another setting, again on both systems, which you can simply adjust in your native application. It is the "Go" button in this case.
The input action for a TextField (or TextFormField) can be specified like this (here, the Go button):
TextField(
textInputAction: TextInputAction.go
...
)
List of all available input actions.
This is how you can use textInputAction:
TextField(
textInputAction: TextInputAction.search,
onSubmitted: (value) {
print("search");
},
decoration: InputDecoration(
border: InputBorder.none,
prefixIcon: Icon(Icons.search),
hintText: 'Search ',
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
),
);
This is currently not possible.
Although you can edit flutter sources to make it possible quite easily.
The following edits are :
flutter/lib/src/widgets/editable_text.dart
Change _openInputConnection line ~430 to
void _openInputConnection() {
if (!_hasInputConnection) {
final TextEditingValue localValue = _value;
_lastKnownRemoteTextEditingValue = localValue;
_textInputConnection = TextInput.attach(this,
new TextInputConfiguration(
inputType: widget.keyboardType,
obscureText: widget.obscureText,
autocorrect: widget.autocorrect,
inputAction: widget.keyboardType == TextInputType.multiline
? TextInputAction.newline
: TextInputAction.done
)
)..setEditingState(localValue);
}
_textInputConnection.show();
}
In the same file, also declare a new field on EditableText class (not the state one) ~line 280
final TextInputAction textInputAction;
And assign it in EditableText constructor above line 164
this.textInputAction,
flutter/lib/src/material/text_field.dart
Same story. Add a new field, but to TextField instead :
final TextInputAction textInputAction;
and add the following to it's constructor :
this.textInputAction,
Finally, pass that new field as parameter to EditableText line 479 :
textInputAction: widget.textInputAction,
Done.
You can now inside your app specify a custom TextInputAction. This won't break existing TextField. It just adds the ability to override the default behavior.
new TextField(
keyboardType: TextInputType.text,
textInputAction: TextInputAction.newline,
),
basically we are use two types of text input fields,
TextField and TextFormField,
so,
for TextField,
TextField(
textInputAction: TextInputAction.go
.......
)
for TextFormField,
TextFormField(
textInputAction: TextInputAction.go,
........
)
both have textInputAction property, we can use this
Here is how to add the action button and also listen to onTap
For TextField
TextField(
textInputAction: TextInputAction.go,
onSubmitted: (value) {
print("Go button is clicked");
},
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
),
);
For TextFormField
TextFormField(
textInputAction: TextInputAction.go,
onFieldSubmitted: (value) {
print("Go button is clicked");
},
decoration: const InputDecoration(
hintText: "Type your search here",
hintStyle: TextStyle(color: Colors.black26),
filled: true,
fillColor: Colors.white,
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.all(Radius.circular(40.0)),
),
contentPadding:
EdgeInsets.symmetric(horizontal: 20.0, vertical: 16.0)),
)
One angle ... I have not explored all the "keyboardType" options within the TextField (optional parameter of TextInputType).
But there are some obvious different keyboards for 'emailAddress' and 'datetime' and 'phone' - one of those options may emit the keyboard that you are looking for ...
Anyone looking for UIReturnKeyDone is like this:
TextField(
textInputAction: TextInputAction.done
...
)

Resources