menu-bar

Thursday, March 9, 2017

Chained dropdown dengan PHP laravel MySql dan AJAX Jquery

Pada kesempatan kali ini admin hendak membagikan pengalamannya bagaimana membuat dropdown yang saling terhubung satu sama lain atau istilahnya chained dropdown. Admin mengambil sample Country-State-City dropdown karena memang dropdown model ini banyak dipakai saat pembuatan aplikasi berbasis web.

Masih sama dengan artikel sebelumnya kita menggunaka Laravel sebagai back end side, MySql sebagai database Country-State-City yang akan di generate dan juga kali ini kita akan memakai fungsi AJAX Jquery getJSON. Tentu saja peranan getJSON disini menjadi sangat penting, karena dengan menggunakan fungsi ini respone yang dikirimkan oleh server terjadi secara real time tanpa men-refresh browser, tanpa jeda waktu membuat aplikasi yang kita buat terlihat dinamis dan lebih user friendly. Oke langsung kita mulai saja!

Pertama siapkan databasenya, untuk gampangnya bisa download projectnya DISINI. Databasenya saya taruh di folder database tinggal di import saja di phpmyadmin PC agan. Setelah database di import, kita siapkan modelnya. 

Berikut ini model yang harus disiapkan, csc_countries.php:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class csc_countries extends Model
{
    
protected $table='csc_countries';
    protected $fillable=[
        'name',
        'sortname',
        'phonecode'
    ];

}

csc_states.php:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class csc_states extends Model
{
    
protected $table='csc_states';
    protected $fillable=[
        'name',
        'country_id'
    ];


}

csc_cities.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class csc_cities extends Model
{
    
protected $table='csc_cities';
    protected $fillable=[
        'name',
        'state_id'
    ];

}

Berikutnya kita siapkan controllernya, csccontroller.php:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests;
use Response;
use App\csc_cities;
use App\csc_states;
use App\csc_countries;

class csccontroller extends Controller
{
    
  public function chained_dopdown(){
    $csc_countrie=csc_countries::all();

    return view('chained-dropdown')->with('csc_countrie',$csc_countrie);
  }

public function getStates($param){
      //GET THE ACCOUNT BASED ON TYPE
      $csc_state = csc_states::where('country_id','=',$param)->get();
      //CREATE AN ARRAY 
      $options = array();      
      foreach ($csc_state as $arrayForEach) {
                $options += array($arrayForEach->id => $arrayForEach->name);                
            }
      
      return Response::json($options);

    }

    public function getCities($param){
      //GET THE ACCOUNT BASED ON TYPE
      $csc_citie = csc_cities::where('state_id','=',$param)->get();
      //CREATE AN ARRAY 
      $options = array();      
      foreach ($csc_citie as $arrayForEach) {
                $options += array($arrayForEach->id => $arrayForEach->name);                
            }
      
      return Response::json($options);

    }


}

Lalu siapkan juga router yang akan menghubungkan request dari client ke server. Route.php:

Route::get('/chained_dopdown','csccontroller@chained_dopdown');
Route::get('/chained_dopdown/getStates/{param}','csccontroller@getStates');
Route::get('/chained_dopdown/getCities/{param}','csccontroller@getCities');

Selanjutnya kita siapkan file javascript untuk men-generate dropdown secara dinamis. csc.js:

$(document).ready(function(){

    var host = window.location.href;    

$("#country").change(function() {

            $.getJSON(host + "/getStates/" + $("#country option:selected").val(), function(data) {
            //console.log(data);            
                var temp = [];
                //CONVERT INTO ARRAY
                $.each(data, function(key, value) {
                    temp.push({v:value, k: key});
                });
                //SORT THE ARRAY
                temp.sort(function(a,b){
                   if(a.v > b.v){ return 1}
                    if(a.v < b.v){ return -1}
                      return 0;
                });
                //APPEND INTO SELECT BOX
                $('#state').empty();
                $('#state').append('<option>Select State/Province</option>');
                $('#city').empty();
                $('#city').append('<option>NA</option>');
                $.each(temp, function(key, obj) {
                    $('#state').append('<option value="' + obj.k +'">' + obj.v + '</option>');
                });
            });                
            
        });

        $("#state").change(function() {

            $.getJSON(host + "/getCities/" + $("#state option:selected").val(), function(data) {
                //console.log(data);
                var temp = [];
                //CONVERT INTO ARRAY
                $.each(data, function(key, value) {
                    temp.push({v:value, k: key});
                });
                //SORT THE ARRAY
                temp.sort(function(a,b){
                   if(a.v > b.v){ return 1}
                    if(a.v < b.v){ return -1}
                      return 0;
                });
                //APPEND INTO SELECT BOX
                $('#city').empty();
                $.each(temp, function(key, obj) {
                    $('#city').append('<option value="' + obj.k +'">' + obj.v + '</option>');           
                });            
            });
            
        }); 

});//end of document ready

Terakhir kita siapkan view-nya. chained-dropdown.blade.php:

