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

wave
มานพ กองอุ่น 11 เม.ย. 2017 05:05:28 16,849

ในบทเรียนรู้นี้มาทำความรู้จักและใช้งาน 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

เขียนบทเรียนรู้ของคุณ

รายละเอียด
ข้อมูลผู้เขียน
มานพ กองอุ่น

มานพ กองอุ่น

เป็นสมาชิกเมื่อ: 18 ธ.ค. 2009

เนื้อหาที่เกี่ยวข้อง