การใช้งาน DepDrop (Dependent Dropdownlist) สำหรับเลือก ภาค จังหวัด อำเภอ และตำบล

คู่มือการเรียนรู้ Yii Framework 2 (Yii2)

บทเรียนดีๆ สำหรับผู้ที่ต้องการแบ่งปัน บทเรียนของคุณอาจมีค่าสำหรับอีกหลายๆ คน

beta version

การใช้งาน DepDrop (Dependent Dropdownlist) สำหรับเลือก ภาค จังหวัด อำเภอ และตำบล

มานพ กองอุ่น dependent dropdownlist จังหวัด อำเภอ ตำบล ภาค 1,380

ในบทเรียนรู้นี้มาทำความรู้จักและใช้งาน Dropdownlist แบบ Dependent โดย dependent dropdownlist เป็น dropdownlist ที่มีความเชื่อมโยงกัน ตัวอย่างเช่น เลือกจังหวัด จะปรากฏรายการอำเภอในจังหวัดนั้น เมื่อเลือกอำเภอก็จะปรากฏตำบลในอำเภอนั้น เป็นต้น และเราจะทำการเก็บข้อมูลตัวเลือกสุดท้ายลงในฐานข้อมูล หรือนำไปประมวลผลข้อมูลต่อไป

สำหรับบทเรียนรู้นี้จะใช้ Package ทีมีชื่อว่า DepDrop ของ Kartik ในการใช้งานโดยสามารถติดตั้งผ่านโปรแกรม Composer ได้โดยใช้คำสั่ง

composer require kartik-v/yii2-widget-depdrop

สามารถดูรายละเอียดเพิ่มเติมได้ที่

https://github.com/kartik-v/yii2-widget-depdrop
http://demos.krajee.com/widget-details/depdrop

File SQL ภาค จังหวัด อำเภอ และตำบล

ก่อนอื่นก็ดาวน์โหลด file sql ภาค จังหวัด อำเภอ และตำบลไป import ลงฐานข้อมูลกันก่อนนะครับ

http://programmerthailand.com/uploads/dep_drop.sql

Generate Model

ทำการ Generate Model ด้วย Gii ครับในที่นี้จะนำไปเก็บไว้ที่ common/models ซึ่งมีรายละเอียดดังต่อไปนี้

common/models/Region.php

<?php

namespace common\models;

use Yii;

/**
 * This is the model class for table "region".
 *
 * @property integer $id
 * @property string $name
 *
 * @property Province[] $provinces
 */
class Region extends \yii\db\ActiveRecord
{
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'region';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['id', 'name'], 'required'],
            [['id'], 'integer'],
            [['name'], 'string', 'max' => 255],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'name' => 'ภาค',
        ];
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getProvinces()
    {
        return $this->hasMany(Province::className(), ['region_id' => 'id']);
    }
}

common/models/Province.php

<?php

namespace common\models;

use Yii;

/**
 * This is the model class for table "province".
 *
 * @property integer $id
 * @property string $code
 * @property string $name
 * @property integer $region_id
 *
 * @property District[] $districts
 * @property Region $region
 */
class Province extends \yii\db\ActiveRecord
{
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'province';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['id', 'code', 'name'], 'required'],
            [['id', 'region_id'], 'integer'],
            [['code'], 'string', 'max' => 2],
            [['name'], 'string', 'max' => 150],
            [['region_id'], 'exist', 'skipOnError' => true, 'targetClass' => Region::className(), 'targetAttribute' => ['region_id' => 'id']],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'code' => 'รหัสจังหวัด',
            'name' => 'จังหวัด',
            'region_id' => 'ภาค',
        ];
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getDistricts()
    {
        return $this->hasMany(District::className(), ['province_id' => 'id']);
    }


    /**
     * @return \yii\db\ActiveQuery
     */
    public function getRegion()
    {
        return $this->hasOne(Region::className(), ['id' => 'region_id']);
    }


}

common/models/District.php

<?php

namespace common\models;

use Yii;

/**
 * This is the model class for table "district".
 *
 * @property integer $id
 * @property string $code
 * @property string $name
 * @property integer $province_id
 *
 * @property Province $province
 * @property Subdistrict[] $subdistricts
 */
