I have two forms in a tab bar. I'm using Getx for state management. All fields in those forms listen to a .obs variable. The forms fields are updating to the variable changes. How ever one field only reflect changes when that page is revisited.
I'm using this variables
final _countryCode = ''.obs
String get countryCode => _countryCode.value;
final _phone = ''.obs
String get phone => _countryCode.value;
These variable are updated on init.
void onInit(){
super.onInit();
_countryCode(user.countryCode); // assign country code
_phone(user.number); // assign number
}
return Obx(() => IntlPhoneField(
final UserController _controller = Get.find()
enabled: true,
showCountryFlag: false,
iconPosition: IconPosition.trailing,
autoValidate: false,
initialValue: _controller.initialPhoneNumber,
initialCountryCode: _controller.userCountryCode,
);
How ever this field is not updating on init. but updates after that page is revisited.. What's causing this? All other fields are updating without any issue. But this one will update only if its revisited. How can i solve this??
It's better to use GetBuilder instead of Obx.
GetBuilder(
init: UserController,
builder: (_controller){
return IntlPhoneField(
enabled: true,
showCountryFlag: false,
iconPosition: IconPosition.trailing,
autoValidate: false,
initialValue: _controller.initialPhoneNumber,
initialCountryCode: _controller.userCountryCode,
);}),
There is also an initstate attribute for GetBuilder,
You can get more details from here.
Related
So I have a ListView with Checkboxes
bool checked = false;
ListView.builder(
itemCount: logs!.length,
itemBuilder: (context, index) {
Log log = logs[index];
return ExpansionTile(
title:
Checkbox(
value: checked,
onChanged: (curValue) {
checked = curValue;
setState(() {});
}),
)
],
)
},
);
The problem is that when I check one Box in the List, all values are changed, because the variable is global & therefore the same boolean is appended to all checkboxes.
When I pack the boolean inside the ListView, I cant click on the Checkbox at all -> because of the setState the value is always reseted & no change appears
So what can I do to make all Checkboxes clickable without influencing the click state of the other ones?
Since you have only 1 variable to check the state of the checkbox, all other checkbox widgets will also depend on this checked variable.
You have to define for every checkbox a own "checked" variable, you could add a checked variable to the Log class and then query and set it each time.
Checkbox(
value: logs[index].checked,
onChanged: (curValue) {
logs[index].checked = curValue;
setState(() {});
},
),
The issue is here using single variable for all items. You can use a List for selected item
List<Log> selectedLogs = [];
Checkbox(
value: selectedLogs.contains(log),
onChanged: (curValue) {
if(selectedLogs.contains(log)){
selectedLogs.remove(log);
}else {
selectedLogs.add(log);
}
setState(() {});
}),
)
Let's say we want to pass an ID on form submission but we don't want the users to see it, on flutter_form_builder: ^7.1.1 there is no option to hide fields, any workaround?
I just found out that flutter_form_builder: ^7.1.1 offers to build your own custom field, so if we want to make a hidden field, we just return a SizedBox.shrink() on builder and set the initial value on FormBuilderField.Heres a sample code.
Widget taskIDField() {
return FormBuilderField(
name: "task_id",
enabled: false,
initialValue: widget.task?.id.toString(),
validator: FormBuilderValidators.compose([
FormBuilderValidators.required(context),
]),
builder: (FormFieldState<dynamic> field) {
//Empty widget
return const SizedBox.shrink();
},
);
}
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();
};
I created a dropdownButton to allow users to select from a dropdown list which will be populated from an API. For now I am populating using a list I created.
Currently the button is displaying the items from my list but after a selection has been made the list doesnt show the selected item and still shows the hint text. What I would like to happen is after a selection has been made then the dropdownButton shows the item that was selected instead of the hint text.
in the onChanged method I added a setState in hopes of updating the _selectedValue variable to the value that was selected and displaying it in the dropdownButton.
I also added a print statement in my setState method and that does trigger and show me the value within the value variable.
Here is my code.
List<DropdownMenuItem<int>> listItems = [DropdownMenuItem(child: Text("2016"), value: 2016,), DropdownMenuItem(child: Text("2021"), value: 2021,)];
int _selectedValue;
body: DropdownButton(
value: _selectedValue,
items: listItems,
hint: Text("Select Year"),
onChanged: (int value){
setState(() {
_selectedValue = value;
print(value);
});
},
),
Your code is fine, but the problem is maybe you are initializing the _selectedValue inside the build() method. So that whenever you call set state the widget rebuilds and initialize again with the default value.
int _selectedValue;
#override
Widget build(BuildContext context) {
return DropdownButton(
value: _selectedValue,
items: listItems,
hint: Text("Select Year"),
onChanged: (int value){
setState(() {
_selectedValue = value;
print(value);
});
},
),
In case anyone else is having this issue, I had the same issue and it was driving me nuts and I was using setState() appropriately etc., It was 100% where I was defining the "initialValue" property.
I was defining it right inside the build method. That did not work, even though I had the same setup in a sister module and it indeed did work. Not sure why that is.
Once I changed the definition of that variable to the state class, it worked like a charm. Hope it saves some, some cycles.
I'm having an issue with the use of a TextFormField in Flutter.
The method called in the initial value returns either null or a String depending on whether an add or edit screen is being used respectively.
If it is an edit screen I'd like the String to be the initial value, and the _itemName to be the initial value if it is not changed, or the new onChanged value if it is.
Below shows two of many attempts that I've made that have presented different problems.
In this case if the user does not edit the text the _itemName ends up being null or a zero length string (I can't remember exactly which one it is):
TextFormField(
initialValue: controller.initialNameValue(),
onChanged: (val) {
setState(() => _itemName = val);
}),
In this case the onChanged method does not update the _itemName and it remains at its initial value:
TextFormField(
initialValue: _itemName = controller.initialNameValue(),
onChanged: (val) {
setState(() => _itemName = val);
}),
The _itemName is then used in an add or edit method where it is passed as a parameter into a setter for a class.
How would I go about ensuring the _itemName remains as its initial value until it's changed, and then when it is changed it updates to the new value? Thanks
After some trial and error I've realised the way of overcoming this problem seems to be to introduce:
#override
void initState() {
super.initState();
_itemName = controller.initialNameValue();
}
And then change the TextFormField to:
TextFormField(
onChanged: (val) {
setState(() => _itemName = val);
},
initialValue: controller.initialNameValue(),
);
The main reason for not introducing a separate controller here was due to the fact I had multiple form fields within the widget I was building, and this created further confusion.
The above approach appears to have solved the issues that I faced, although I understand it may not be the cleanest approach to this.