How to populating 2nd DropdownMenu based on first item selected flutter

0

I'm populating states name from JSON and display as a dropdown list after that I show 2nd dropdown list based on first value selected. But I don't now how to populate 2nd dropdown when 1st dropdown value changed. I also want to get location id, name and city when select 2nd dropdown value.

My Json

{
    "data": [
        {
            "state": "TEXAS",
            "locations": [
                {
                    "id": 1,
                    "name": "FITT Sugarland",
                    "city": "HOUSTON",
                    "state": "TEXAS",
                    "timezone": "",
                    "ownerName": "",
                    "ownerPhoneNumber": "",
                    "ownerEmail": "",
                    "ownerWebsite": "",
                    "capacity": 0,
                    "description": "HOUSTON SUGARLAND",
                    "createdBy": "",
                    "modifiedBy": "",
                    "createdAt": "2020-08-18T10:17:55.000Z",
                    "modifiedAt": "2020-08-18T10:17:55.000Z"
                },
                {
                    "id": 2,
                    "name": "FITT Pearland",
                    "city": "HOUSTON",
                    "state": "TEXAS",
                    "timezone": "",
                    "ownerName": "",
                    "ownerPhoneNumber": "",
                    "ownerEmail": "",
                    "ownerWebsite": "",
                    "capacity": 0,
                    "description": "second location",
                    "createdBy": "",
                    "modifiedBy": "",
                    "createdAt": "2020-08-18T10:18:38.000Z",
                    "modifiedAt": "2020-08-18T10:18:38.000Z"
                }
            ]
        }
    ]
}

Model Class

class LocationModel {
  List<LocationList> data;

  LocationModel({this.data});