class District extends \yii\db\ActiveRecord
{
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'district';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['id', 'code', 'name'], 'required'],
            [['id', 'province_id'], 'integer'],
            [['code'], 'string', 'max' => 4],
            [['name'], 'string', 'max' => 150],
            [['province_id'], 'exist', 'skipOnError' => true, 'targetClass' => Province::className(), 'targetAttribute' => ['province_id' => 'id']],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'code' => 'รหัสอำเภอ',
            'name' => 'อำเภอ',
            'province_id' => 'จังหวัด',
        ];
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getProvince()
    {
        return $this->hasOne(Province::className(), ['id' => 'province_id']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getSubdistricts()
    {
        return $this->hasMany(Subdistrict::className(), ['district_id' => 'id']);
    }
}

common/models/Subdistrict.php

<?php

namespace common\models;

use Yii;

/**
 * This is the model class for table "subdistrict".
 *
 * @property integer $id
 * @property string $code
 * @property string $name
 * @property integer $district_id
 *
 * @property District $district
 */
class Subdistrict extends \yii\db\ActiveRecord
{
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'subdistrict';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['id', 'code', 'name'], 'required'],
            [['id', 'district_id'], 'integer'],
            [['code'], 'string', 'max' => 6],
            [['name'], 'string', 'max' => 150],
            [['district_id'], 'exist', 'skipOnError' => true, 'targetClass' => District::className(), 'targetAttribute' => ['district_id' => 'id']],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'code' => 'รหัสตำบล',
            'name' => 'ตำบล',
            'district_id' => 'อำเภอ',
        ];
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getDistrict()
    {
        return $this->hasOne(District::className(), ['id' => 'district_id']);
    }
}

 

สร้าง Model สำหรับค้นหาข้อมูล

ทำการสร้าง model สำหรับการค้นหาข้อมูล เพื่อรับข้อมูลที่เลือก ภาค จังหวัด อำเภอ และตำบล ก่อนนำข้อมูลไปใช้งานต่อไป โดยสร้างไว้ที่ common/models/MyDepDrop.php

<?php


namespace common\models;


use yii\base\Model;

class MyDepDrop extends Model
{
    public $region_id;
    public $province_id;
    public $district_id;
    public $subdistrict_id;

    public function rules()
    {
        return [['region_id', 'province_id', 'district_id', 'subdistrict_id'], 'required'];
    }

    public function attributeLabels()
    {
        return [
            'region_id' => 'ภาค',
            'province_id' => 'จังหวัด',
            'district_id' => 'อำเภอ',
            'subdistrict_id' => 'ตำบล'
        ];
    }
}

สร้าง Controller 

ทำการสร้าง Controller เพื่อทดสอบการทำงาน หรือหากเข้าใจหลักการทำงานแล้วสามารถนำไปประยุกต์ใช้ได้เลยครับ

frontend/controllers/DepDropController.php

<?php


namespace frontend\controllers;


use common\models\District;
use common\models\MyDepDrop;
use common\models\Province;
use common\models\Subdistrict;
use Yii;
use yii\helpers\Json;
use yii\web\Controller;

class DepDropController extends Controller
{
    public function actionIndex()
    {
        $model = new MyDepDrop();

        if($model->load(Yii::$app->request->post())){
            var_dump($model);
        }

        return $this->render('index', [
            'model' => $model
        ]);
    }

    public function actionProvinceList() {
        $out = [];
        if (isset($_POST['depdrop_parents'])) {
            $parents = $_POST['depdrop_parents'];
            if ($parents != null) {
                $region_id = $parents[0];
                foreach(Province::find()->where(['region_id' => $region_id])->orderBy(['name' => SORT_ASC])->all() as $province){
                    $out[] = ['id' => $province->id, 'name' => $province->name];
                }

                echo Json::encode(['output'=>$out, 'selected'=>'']);
                return;
            }
        }
        echo Json::encode(['output'=>'', 'selected'=>'']);
    }

    public function actionDistrictList() {
        $out = [];
        if (isset($_POST['depdrop_parents'])) {
            $parents = $_POST['depdrop_parents'];
            if ($parents != null) {
                $province_id = $parents[0];
                foreach(District::find()->where(['province_id' => $province_id])->orderBy(['name' => SORT_ASC])->all() as $district){
                    $out[] = ['id' => $district->id, 'name' => $district->name];
                }

                echo Json::encode(['output'=>$out, 'selected'=>'']);
                return;
            }
        }
        echo Json::encode(['output'=>'', 'selected'=>'']);
    }

