List<Map<String, dynamic>> category = [
{
"name": "One",
"detail": ['11', '12', '13', '14'],
"department": "aaa",
},
{
"name": "two",
"detail": ['21', '22', '23', '24'],
"department": "bbb",
},
{
"name": "three",
"detail": ['31', '32', '33', '34'],
"department": "ccc",
},
{
"name": "four",
"detail": ['41', '42', '43', '44'],
"department": "aaa",
},
{
"name": "five",
"detail": ['41', '42', '43', '44'],
"department": "aaa",
},
];
for (final item in category) {
if (item["department"] == "aaa") {
for (final value in item.values) {
if (value is List) {
for (final listValue in value) {
data.add({'value': listValue, 'bold': false});
}
} else {
data.add({'value': item['department'], 'bold': true});
}
}
}
}
I have used the above (loop) method to doing the dropdown, but the category "name" will repeat many times, as shown in first picture
May I know how to make the list category be like the second picture dropdown, for example, the name will be the label, detail will be item of the label. Lastly, the 'department' is for classify showing which data, let say I want to show the data that department is 'aaa' means that 3 list data will be shown in the dropdown item.
Looking at your data named as "category" which is a list of Maps, I think you can add labels and achieve the required functionality that includes using custom variable in the following way:
const dept = 'aaa';
final data = category.where((element) => element['department'] == dept);
List<DropdownMenuItem<String>>? get_items() {
final List<DropdownMenuItem<String>> _dropdownItems1 = [];
for (final val in data) {
for (final value in val.values) {
if (value is List) {
for (final listValue in value) {
_dropdownItems1.add(
DropdownMenuItem(
child: Text(listValue),
value: listValue,
),
);
}
} else if (value != dept) {
_dropdownItems1.add(DropdownMenuItem(
child:
Text(value, style: const TextStyle(fontWeight: FontWeight.bold)),
value: value,
));
}
}
}
return _dropdownItems1;
}
Now, in the dropdownbutton you can simply call "get_items()" to get the dropdown menu items for creating the dropdown menu.
It can be done as mentioned in the code below.
DropdownButton<String>(
value: selectedItem,
items: get_items(),
onChanged: (value) {
setState(() {
selectedItem = value;
});
}),
The output will be as follows:
Output Dropdown menu
Related
I have list like this in provider:
List orders=[]:
void getOrders(){
orders = [
{"id":1,
"order":[
{"id":1,"name":"mike"},
{"id":2,"name":"john"},
{"id":3,"name":"smith"}
]
},
{"id":1,
"order":[
{"id":1,"name":"roz"},
{"id":2,"name":"sam"},
{"id":3,"name":"ruby"}
]
},
];
notifyListeners();
}
in provider when I use this methos to chane indexed order with another:
void changeOrder(orderIndex,item){
orders[orderIndex].update("order",(val)=>item);
notifyListeners();
}
I get this error type '(dynamic) => dynamic' is not a subtype of type '(Object) => Object' of 'update'
and when I use this :
void changeOrder(orderIndex,item){
orders[orderIndex]["order"]=item;
notifyListeners();
}
I get this error Unsupported operation: Cannot modify unmodifiable map
Add More Details
the item in changeOrder method comes from screen contain orders :
var item = List.from(orders[index]);
orders type is List<Map<String, dynamic>>. While reading the item, it will be a map instead of list.
Map item = Map.from(orders[index]);
And you can use both way you;ve tried.
List<Map<String, dynamic>> orders = [];
void getOrders() {
orders = [
{
"id": 1,
"order": [
{"id": 1, "name": "mike"},
{"id": 2, "name": "john"},
{"id": 3, "name": "smith"}
]
},
{
"id": 1,
"order": [
{"id": 1, "name": "roz"},
{"id": 2, "name": "sam"},
{"id": 3, "name": "ruby"}
]
},
];
}
void changeOrder(orderIndex, item) {
orders[orderIndex]["order"] = item;
// orders[orderIndex].update("order", (val) => item);
}
void main(List<String> args) {
getOrders();
print(orders);
Map item = Map.from(orders[1]);
changeOrder(1, item);
print(orders);
}
In Flutter, I am trying to make a dependent dropdown with the following json.
I Want the Dropdown to be in this format
First, Independent Dropdown
dataNames
Second, Dependent Dropdown
indexes of the dataSets' children
Third, Dependent Dropdown
select the children of the above drop-down (...hello 1, hello 2... )
[
{
"dataName": "data1",
"dataSets": [
["hello 1", "hello 2", "hello 3"],
["hi 1", "hi 2", "hi 3", "hi 4"]
]
},
{
"dataName": "data2",
"dataSets": [
["2nd 1", "2nd 2", "2nd 3"],
["let 1", "let 2", "let 3", "let 4"]
]
}
]
Here is the first step: parsing the json into a class model and then creating a list of models. second step build the DropdownMenuItem list to be consumed by the DropDownbutton. Create a _currentResultClass variable the first dropdownbutton (level1) selection. Step 3: filter on level 1 dataName and find the model then populate dropdownmenuitems based on a filter by that dataname.
class ResultClass
{
String?dataName;
//List<List<String>> dataSets= new List.generate(n, (i) => []);
List<List<String>>? dataSets= [];
ResultClass({this.dataName,this.dataSets});
ResultClass.fromJson(Map<String, dynamic> json) {
dataName = json['dataName'];
dataSets = json['dataSets'];
}
Map<String,dynamic> toJson(){
final Map<String,dynamic>data = new Map<String,dynamic>();
data['dataName']=this.dataName;
data['dataSet']=this.dataSets;
return data;
}
}
class TestDropDown extends StatefulWidget {
TestDropDown({Key? key}) : super(key: key);
#override
State<TestDropDown> createState() => _TestDropDownState();
}
class _TestDropDownState extends State<TestDropDown> {
ResultClass ? _currentResultClassLevel1;
String ? _currentStringLevel2;
List<ResultClass> lst=[];
List<DropdownMenuItem<ResultClass>>? itemsLevel1;
var data=[
{
"dataName": "data1",
"dataSets": [
["hello 1", "hello 2", "hello 3"],
["hi 1", "hi 2", "hi 3", "hi 4"]
]
},
{
"dataName": "data2",
"dataSets": [
["2nd 1", "2nd 2", "2nd 3"],
["let 1", "let 2", "let 3", "let 4"]
]
}
];
#override
void initState() {
// TODO: implement initState
super.initState();
for(var i=0; i<data.length; i++)
{
ResultClass model = ResultClass.fromJson(data[i]);
lst.add(model);
if (i==0)
{
_currentResultClassLevel1=model;
}
}
itemsLevel1 = lst
.map((item) => DropdownMenuItem<ResultClass>(
child: Text(item.dataName??""), value: item))
.toList();
}
#override
Widget build(BuildContext context) {
List<ResultClass> models = lst.where((item)=> item.dataName==_currentResultClassLevel1?.dataName).toList();
List<String> strings=[];
models.forEach((model)=>
model.dataSets?[0].forEach((element)=>strings.add(element)));
var itemsLevel2= strings.map((item) => DropdownMenuItem<String>(
child: Text(item), value: item))
.toList();
return Scaffold(appBar: AppBar(title: Text("Dropdown"),),body:
Column(children: [
DropdownButton<ResultClass>(items: itemsLevel1,
value: this._currentResultClassLevel1,
onChanged: (item){
setState(() {
_currentResultClassLevel1=item;
});
},),
DropdownButton<String>(items: itemsLevel2,
value: this._currentStringLevel2,
onChanged: (item){
setState((){
_currentStringLevel2=item;
});
},),
SizedBox(height:50)
],)
);
}
}
I am working with dropbox, but what i want to do is retrieve value depending on what the user chooses on the dropbox; for example the users picks "apple" on the dropdownbox what i want to return will be "Vitamin C"
Here is what i have so far:
String myFruits;
List<String> fruits = [
"APPLE",
"ORANGE",
"BANANA",];
DropdownSearch(
onChanged: (dynamic value) {
myFruits = value;
},
mode: Mode.DIALOG,
items: fruits,
),
For now when i print myFruits what it shows is the selected value of the dropbox, what I want is that if pick apple it will return "vitamin c" like that. Thanks :) How can i achieve this?
you can define a Map from fruits and returnedValue like:
Map<String, String> returnedValue = {
"APPLE" : "Vitamin A",
"ORANGE" : "Vitamin C",
"BANANA" : "Vitamin K",
};
and return from this.
all your code like this :
Function(String) returnFunction();
String myFruits;
String myVitamin;
List<String> fruits = [
"APPLE",
"ORANGE",
"BANANA",
];
Map<String, String> returnedValue = {
"APPLE" : "Vitamin A",
"ORANGE" : "Vitamin C",
"BANANA" : "Vitamin K",
};
DropdownSearch(
onChanged: (dynamic value) {
myFruits = value;
myVitamin = returnedValue[value];
returenFunction(myVitamin); // if you want return from this class
},
mode: Mode.DIALOG,
items: fruits,
),
I populate the dropdown menu with the GET Request's distList.sectionName values. What I am trying to do is catch the index of the selected museum and then send this index's values to the another API call. For example; lets say user is select the "İnternet Müzesi" in the dropdown menu. After that I need to locate the position of the "İnternet Müzesi" in the distList. And then catch this two fields: "distId": "MRK" and "sectionId": "INT01" values so I can send these values to another API call. How can I achieve this?
My DropdownButton widget:
Container(
child: DropdownButton<String>(
hint: Text("Lütfen listeden seçim yapın."),
items: snapshot.data.distList
.map<DropdownMenuItem<String>>((item) {
return DropdownMenuItem<String>(
value: item.sectionName,
child: Text(item.sectionName));
}).toList(),
value: _currentSelectedValue,
isExpanded: false,
onChanged: (String? value) {
print("Drop Down Selected Museum is $value");
setState(() {
_currentSelectedValue = value;
});
},
),
),
Here is my GET Request response:
"distList": [
{
"distId": "MRK",
"sectionId": "INT01",
"sectionName": "İnternet Müzesi",
"sectionNameEng": null
},
{
"distId": "IAR",
"sectionId": "IAR01",
"sectionName": "İstanbul Arkeoloji Müzesi",
"sectionNameEng": "İSTANBUL ARCHAEOLOGICAL MUSEUMS"
},
{
"distId": "TPK",
"sectionId": "TPK01",
"sectionName": "İstanbul Topkapı Sarayı Müzesi",
"sectionNameEng": "TOPKAPI PALACE MUSEUM"
},
{
"distId": "MRK",
"sectionId": "CUM01",
"sectionName": "Ankara Cumhuriyet Müzesi",
"sectionNameEng": "MUSEUM OF REPUBLIC OF ANKARA"
}
],
"acknowledge": true,
"message": null,
"requestId": null
}
ok, I found the solution.
in the setState I catch the selectedValue's field like this:
_currentSelectedValue = value;
var var2 = snapshot.data.distList!.firstWhere(
(e) =>
e.sectionName ==
"$_currentSelectedValue");
print(var2.distId);
print(var2.sectionId);
});
how all pages to map title print?
how json select example id=12 to map print title
{
"result": {
"name": "json1",
"pages": [
{
"zones": [
{
"title": "title1"
},
{
"title": "title2"
}
],
"id": 4
},
{
"zones": [
{
"title": "title3"
},
{
"title": "title4"
}
],
"id": 12
}
],
"creatorUserName": "admin",
"id": 2
}
}
List post = json;
children: post
.map( (post) => Container(
child: Center(child: Text(post.title]),)
))
.toList(),
I make a code to parse your json
var data = json.decode(jsonData);
var pagesArray = data["result"]["pages"];
pagesArray.forEach((page) {
var zones = page["zones"];
//Each id have your titles
int id = page["id"];
List<String> titles = new List();
zones.forEach((zone) {
titles.add(zone["title"]);
});
print("Id $id have this titles : ${titles.toString()}");
});