Cannot update DropdownButtonFormField field value in flutter with getx obs - flutter

I am using getx obs with fluter and the below is json response.
[{"id":1,"designation":"Deputy General Manager"},{"id":2,"designation":"Executive Director, Technical Operations","designation_short_code":"ED, TO"},{"id":3,"designation":"Manager","designation_short_code":"M"},{"id":4,"designation":"Sr. Manager","designation_short_code":"Sr. M"}]
In controller I am using--
var listData = List<dynamic>.empty(growable: true).obs;
var designation = 1.obs;
void setDesignation(int value) {
designation.value = value;
}
I am getting the above json response based on api call under listData.
In UI I am using the below code..
Obx(() => DropdownButtonFormField<dynamic>(
decoration: InputDecoration(
hintText: 'Designation',
labelText: 'Select Designation',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
),
filled: true,
fillColor: Colors.white,
errorStyle: TextStyle(color: Colors.yellow),
),
hint: Text(
'Select Designation',
),
onChanged: (selectedValue) {
designation_controller
.setDesignation(selectedValue);
},
value:
designation_controller.designation.value.toInt(),
items: designation_controller.listData.map((map) {
return DropdownMenuItem(
child: Text(map['designation']),
value: map['id'],
);
}).toList(),
)),
My problem is whenever I select designation it is not updating though my api end point is hitting with 200 response.
Can anyone help me please.
Thanks in advnace.

I have fixed problem. My problem was in the below code
updateData(
controller.userData[0]['id'],
controller.designationEdittingTextController.text
)
I have changed controller.designationEdittingTextController.text to controller.designationEdit.value as below
updateData(
controller.userData[0]['id'],
controller.designationEdit.value
)
Thanks

Related

Using Localization inside a list - Flutter

My application contains localizations (translation "en","ar"), in my translation JSON files there are cities that users will choose while registration process these cities appears in a DropDownButtonFormField widget as follows:
final provincesField = DropdownButtonFormField<String>(
value: dropDownValue,
onChanged: (String? newValue) {
setState(() {
dropDownValue = newValue!;
});
},
items: provinces.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: SizedBox(
width: 100.0,
child: Text(value, textAlign: TextAlign.center),
));
}).toList(),
elevation: 4,
decoration: InputDecoration(
prefixIcon: Icon(Icons.flag_circle),
labelText: AppLocalizations.of(context)!.chooseProvinence,
alignLabelWithHint: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
);
the cities are declared in this list:
List<String> provinces = [
'عمان',
'إربد',
'الزرقاء',
'المفرق',
'الطفيلة',
'عجلون',
'معان',
'الكرك',
'مادبا',
'العقبة',
'البلقاء',
'جرش'
];
String dropDownValue = 'عمان';
what am trying to achieve is that cities will appear to user based on the app language. I have tried to use AppLocalizations.of(context)!.city inside of the list but its not working so i believe there is some way to declare the list values based on localization, ill appreciate any help
Suppose below localizations data is your cities list
English:
"Dhaka" : "Dhaka",
"Chittagong" : "Chittagong",
"Cumilla" : "Cumilla",
"Rajshahi" : "Rajshahi",
"Bhola" : "Bhola",
Arabic:
"Dhaka" : "دكا",
"Chittagong" : "شيتاغونغ",
"Cumilla" : "كوميلا",
"Rajshahi" : "راجشاهي",
"Bhola" : "بولا",
initialize your the localization keys of your cities and dropDownValue
List<String> provinces = [
"Dhaka",
"Chittagong",
"Cumilla",
"Rajshahi",
"Bhola",
];
String dropDownValue = 'Dhaka';
here is the widget. I used getx localization. So I used 'tr' after the child text of DropdownMenuItem. I hope it's can help u.
Widget TestWidget() {
return DropdownButtonFormField<String>(
value: dropDownValue,
onChanged: (String? newValue) {
// To print the value with localization
print(newValue!.tr);
},
items: provinces.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(value: value, child: Text(value.tr));
}).toList(),
elevation: 4,
decoration: InputDecoration(
prefixIcon: Icon(Icons.flag_circle),
labelText: 'Select',
alignLabelWithHint: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
);
}
If you need to store the city in database or anywhere with localization then you can use it like [dropDownValue.tr]

How to save DropdownButtonFormField value to Firebase real-time database?

