Posted in API Dart Flutter PHP & MySQL

Flutter – How to make Drop Down and insert options by PHP MySQL

Flutter – How to make Drop Down and insert options by PHP MySQL Posted on May 21, 2020Leave a comment
I'm Hari Prasad Chaudhary from Nepal, developer of the finest educational website/app "MeroSpark" and the finest eCommerce system "PasalaY". Here I share the code snippet which I learn during development.

In this example, we have a list of countries in DropDownButton(), and whenever a user chooses one country from that list, the list of the city gets updated automatically by fetching JSON data from the server. PHP and MySQL database are used at the back end to generate JSON data. We will communicate with the server using REST API. DropdownMenuItem() is used to make options inside Drop Down.

dropdown with options

At our back end, PHP and MySQL is used. The database table is like below:

table: city_list

PHP code to generate JSON data: test/city_list.php

<?php 
  $db = "test_db";
  $host = "localhost";
  $db_user = 'root';
  $db_password = 'root';
  //MySql server and database info

  $link = mysqli_connect($host, $db_user, $db_password, $db);
  //connecting to database

  if(isset($_REQUEST["country"])){
      $country = $_REQUEST["country"];
  }else{
      $country = "";
  } //if there is country parameter then grab it

  $json["error"] = false;
  $json["errmsg"] = "";
  $json["data"] = array();

  $country = mysqli_real_escape_string($link, $country);
  //remove the conflict of inverted comma with SQL query. 

  $sql = "SELECT * FROM city_list WHERE LCASE(country_name) = LCASE('$country') ORDER BY city_name ASC";
  $res = mysqli_query($link, $sql);
  $numrows = mysqli_num_rows($res);
  if($numrows > 0){
     //check if there is any data
      while($array = mysqli_fetch_assoc($res)){
           array_push($json["data"], $array);
      }
  }else{
      $json["error"] = true;
      $json["errmsg"] = "No any data to show.";
  }

  mysqli_close($link);

  header('Content-Type: application/json');
  // tell browser that its a json data
  echo json_encode($json);

?>

Output JSON by city_list.php

{
   "error":false,
   "errmsg":"",
   "data":[
      {
         "city_id":"1",
         "country_name":"Nepal",
         "city_name":"Kathamandu"
      },
      {
         "city_id":"6",
         "country_name":"Nepal",
         "city_name":"Lumbini"
      },
      {
         "city_id":"5",
         "country_name":"Nepal",
         "city_name":"Pokhara"
      }
   ]
}

Now in the flutter part, add http Flutter package in your dependency by adding the following line in pubspec.yaml file.

dependencies:
  flutter:
    sdk: flutter
  http: ^0.12.1

Add Internet Permission by adding this line in android/app/src/main/AndroidManifest.xml before <application>

<uses-permission android:name="android.permission.INTERNET"/>

Dart Code, see explanation in comments to understand the code.

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:http/http.dart' as http;
//import http package manually

class MyDropDown extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return _MyDropDown();
  }
}

class _MyDropDown extends State<MyDropDown>{

  String countryname, message;
  bool error;
  var data;

  List<String> countries = ["Nepal", "India", "USA"];
  //we make list of strings with the name of countries

  String dataurl = "http://192.168.0.112/test/city_list.php";
  // do not use http://localhost/ for your local machine, Android emulation do not recognize localhost
  // insted use your local ip address or your live URL, 
  // hit "ipconfig" on Windows or "ip a" on Linux to get IP Address

  @override
  void initState() {
    error = false;
    message = "";
    countryname = "Nepal"; //default country
    super.initState();
  }

  Future<void> getCity() async {
        var res = await http.post(dataurl + "?country=" + Uri.encodeComponent(countryname));
        //attache countryname on parameter country in url
        if (res.statusCode == 200) {
            setState(() {
                 data = json.decode(res.body);
                 if(data["error"]){
                     //check fi there is any error from server.
                     error = true;
                     message = data["errmsg"];
                 }
            });
        }else{
           //there is error
           setState(() {
               error = true;
               message = "Error during fetching data";
           });
        }
  }

  @override
  Widget build(BuildContext context) {
        return Scaffold(
             appBar: AppBar(title:Text("City List"), backgroundColor: Colors.redAccent,),
             body:Container( 
                 padding:EdgeInsets.all(30),
                 child: Column(
                    children:<Widget>[
    
                     Container( //wrapper for Country list
                            child:DropdownButton(
                                isExpanded: true,
                                value: countryname,
                                hint: Text("Select Country"),
                                items: countries.map((countryone){
                                  return DropdownMenuItem(
                                    child: Text(countryone), //label of item
                                    value: countryone, //value of item
                                  );
                                 }).toList(), 
                                 onChanged: (value){
                                     countryname = value; //change the country name
                                     getCity(); //get city list.
                                 },
                            ),
                          
                     ),

                     Container( //wrapper for City list
                         margin: EdgeInsets.only(top:30),
                         child:error?Text(message):
                               data == null?
                               Text("Choose Country"):
                               cityList(),
                               //if there is error then show error message,
                               //else check if data is null,
                               //if not then show city list,
                               
                     )
                ]
             ),
         )
    );
  }

  Widget cityList(){ //widget function for city list
      List<CityOne> citylist = List<CityOne>.from(
         data["data"].map((i){
                         return CityOne.fromJSON(i);
         })
      ); //searilize citylist json data to object model.

      return DropdownButton(
                hint: Text("Select City"),
                isExpanded: true,
                items: citylist.map((cityOne){
                   return DropdownMenuItem(
                        child: Text(cityOne.cityname),
                        value: cityOne.cityname,
                     );
                }).toList(),
                onChanged: (value){ 
                  print("Selected city is $value");
                }
            );
  }
}

//model class to searilize country list JSON data.
class CityOne{
  String id, countryname, cityname;
  CityOne({this.id, this.countryname, this.cityname});

  factory CityOne.fromJSON(Map<String, dynamic> json){
     return CityOne(
       id:json["city_id"],
       countryname: json["country_name"],
       cityname: json["city_name"]
     );
  }
}

In this way, you can make Drop Down and insert options inside it from PHP and MySQL database.

I'm Hari Prasad Chaudhary from Nepal, developer of the finest educational website/app "MeroSpark" and the finest eCommerce system "PasalaY". Here I share the code snippet which I learn during development.

Leave a Reply

Your email address will not be published. Required fields are marked *