  LocationModel.fromJson(Map<String, dynamic> json) {
    if (json['data'] != null) {
      data = new List<LocationList>();
      json['data'].forEach((v) {
        data.add(new LocationList.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.data != null) {
      data['data'] = this.data.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class LocationList {
  String state;
  List<Locations> locations;

  LocationList({this.state, this.locations});

  LocationList.fromJson(Map<String, dynamic> json) {
    state = json['state'];
    if (json['locations'] != null) {
      locations = new List<Locations>();
      json['locations'].forEach((v) {
        locations.add(new Locations.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['state'] = this.state;
    if (this.locations != null) {
      data['locations'] = this.locations.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class Locations {
  int id;
  String name;
  String city;
  String state;
  String timezone;
  String ownerName;
  String ownerPhoneNumber;
  String ownerEmail;
  String ownerWebsite;
  int capacity;
  String description;
  String createdBy;
  String modifiedBy;
  String createdAt;
  String modifiedAt;

  Locations(
      {this.id,
      this.name,
      this.city,
      this.state,
      this.timezone,
      this.ownerName,
      this.ownerPhoneNumber,
      this.ownerEmail,
      this.ownerWebsite,
      this.capacity,
      this.description,
      this.createdBy,
      this.modifiedBy,
      this.createdAt,
      this.modifiedAt});

  Locations.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    name = json['name'];
    city = json['city'];
    state = json['state'];
    timezone = json['timezone'];
    ownerName = json['ownerName'];
    ownerPhoneNumber = json['ownerPhoneNumber'];
    ownerEmail = json['ownerEmail'];
    ownerWebsite = json['ownerWebsite'];
    capacity = json['capacity'];
    description = json['description'];
    createdBy = json['createdBy'];
    modifiedBy = json['modifiedBy'];
    createdAt = json['createdAt'];
    modifiedAt = json['modifiedAt'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['name'] = this.name;
    data['city'] = this.city;
    data['state'] = this.state;
    data['timezone'] = this.timezone;
    data['ownerName'] = this.ownerName;
    data['ownerPhoneNumber'] = this.ownerPhoneNumber;
    data['ownerEmail'] = this.ownerEmail;
    data['ownerWebsite'] = this.ownerWebsite;
    data['capacity'] = this.capacity;
    data['description'] = this.description;
    data['createdBy'] = this.createdBy;
    data['modifiedBy'] = this.modifiedBy;
    data['createdAt'] = this.createdAt;
    data['modifiedAt'] = this.modifiedAt;
    return data;
  }
}

My Code

import 'dart:io';

import 'package:fittheorem/models/location_list.dart';
import 'package:fittheorem/providers/auth_session.dart';
import 'package:fittheorem/providers/user_details.dart';
import 'package:fittheorem/ui/widgets/error_snakbar.dart';
import 'package:fittheorem/utils/app_config.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';

class LocationUpdate extends StatefulWidget {
  @override
  _LocationUpdateState createState() => _LocationUpdateState();
}

class _LocationUpdateState extends State<LocationUpdate> {
  LocationModel _locationModel;
  bool isLoading = true;
  String _selectedState = "TEXAS";
  List<String> _statesList = [];

  String _selectedLocation = "FITT Sugarland";
  List<Locations> _locationsList = List();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    getList();
  }

  Future<void> getList() async {
    try {
      _locationModel = await Provider.of<UserDetails>(context, listen: false)
          .getLocationList("token");
      for (int i = 0; i < _locationModel.data.length; i++) {
        _statesList.add(_locationModel.data[i].state);
      }
      _locationsList = _locationModel.data[0].locations;
      _selectedState = _statesList[0];
      _selectedLocation = _locationsList[0].name;
      if (mounted) {
        setState(() {
          isLoading = false;
        });
      }
    } on HttpException catch (error) {
      CustomWidgets.buildErrorSnackbar(context);
    } catch (error) {
      CustomWidgets.buildErrorSnackbar(context);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: AppConfig.bgColor,
        child: SafeArea(
          child: Column(
            children: <Widget>[
              Container(
                padding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
                height: 40.0,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    GestureDetector(
                      behavior: HitTestBehavior.translucent,
                      onTap: () {
                        Navigator.pop(context, true);
                      },
                      child: Container(
                          height: 25.0,
                          width: 25.0,
                          child: SvgPicture.asset(AppConfig.backImage,
                              color: Colors.white, semanticsLabel: 'back')),
                    ),
                    Text('LOCATION',
                        style: GoogleFonts.roboto(
                          textStyle: TextStyle(
                              fontSize: 18.0, color: Color(0xffFFFFFF)),
                        )),
                    SizedBox(
                      width: 25.0,
                    ),
                  ],
                ),
              ),
              Expanded(
                child: Container(
                  color: Colors.white,
                  height: MediaQuery.of(context).size.height,
                  width: MediaQuery.of(context).size.width,
                  padding: EdgeInsets.all(30.0),
                  child: isLoading
                      ? Center(
                          child: AppConfig().myLoader(),
                        )
                      : Column(
                          mainAxisAlignment: MainAxisAlignment.start,
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            SizedBox(
                              height: 20.0,
                            ),
                            Padding(
                              padding: const EdgeInsets.only(left: 5.0),
                              child: Text('UPDATE YOUR LOCATION',
                                  style: GoogleFonts.roboto(
                                    textStyle: TextStyle(
                                        fontSize: 16.0,
                                        color: Color(0xff000000)),
                                  )),
                            ),
                            SizedBox(
                              height: 20.0,
                            ),
                            Container(
                              height: 40.0,
                              decoration: new BoxDecoration(
                                border: new Border.all(
                                    color: Colors.black54, width: 0.0),
                                borderRadius: new BorderRadius.circular(10.0),
                              ),
                              child: new DropdownButtonHideUnderline(
                                  child: ButtonTheme(
                                      alignedDropdown: true,
                                      child: new DropdownButton(
                                        value: _selectedState,
                                        hint: Text("State"),
                                        isExpanded: true,
                                        items: _statesList
                                            .map((String item) =>
                                                DropdownMenuItem<String>(
                                                    child: Text(item),
                                                    value: item))
                                            .toList(),
                                        onChanged: (String newValue) {
                                          if (mounted)
                                            setState(() {
                                              _selectedState = newValue;
                                            });
                                        },
                                        style: Theme.of(context)
                                            .textTheme
                                            .bodyText2,
                                      ))),
                            ),
                            SizedBox(
                              height: 20.0,
                            ),
                            Container(
                              height: 40.0,
                              decoration: new BoxDecoration(
                                border: new Border.all(
                                    color: Colors.black54, width: 0.0),
                                borderRadius: new BorderRadius.circular(10.0),
                              ),
                              child: new DropdownButtonHideUnderline(
                                  child: ButtonTheme(
                                      alignedDropdown: true,
                                      child: new DropdownButton(
                                        value: _selectedLocation,
                                        hint: Text("Location"),
                                        isExpanded: true,
                                        items: _locationsList.map((item) {
                                          return new DropdownMenuItem(
                                            child: new Text(item.name),
                                            value: item.name,
                                          );
                                        }).toList(),
                                        onChanged: (newValue) {
                                          if (mounted) print(newValue);
                                          setState(() {
                                            _selectedLocation = newValue;
                                          });
                                        },
                                        style: Theme.of(context)
                                            .textTheme
                                            .bodyText2,
                                      ))),
                            )
                          ],
                        ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}
flutter
dart
drop-down-menu
asked on Stack Overflow Aug 19, 2020 by Gursewak Singh

1 Answer

1

You can copy paste run full code below
Step 1: Change data type of _selectedLocation

Locations _selectedLocation;

Step 2: _selectedState's onChanged

onChanged: (String Value) {
      if (mounted)
        setState(() {
          _selectedState = Value;

          int index = _locationModel.data
              .indexWhere((element) =>
                  element.state ==
                  _selectedState);

          _locationsList = _locationModel
              .data[index].locations;
          _selectedLocation =
              _locationsList[0];
        });
    },

Step 3: _selectedLocation's onChanged

onChanged: (Value) {
      if (mounted) print(Value);
      setState(() {
        _selectedLocation = Value;
        print(
            "${_selectedLocation.name} ${_selectedLocation.id} ${_selectedLocation.city}");
      });
    },

working demo

enter image description here

full code

import 'dart:convert';

import 'package:flutter/material.dart';

LocationModel locationModelFromJson(String str) =>
    LocationModel.fromJson(json.decode(str));

class LocationModel {
  List<LocationList> data;

  LocationModel({this.data});

  LocationModel.fromJson(Map<String, dynamic> json) {
    if (json['data'] != null) {
      data = List<LocationList>();
      json['data'].forEach((v) {
        data.add(LocationList.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = Map<String, dynamic>();
    if (this.data != null) {
      data['data'] = this.data.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class LocationList {
  String state;
  List<Locations> locations;

  LocationList({this.state, this.locations});

  LocationList.fromJson(Map<String, dynamic> json) {
    state = json['state'];
    if (json['locations'] != null) {
      locations = List<Locations>();
      json['locations'].forEach((v) {
        locations.add(Locations.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = Map<String, dynamic>();
    data['state'] = this.state;
    if (this.locations != null) {
      data['locations'] = this.locations.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class Locations {
  int id;
  String name;
  String city;
  String state;
  String timezone;
  String ownerName;
  String ownerPhoneNumber;
  String ownerEmail;
  String ownerWebsite;
  int capacity;
  String description;
  String createdBy;
  String modifiedBy;
  String createdAt;
  String modifiedAt;

  Locations(
      {this.id,
      this.name,
      this.city,
      this.state,
      this.timezone,
      this.ownerName,
      this.ownerPhoneNumber,
      this.ownerEmail,
      this.ownerWebsite,
      this.capacity,
      this.description,
      this.createdBy,
      this.modifiedBy,
      this.createdAt,
      this.modifiedAt});

  Locations.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    name = json['name'];
    city = json['city'];
    state = json['state'];
    timezone = json['timezone'];
    ownerName = json['ownerName'];
    ownerPhoneNumber = json['ownerPhoneNumber'];
    ownerEmail = json['ownerEmail'];
    ownerWebsite = json['ownerWebsite'];
    capacity = json['capacity'];
    description = json['description'];
    createdBy = json['createdBy'];
    modifiedBy = json['modifiedBy'];
    createdAt = json['createdAt'];
    modifiedAt = json['modifiedAt'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = Map<String, dynamic>();
    data['id'] = this.id;
    data['name'] = this.name;
    data['city'] = this.city;
    data['state'] = this.state;
    data['timezone'] = this.timezone;
    data['ownerName'] = this.ownerName;
    data['ownerPhoneNumber'] = this.ownerPhoneNumber;
    data['ownerEmail'] = this.ownerEmail;
    data['ownerWebsite'] = this.ownerWebsite;
    data['capacity'] = this.capacity;
    data['description'] = this.description;
    data['createdBy'] = this.createdBy;
    data['modifiedBy'] = this.modifiedBy;
    data['createdAt'] = this.createdAt;
    data['modifiedAt'] = this.modifiedAt;
    return data;
  }
}

class LocationUpdate extends StatefulWidget {
  @override
  _LocationUpdateState createState() => _LocationUpdateState();
}

class _LocationUpdateState extends State<LocationUpdate> {
  LocationModel _locationModel;
  bool isLoading = true;
  String _selectedState = "TEXAS";
  List<String> _statesList = [];

  Locations _selectedLocation;
  List<Locations> _locationsList = List();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    getList();
  }

  Future<void> getList() async {
    try {
      /*_locationModel = await Provider.of<UserDetails>(context, listen: false)
          .getLocationList("token");*/
      String jsonString = '''
     {
    "data": [
        {
            "state": "TEXAS",
            "locations": [
                {
                    "id": 1,
                    "name": "FITT Sugarland",
                    "city": "HOUSTON",
                    "state": "TEXAS",
                    "timezone": "",
                    "ownerName": "",
                    "ownerPhoneNumber": "",
                    "ownerEmail": "",
                    "ownerWebsite": "",
                    "capacity": 0,
                    "description": "HOUSTON SUGARLAND",
                    "createdBy": "",
                    "modifiedBy": "",
                    "createdAt": "2020-08-18T10:17:55.000Z",
                    "modifiedAt": "2020-08-18T10:17:55.000Z"
                },
                {
                    "id": 2,
                    "name": "FITT Pearland",
                    "city": "HOUSTON",
                    "state": "TEXAS",
                    "timezone": "",
                    "ownerName": "",
                    "ownerPhoneNumber": "",
                    "ownerEmail": "",
                    "ownerWebsite": "",
                    "capacity": 0,
                    "description": "second location",
                    "createdBy": "",
                    "modifiedBy": "",
                    "createdAt": "2020-08-18T10:18:38.000Z",
                    "modifiedAt": "2020-08-18T10:18:38.000Z"
                }
            ]
        },
         {
            "state": "A",
            "locations": [
                {
                    "id": 1,
                    "name": "A1",
                    "city": "A City 1",
                    "state": "A",
                    "timezone": "",
                    "ownerName": "",
                    "ownerPhoneNumber": "",
                    "ownerEmail": "",
                    "ownerWebsite": "",
                    "capacity": 0,
                    "description": "HOUSTON SUGARLAND",
                    "createdBy": "",
                    "modifiedBy": "",
                    "createdAt": "2020-08-18T10:17:55.000Z",
                    "modifiedAt": "2020-08-18T10:17:55.000Z"
                },
                {
                    "id": 2,
                    "name": "A2",
                    "city": "A city 2",
                    "state": "A",
                    "timezone": "",
                    "ownerName": "",
                    "ownerPhoneNumber": "",
                    "ownerEmail": "",
                    "ownerWebsite": "",
                    "capacity": 0,
                    "description": "second location",
                    "createdBy": "",
                    "modifiedBy": "",
                    "createdAt": "2020-08-18T10:18:38.000Z",
                    "modifiedAt": "2020-08-18T10:18:38.000Z"
                }
            ]
        }
    ]
}
      ''';
      _locationModel = locationModelFromJson(jsonString);
      for (int i = 0; i < _locationModel.data.length; i++) {
        _statesList.add(_locationModel.data[i].state);
      }
      _locationsList = _locationModel.data[0].locations;
      _selectedState = _statesList[0];
      _selectedLocation = _locationsList[0];
      if (mounted) {
        setState(() {
          isLoading = false;
        });
      }
      //} on HttpException catch (error) {
      // CustomWidgets.buildErrorSnackbar(context);
    } catch (error) {
      //CustomWidgets.buildErrorSnackbar(context);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        //color: AppConfig.bgColor,
        child: SafeArea(
          child: Column(
            children: <Widget>[
              Container(
                padding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
                height: 40.0,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    GestureDetector(
                      behavior: HitTestBehavior.translucent,
                      onTap: () {
                        Navigator.pop(context, true);
                      },
                      child: Container(
                          height: 25.0,
                          width: 25.0,
                          child: Image.network(
                              'https://picsum.photos/250?image=9',
                              color: Colors.white)),
                    ),
                    Text('LOCATION',
                        style: TextStyle(
                          fontSize: 18.0,
                          color: Color(0xffFFFFFF),
                        )),
                    SizedBox(
                      width: 25.0,
                    ),
                  ],
                ),
              ),
              Expanded(
                child: Container(
                  color: Colors.white,
                  height: MediaQuery.of(context).size.height,
                  width: MediaQuery.of(context).size.width,
                  padding: EdgeInsets.all(30.0),
                  child: isLoading
                      ? Center(
                          child: CircularProgressIndicator(),
                        )
                      : Column(
                          mainAxisAlignment: MainAxisAlignment.start,
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            SizedBox(
                              height: 20.0,
                            ),
                            Padding(
                              padding: const EdgeInsets.only(left: 5.0),
                              child: Text('UPDATE YOUR LOCATION',
                                  style: TextStyle(
                                    fontSize: 16.0,
                                    color: Color(0xff000000),
                                  )),
                            ),
                            SizedBox(
                              height: 20.0,
                            ),
                            Container(
                              height: 40.0,
                              decoration: BoxDecoration(
                                border: Border.all(
                                    color: Colors.black54, width: 0.0),
                                borderRadius: BorderRadius.circular(10.0),
                              ),
                              child: DropdownButtonHideUnderline(
                                  child: ButtonTheme(
                                      alignedDropdown: true,
                                      child: DropdownButton(
                                        value: _selectedState,
                                        hint: Text("State"),
                                        isExpanded: true,
                                        items: _statesList
                                            .map((String item) =>
                                                DropdownMenuItem<String>(
                                                    child: Text(item),
                                                    value: item))
                                            .toList(),
                                        onChanged: (String Value) {
                                          if (mounted)
                                            setState(() {
                                              _selectedState = Value;

                                              int index = _locationModel.data
                                                  .indexWhere((element) =>
                                                      element.state ==
                                                      _selectedState);

                                              _locationsList = _locationModel
                                                  .data[index].locations;
                                              _selectedLocation =
                                                  _locationsList[0];
                                            });
                                        },
                                        style: Theme.of(context)
                                            .textTheme
                                            .bodyText2,
                                      ))),
                            ),
                            SizedBox(
                              height: 20.0,
                            ),
                            Container(
                              height: 40.0,
                              decoration: BoxDecoration(
                                border: Border.all(
                                    color: Colors.black54, width: 0.0),
                                borderRadius: BorderRadius.circular(10.0),
                              ),
                              child: DropdownButtonHideUnderline(
                                  child: ButtonTheme(
                                      alignedDropdown: true,
                                      child: DropdownButton(
                                        value: _selectedLocation,
                                        hint: Text("Location"),
                                        isExpanded: true,
                                        items: _locationsList.map((item) {
                                          return DropdownMenuItem(
                                            child: Text(item.name),
                                            value: item,
                                          );
                                        }).toList(),
                                        onChanged: (Value) {
                                          if (mounted) print(Value);
                                          setState(() {
                                            _selectedLocation = Value;
                                            print(
                                                "${_selectedLocation.name} ${_selectedLocation.id} ${_selectedLocation.city}");
                                          });
                                        },
                                        style: Theme.of(context)
                                            .textTheme
                                            .bodyText2,
                                      ))),
                            )
                          ],
                        ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: LocationUpdate(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}
answered on Stack Overflow Aug 19, 2020 by chunhunghan

User contributions licensed under CC BY-SA 3.0