Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
400 views
in Technique[技术] by (71.8m points)

flutter - There should be exactly one item with [DropdownButton]'s value

I am building an app for an e-commerce system which can post data to the server. There are multiple item categories which have different and customizable values. For example, laptop category can have processor, ram, storage size attributes. Some of this attribute are textboxes (eg. model) while others need to be dropdowns (eg. processor - core i7, i5, etc...). The number of attributes can not be fixed since it depends on the category (might be added or removed anytime)

I was trying to build a form which will show this attributes as a textbox or dropdown depending on the attribute type (AttributeType column). I was able to show both the textboxes and dropdowns (with their elements successfully. The problem I have is accessing dropdown values to create a post request to the server.

Here is the code

 FutureBuilder<FormListModel>(
                future: _formList,
                builder: (context, snapshot) {
                  if (snapshot.hasData) {
                    return ListView.builder(
                      primary: false,
                      scrollDirection: Axis.vertical,
                      shrinkWrap: true,
                      itemCount: snapshot.data.customattributes.length,
                      itemBuilder: (context, index) {
                        var item = snapshot.data.customattributes[index];
                        print(item.name);
                        
                        if (item.AttributeType == 'Text') {
                          return Container(
                            //padding: EdgeInsets.only(top: 8),
                            margin:
                                EdgeInsets.only(top: 15, left: 15, right: 15),
                            child: Column(
                              children: [
                                Form(
                                  child: TextFormField(
                                    controller: model_controller,
                                    decoration: InputDecoration(
                                      contentPadding: EdgeInsets.symmetric(
                                          vertical: 10, horizontal: 10),
                                      labelText: item.name,
                                      border: OutlineInputBorder(
                                        borderSide: BorderSide(
                                            color: Colors.blueAccent),
                                      ),
                                    ),
                                    onChanged: (value) {
                                      //print(model_controller.text);
                                    },
                                  ),
                                ),
                              ],
                            ),
                          );
                        } else if (item.AttributeType == 'Selectlist') {
                          return Container(
                            //padding: EdgeInsets.only(top: 8),
                            margin:
                                EdgeInsets.only(top: 20, left: 15, right: 15),
                            child: Column(
                              children: [
                                Form(
                                  child: InputDecorator(
                                    decoration: InputDecoration(
                                      contentPadding: EdgeInsets.symmetric(
                                          vertical: 12, horizontal: 12),
                                      labelText: item.name,
                                      labelStyle: TextStyle(
                                          fontSize: 20,
                                          color: Colors.blueAccent),
                                      border: const OutlineInputBorder(),
                                    ),
                                    child: DropdownButtonHideUnderline(
                                      child: DropdownButton(
                                        isDense: true,
                                        icon: Icon(Icons.keyboard_arrow_down),
                                        value: selectedAttribute,
                                        onChanged: (newValue) {
                                          setState(() {
                                            selectedAttribute = newValue;
                                          });
                                        },
                                        //decoration: InputDecoration(border: InputBorder.none),
                                        items: item.children
                                            .map<DropdownMenuItem>((items) {
                                          return DropdownMenuItem<String>(
                                            child: Row(
                                              children: [
                                                Padding(
                                                  padding:
                                                      EdgeInsets.only(top: 7),
                                                  child: Text(items.element),
                                                ),
                                              ],
                                            ),
                                            value: items.element,
                                          );
                                        }).toList(),
                                      ),
                                    ),
                                  ),
                                ),
                              ],
                            ),
                          );
                        } else {
                          return null;
                        }
                      },
                    );
                  } else {
                    return Container();
                  }
                }),

Here is the json file which we get from the server to create the form using ListView.builder

{
    "category": {
        "CategoryName": "Laptops",
        "CategoryID": 34
    },
    "customattributes": [
        {
            "Name": "Model",
            "AttributeType": "Text",
            "AttributeID": 7
        },
        {
            "Name": "Processor",
            "AttributeType": "Selectlist",
            "AttributeID": 2,
            "Children": [
                {
                    "Element": "Intel Core i3"
                },
                {
                    "Element": "Intel Core i5"
                },
                {
                    "Element": "Intel Core i7"
                }
            ]
        },
        {
            "Name": "Storage Size",
            "AttributeType": "Selectlist",
            "AttributeID": 1,
            "Children": [                
                {
                    "Element": "1TB"
                },
                {
                    "Element": "2TB"
                },
                {
                    "Element": "2.5TB"
                }
            ]
        },
        {
            "Name": "RAM",
            "AttributeType": "Selectlist",
            "AttributeID": 3,
            "Children": [
                {
                    "Element": "12GB"
                },
                {
                    "Element": "16GB"
            ]
        }
    ],
    
}

Here is the form

enter image description here

When I select any value from the dropdown, I get an error which says, There should be exactly one item with [DropdownButton]'s value

enter image description here

  1. So how can I access the values of each dropdown so that I can make http post request to the server. Please bear in mind that the number of dropdowns (attributes) is vary for each category. 2nd question, not that important but is there a way where I can assign a name for each dropdown using the 'Name' column of the attributes in the json file.
question from:https://stackoverflow.com/questions/65915250/there-should-be-exactly-one-item-with-dropdownbuttons-value

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Try to set other dropdown value to null when changing the dropdown value in onChanged method


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...