I'm using firebase real-time database and I have a form where the user adds the information to the database using it, but I'm stuck with the DropdownButtonFormField, how can I store the value in my database when the form button is pressed?
I used to use the controller when it was TextFormField, but now, I don't know what to do
DropdownButtonFormField(
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(20.0)),
borderSide:
BorderSide(width: 2, color: appColor),
),
labelText: 'Location',
labelStyle: TextStyle(
fontSize: 20, color: Colors.black)),
isExpanded: true,
// Initial Value
value: selectedLocation,
icon: const Icon(
Icons.keyboard_arrow_down,
color: appColor,
),
// Array list of items
items: Locations.map((String items) {
return DropdownMenuItem(
value: items,
child: Text(items),
);
}).toList(),
// After selecting the desired option,it will
// change button value to selected value
onChanged: (String? newLocation) {
setState(() {
selectedLocation = newLocation!;
});
},
),
you get the selectedLocation value and pass that to firebase method. print selectedLocation in the onChange method then when ever you click item in dropdown, the selectedLocation will change.
DatabaseReference ref = FirebaseDatabase.instance.ref("users/123");
await ref.set({
"selectedLocation": selectedLocation ,
});

When tap on textfield, app crashes returns homepage

Hi I get an error when user focus textfield, app crashes and returns to homepage (see clip here https://www.screencast.com/t/yiJkCBsibcoY)
I've had this error for a while now and cannot seem to fix it, sometimes it happens on other textfields. I cannot replicate the issue only sent from users. Anyone experience this with flutter?
Widget searchBox() {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
border: Border.all(color: Color(0xff0F004E), width: 1.0),
),
child: SimpleAutoCompleteTextField(
key: keyAuto,
controller: textController,
suggestions: suggestions,
textChanged: (text) => searchProduct = text,
textSubmitted: (text) {
loadingBarActive = true;
_sendAnalyticsEvent(text, 'serach_food_action');
searchProduct = text.replaceAll(new RegExp(r'[^\w\s]+'), '');
print('searchProduct RegX $searchProduct');
newSearch = true;
_filterCategories(searchProduct);
_filterRecipes(searchProduct);
// reset search values to intial
usdaItems.clear();
usda!.clear();
perPage = perPageIntial;
present.value = 0;
loadingBarActive = false;
selectApi = <int, Widget>{
0: allProductTab(),
1: allProductTab(),
2: allProductTab(),
3: allProductTab(),
};
setState(() {
_loadUSDAlist = usdaFoodProductList();
_loadOpenList = openFoodProductList();
});
},
style: TextStyle(
fontFamily: 'Nunito', fontSize: 20.0, color: Color(0xff0F004E)),
decoration: InputDecoration(
border: InputBorder.none,
// contentPadding: EdgeInsets.only(top: 14.0),
hintText: 'Search',
hintStyle: TextStyle(
fontFamily: 'Nunito', fontSize: 16.0, color: Color(0xff0F004E)),
prefixIcon: Icon(Icons.search, color: Color(0xff0F004E)),
suffixIcon: IconButton(
icon: Icon(Icons.close, color: Color(0xff0F004E)),
onPressed: () {
textController.clear();
})),
),
);
}
I had exactly the same issue and was literally going crazy trying to find the solution. For me the error originated in my usage of the GetX state management library. For me the issue was solved by replacing this:
Get.to(ReservationDetails(res: Reservation.empty()))
?.then(((value) => setState(() {
//Reload the reservations for the new date from the server
_taskesFuture =
FetchReservation(setStatePublic: _setStatePublic)
.fetchReservation(_selectedDate);
})));
with:
Navigator.push(context,
MaterialPageRoute(
builder: ((context) =>
ReservationDetails(res: Reservation.empty()))))
.then((value) => setState(() {
//Reload the reservations for the new date from the server
_taskesFuture =
FetchReservation(setStatePublic: _setStatePublic)
.fetchReservation(_selectedDate);
}));
I suggest you have a look at how you are opening the page you are experiencing this issue.

how to get selections from multi_select_flutter?