@extends('layouts.app')
@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-10 col-md-offset-1">
            <div class="panel panel-default">
                <div class="panel-heading">Chained Dropdown</div>

                <div class="panel-body">                            
                    <label>Country</label>
                        <select name="state_province" id="country">
                            <option value="">Select Country</option>
                            @foreach($csc_countrie as $csc_countries)
                                <option value="{{$csc_countries->id}}">{{$csc_countries->name}}</option>
                            @endforeach
                        </select>
                    <br>

                    <label>State</label>
                        <select name="state_province" id="state">
                            <option value="">NA</option>
                        </select>
                    <br>

                    <label>City</label>
                        <select name="city" id="city">
                            <option value="">NA</option>
                        </select>
                </div>
            </div>
        </div>
    </div>
</div>
<script type="text/javascript" src='{{URL::asset("js/jquery-1.12.4.min.js")}}'></script>
<script type="text/javascript" src='{{URL::asset("js/csc.js")}}'></script>
@endsection

Dan persiapan kitapun selesai. Penjelasan singkatnya kurang lebih begini. Table country, state dan city saling terhubung satu sama lain atau memiliki relasi, dimana table country dan table state dihubungkan oleh kolom id(pada table country) dan kolom country_id(pada table state), begitu juga dengan table state dan city, id(pada table state) dan kolom state_id(pada table city). 

Jadi, saat user memilih nama country, maka id nya akan dikirm kan ke controller dan dicocokan ke database (melalui model) sehingga controller akan mencocokan id country mana yang dimaksud oleh user pada table state barulah setelahnya respone dikembalikan ke user.

public function getStates($param){
      //GET THE ACCOUNT BASED ON TYPE
      $csc_state = csc_states::where('country_id','=',$param)->get();
      //CREATE AN ARRAY 
      $options = array();      
      foreach ($csc_state as $arrayForEach) {
                $options += array($arrayForEach->id => $arrayForEach->name);                
            }
      
      return Response::json($options);

Nah magic-nya terjadi disini. Respone diterima oleh getJSON (pada file csc.js) dan di tampilkan pada view.

$("#country").change(function() {

            $.getJSON(host + "/getStates/" + $("#country option:selected").val(), function(data) {
             //console.log(data);            
                var temp = [];
                //CONVERT INTO ARRAY
                $.each(data, function(key, value) {
                    temp.push({v:value, k: key});
                });
                //SORT THE ARRAY
                temp.sort(function(a,b){
                   if(a.v > b.v){ return 1}
                    if(a.v < b.v){ return -1}
                      return 0;
                });
                //APPEND INTO SELECT BOX
                $('#state').empty();
                $('#state').append('<option>Select State/Province</option>');
                $('#city').empty();
                $('#city').append('<option>NA</option>');
                $.each(temp, function(key, obj) {
                    $('#state').append('<option value="' + obj.k +'">' + obj.v + '</option>');
                });
            });                
            
        });

Begitu juga mekanisme yang terjadi pada state dan city, id pada state yang dipilih dicocokan dengan table city dan barulah responenya dikembalikan ke user.

public function getCities($param){
      //GET THE ACCOUNT BASED ON TYPE
      $csc_citie = csc_cities::where('state_id','=',$param)->get();
      //CREATE AN ARRAY 
      $options = array();      
      foreach ($csc_citie as $arrayForEach) {
                $options += array($arrayForEach->id => $arrayForEach->name);                
            }
      
      return Response::json($options);

    }

$("#state").change(function() {

            $.getJSON(host + "/getCities/" + $("#state option:selected").val(), function(data) {
                //console.log(data);
                var temp = [];
                //CONVERT INTO ARRAY
                $.each(data, function(key, value) {
                    temp.push({v:value, k: key});
                });
                //SORT THE ARRAY
                temp.sort(function(a,b){
                   if(a.v > b.v){ return 1}
                    if(a.v < b.v){ return -1}
                      return 0;
                });
                //APPEND INTO SELECT BOX
                $('#city').empty();
                $.each(temp, function(key, obj) {
                    $('#city').append('<option value="' + obj.k +'">' + obj.v + '</option>');           
                });            
            });
            
        });

Nah selesai sudah permbahasan kita kali ini, semoga bermanfaat dan mohon maaf kalau ada penjelasan yang kurang dapat dimengerti, pun kalau ada koreksi perhal penjelasan saya boleh di cantumkan dalam kolom komentar. Terima Kasih

7 comments:

  1. Gan, link databasenya not found tuh

    ReplyDelete
    Replies
    1. Thx infonya gan, nanti saya coba cek lagi yaa..

      Delete
  2. gan, kok hasil json nya cuma 1 data yah?

    ReplyDelete
  3. gan, kok hasil json nya cuma 1 data yah?

    ReplyDelete
    Replies
    1. Hai gan, cuma satu data gimana ya gan? Coba aja di debug dulu ke console.log gan response nya

      Delete
  4. Mantabs, setelah saya coba berhasil. Namun untuk laravel 5.6, respon dari controller sintaksnya menjadi :

    response()->json($var);

    dan untuk menerimanya, di script java script saya hilangkan variabel host. Terima Kasih tutorialnya, semoga barokah ilmunya.

    ReplyDelete