    public function actionSubdistrictList() {
        $out = [];
        if (isset($_POST['depdrop_parents'])) {
            $parents = $_POST['depdrop_parents'];
            if ($parents != null) {
                $subdistrict_id = $parents[0];
                foreach(Subdistrict::find()->where(['district_id' => $subdistrict_id])->orderBy(['name' => SORT_ASC])->all() as $subdistrict){
                    $out[] = ['id' => $subdistrict->id, 'name' => $subdistrict->name];
                }

                echo Json::encode(['output'=>$out, 'selected'=>'']);
                return;
            }
        }
        echo Json::encode(['output'=>'', 'selected'=>'']);
    }
}

สร้าง View

ทำการสร้าง view ใน frontend/views/dep-drop/index.php 

<?php
use common\models\Region;
use kartik\depdrop\DepDrop;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\helpers\Url;
use yii\widgets\ActiveForm;

$this->title = 'ภาค จังหวัด อำเภอ และตำบล';
?>
<h1><?=$this->title?></h1>
<?php $form = ActiveForm::begin()?>
<?=$form->field($model, 'region_id')->dropDownList(ArrayHelper::map(Region::find()->all(), 'id', 'name'), ['prompt' => 'เลือกภาค'])?>
<?=$form->field($model, 'province_id')->widget(DepDrop::className(), [
    'pluginOptions' => [
        'depends' => [Html::getInputId($model, 'region_id')],
        'placeholder' => 'เลือกจังหวัด',
        'url' => Url::to(['province-list'])
    ]
])?>
<?=$form->field($model, 'district_id')->widget(DepDrop::className(), [
    'pluginOptions' => [
        'depends' => [Html::getInputId($model, 'province_id')],
        'placeholder' => 'เลือกอำเภอ',
        'url' => Url::to(['district-list'])
    ]
])?>
<?=$form->field($model, 'subdistrict_id')->widget(DepDrop::className(), [
    'pluginOptions' => [
        'depends' => [Html::getInputId($model, 'district_id')],
        'placeholder' => 'เลือกตำบล',
        'url' => Url::to(['subdistrict-list'])
    ]
])?>

<?= Html::submitButton('ส่งข้อมูล', ['class' => 'btn btn-success'])?>
<?php ActiveForm::end()?>

เมื่อเลือกภาค จังหวัด อำเภอ และตำบลแล้วจะสามารถส่งข้อมูล และแสดงผลข้อมูลผ่าน var_dump($model) ดังนี้

D:\wamp64\www\yii2-survey\frontend\controllers\DepDropController.php:22:
object(common\models\MyDepDrop)[61]
  public 'region_id' => string '3' (length=1)
  public 'province_id' => string '23' (length=2)
  public 'district_id' => string '325' (length=3)
  public 'subdistrict_id' => string '2951' (length=4)
  private '_errors' (yii\base\Model) => null
  private '_validators' (yii\base\Model) => 
    object(ArrayObject)[62]
      private 'storage' => 
        array (size=1)
          0 => 
            object(yii\validators\RequiredValidator)[65]
              ...
  private '_scenario' (yii\base\Model) => string 'default' (length=7)
  private '_events' (yii\base\Component) => 
    array (size=0)
      empty
  private '_behaviors' (yii\base\Component) => 
    array (size=0)
      empty

จะเห็นว่าเราสามารถเรียกใช้งาน object ได้เรียบร้อยแล้ว โดยข้อมูลที่จะนำไปใช้คือ

  public 'region_id' => string '3' (length=1)
  public 'province_id' => string '23' (length=2)
  public 'district_id' => string '325' (length=3)
  public 'subdistrict_id' => string '2951' (length=4)

 


หากบทเรียนรู้มีความผิดพลาดประการใด หรือมีข้อเสนอแนะกรุณาแจ้ง contact@programmerthailand.com
มานพ กองอุ่น

มานพ กองอุ่น
admin

  • 2 เพื่อน
  • 9 ผู้ติดตาม
  • 758 โพสต์