has to be something simple I'm not getting but have been struggling on this for way too long. If anybody can help me out I would be appreciative. I believe it has to do with some kind of type issues as when I make selections I have a print statement that then prints out what I'm getting back:
[Instance of 'MultiSelectItem', Instance of 'Analysis', Instance of 'Analysis']
Not sure how to convert the above to a List of Analysis and not able to carry out per the example for the package:
MultiSelectDialogField(
items: _animals.map((e) => MultiSelectItem(e, e.name)).toList(),
listType: MultiSelectListType.CHIP,
onConfirm: (values) {
_selectedAnimals = values;
},
),
where I also have to use a 'cast' in my code. My attempt:
MultiSelectDialogField(
items: _analyses.map((analysis) => MultiSelectItem<Analysis>(analysis, analysis.name)).toList(),
initialValue: outwardsData.outwards[widget.index].lossFeed
.map((analysis) => MultiSelectItem<Analysis>(analysis, analysis.name))
.toList(),
title: Text(
"Loss Feeds:",
style: TextStyle(color: Colors.black),
),
selectedColor: kConvexGreen,
unselectedColor: kConvexLightGreen,
backgroundColor: kConvexGreen,
decoration: BoxDecoration(
color: kConvexGreen.withOpacity(0.1),
borderRadius: BorderRadius.all(Radius.circular(5)),
border: Border.all(
color: kConvexGreen,
width: 2,
),
),
confirmText: Text(
'Submit',
style: TextStyle(color: Colors.white),
),
cancelText: Text(
'Cancel',
style: TextStyle(color: Colors.white),
),
searchable: true,
buttonText: Text("Loss Feeds"),
onSelectionChanged: (results) {
**print(results)**;
},
onConfirm: (results) {
// this is different than what example shows; without cast it errors
// "A value of type 'List<Object?>' can't be assigned to a variable of type 'List<Analysis>'". (Documentation)
_selectedAnalyses = results.cast();
},
chipDisplay: MultiSelectChipDisplay(
chipColor: kConvexGreen,
textStyle: TextStyle(color: Colors.white),
onTap: (value) {
setState(() {
_selectedAnalyses.remove(value);
// crashes here even though both are of same type List<Analyses> (theoretically)
// this is just here for testing purposes as am through many iterations trying to get
// data into lossFeed.
outwardsData.outwards[widget.index].lossFeed =
_selectedAnalyses;
});
},
),
),
I'm sure a more experienced flutter person will understand this (maybe) but I found that I couldn't just have the initial values come from the same list type used for the item (List< Analysis> _analyses) but I actually had to map it to use the same items data (_analyses).
initialValue: outwardsData.outwards[widget.index].lossFeed.map((analysis) => _analyses[analysis.id - 1]).toList()
Had other problems with this widget such as I found I couldn't map the results from onConfirm directly to List but instead had to do the following:
_rData.lossFeed = results.toList().cast<Analysis>()
as the data came back as List< dynamic>.
Couldn't find great examples online and trust experience will be the cure-all at some point.

Resetting TextfieldController for all textfields, using provider

I'm having a problem trying to figuring out the proper way on how to do this. Basically in my app, I want to reset all the fields for "cleanup" by the user. I can reset everything, but the TextFields. The only way that I found to solve the problem is by using the if that you can see inside the Consumer. I don't think though it's the proper way on how to handle this type of thing.
I also thought to push inside my provider class all the controller and then reset them, but I think it's still too heavy. I'm trying to find the cleanest and lightest solution, even to learn what's the best practice in these situations.
Thanks in advance!
return Provider.of<Provider_Class>(context, listen: false).fields[_label] != null ? SizedBox(
height: 57.5,
child: Consumer<Provider_Class>(builder: (context, provider, child) {
if (provider.resetted == true) {
_controller.text = "";
}
return Material(
elevation: this.elev,
shadowColor: Colors.black,
borderRadius: new BorderRadius.circular(15),
animationDuration: new Duration(milliseconds: 500),
child: new TextField(
focusNode: _focusNode,
keyboardAppearance: Brightness.light,
style: Theme.of(context).textTheme.headline5,
controller: _controller,
keyboardType: TextInputType.number,
textAlign: TextAlign.end,
inputFormatters: <TextInputFormatter>[
LengthLimitingTextInputFormatter(8),
_whichLabel(widget.label),
],
decoration: new InputDecoration(
enabledBorder: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(15),
borderSide: new BorderSide(width: 1.2, color: CliniLiliac300),
),
focusedBorder: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(15),
borderSide: new BorderSide(width: 2.5, color: CliniLiliac300),
),
filled: true,
fillColor: Colors.white,
hintText: "0.0",
hintStyle: new TextStyle(fontSize: 15, color: Colors.black, fontFamily: "Montserrat"),
),
onChanged: (val) {
var cursorPos = _controller.selection;
val = val.replaceAll(",", ".");
if (val == "") {
provider.fields[_label] = 0.0;
} else if (double.parse(val) > provider.measure[_label] &&
provider.measure[_label] != 0) {
provider.fields[_label] % 1 == 0
? _controller.text = provider.fields[_label].toString().split(".")[0]
: _controller.text = provider.fields[_label].toString();
if (cursorPos.start > _controller.text.length) {
cursorPos = new TextSelection.fromPosition(
new TextPosition(offset: _controller.text.length),
);
}
_controller.selection = cursorPos;
} else {
provider.fields[_label] = double.parse(val);
}
provider.calculateResultRA();
},
),
);
}),
) : SizedBox();
}
Use TextFormField instead of TextField. TextFormField has several callbacks like validator, onSaved, onChanged, onEditingComplete, onSubmitted, ...
You can connect all your TextFormFields by wrapping it in a Form. This form should be given a GlobalKey so that you can identify the Form and call methods on FormState.
final _form = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
// ...
return Form(
key: _form,
child: // build Material with TextFormFields
);
}
Now to call onSaved on each TextFormField, you can call _form.currentState().save(). To reset every TextFormField you can call _form.currentState().reset().
You can get more information about how to build a Form and the functions you can call on FomState here:
https://flutter.dev/docs/cookbook/forms/validation
https://api.flutter.dev/flutter/widgets/FormState-class.html