บทความนี้เป็นการสอนการทำ Dropdown 3 ชั้น โดยใช้เทคนิค Ajax ในการช่วยเพื่อให้หน้าเว็บไปต้องรีเฟส โดยขั้นตอนการทำงานเริ่มจากเลือกจังหวัด เมื่อเลือกจังหวัดแล้ว Dropdown ชั้นที่ 2 จะมีรายชื่ออำเภอของจังหวัดที่เลือกเท่านั้น หลังจากนั้นเมื่อเราเลือกอำเภอ Dropdown ชั้นที่ 3 จะมีรายชื่อตำบลของอำเภอที่เราเลือก จะเห็นได้ว่าทั้งหมดนี้เราใช้ ภาษา PHP + MySQL (เทคนิค Ajax) เท่านั้น ซึ่งทางผู้เขียนจะอธิบายขั้นตอนของ code เพื่อให้ผู้อ่านเข้าใจได้ง่ายขึ้น
เดโม่ตัวอย่าง
เครื่องมือพัฒนา
1. XAMPP สำหรับจำลองเครื่องเราเป็น SERVER ให้ใช้เวอร์ชั่นล่าสุด (ที่ใช้ php 7 ขึ้นไป)
2. VSCODE ใช้ในการเขียนโปรแกรม
ขั้นตอน
1. ดาวน์โหลดฐานข้อมูลมาก่อน สามารถดาวน์โหลดได้ที่ Click to Download อ้างอิงจาก https://github.com/parsilver/thailand-provinces
2. หลังจากนั้นทำการสร้าง database ชื่อ thailand แล้วทำการ Import SQL โดยใช้ PHPMyAdmin
3 สร้างโปรเจค multiple_dropdown ไว้ใน c:\xampp\htdocs\
4. สร้างไฟล์ connect.php เพื่อเชื่อมต่อฐานข้อมูล code ตัวอย่างด้านล่าง
1 2 3 4 5 6 7 8 9 |
<?php $info = array( 'host' => 'localhost', 'user' => 'root', 'password' => '', 'dbname' => 'thailand' ); $conn = mysqli_connect($info['host'], $info['user'], $info['password'], $info['dbname']) or die('Error connection database!'); mysqli_set_charset($conn, 'utf8'); |
5. สร้างไฟล์ index.php เพื่อสร้าง html และทำ multiple dropdown ดู code ตัวอย่างด้านล่าง
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
<?php include('connect.php'); $sql = "SELECT * FROM provinces"; $query = mysqli_query($conn, $sql); ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Multiple Dropdown - itoffside.com</title> <link href="assets/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container my-5"> <div class="card"> <div class="card-body"> <h3>การทำ Multiple Dropdown ด้วย Ajax เลือก 3 ขั้น</h3> <form> <div class="form-row"> <div class="form-group col-md-4"> <label for="province">จังหวัด</label> <select name="province_id" id="province" class="form-control"> <option value="">เลือกจังหวัด</option> <?php while($result = mysqli_fetch_assoc($query)): ?> <option value="<?=$result['id']?>"><?=$result['name_th']?></option> <?php endwhile; ?> </select> </div> <div class="form-group col-md-4"> <label for="amphure">อำเภอ</label> <select name="amphure_id" id="amphure" class="form-control"> <option value="">เลือกอำเภอ</option> </select> </div> <div class="form-group col-md-4"> <label for="district">ตำบล</label> <select name="district_id" id="district" class="form-control"> <option value="">เลือกตำบล</option> </select> </div> </div> </form> </div> </div> </div> <script src="assets/jquery.min.js"></script> <script src="assets/script.js"></script> </body> </html> <?php mysqli_close($conn); |
คำอธิบาย Code
บรรทัด 1-5 เป็นการเชื่อต่อฐานข้อมูลและดึงข้อมูลจังหวัดมา (province)
บรรทัด 22-31 เป็นการนำข้อมูลจังหวัดที่ได้ จากบรรทัด 1-5 มาแสดงในหน้าจอ
บรรทัด 32-43 เป็นการใส่ dropdown อำเภอ, ตำบล แต่ยังไม่มีข้อมูล จนกว่า เราจะเลือกจังหวัด ซึ่งเราจะนำ javascript มาจับ Event หน้าจอ เพื่อเรียกใช้งาน ajax แล้วนำข้อมูล อำเภอ, ตำบล มาใส่ตามลำดับ
บรรทัด 51 เป็นการเรียกใช้ไฟล์ script.js โดย file นี้มีความสำคัญในการ จัดการ AJAX
6. สร้างไฟล์ script.js ไว้ที่โฟล์เดอร์ assets เพื่อใช้สำหรับ เวลาเราเปลี่ยนแปลง จังหวัดหรืออำเภอ ให้ทำการ ดึงข้อมูล มาใหม่
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
$(function(){ var provinceObject = $('#province'); var amphureObject = $('#amphure'); var districtObject = $('#district'); // on change province provinceObject.on('change', function(){ var provinceId = $(this).val(); amphureObject.html('<option value="">เลือกอำเภอ</option>'); districtObject.html('<option value="">เลือกตำบล</option>'); $.get('get_amphure.php?province_id=' + provinceId, function(data){ var result = JSON.parse(data); $.each(result, function(index, item){ amphureObject.append( $('<option></option>').val(item.id).html(item.name_th) ); }); }); }); // on change amphure amphureObject.on('change', function(){ var amphureId = $(this).val(); districtObject.html('<option value="">เลือกตำบล</option>'); $.get('get_district.php?amphure_id=' + amphureId, function(data){ var result = JSON.parse(data); $.each(result, function(index, item){ districtObject.append( $('<option></option>').val(item.id).html(item.name_th) ); }); }); }); }); |
อธิบาย Code
บรรทัด 2-4 สร้างตัวแปรเพื่อเก็บ Element Selector ของ Dropdown จังหวัด, อำเภอ, ตำบล
บรรทัด 7-21
– เมื่อมีการเปลี่ยนแปลง Dropdown (เลือกจังหวัด) จะทำการ Clear ข้อมูล อำเภอ, ตำบล ตามบรรทัด 10-11
– หลังจากนั้น จะทำการใช้ GET ของ jQuery ยิง Request ไปที่ get_amphure.php เพื่อดึงข้อมูลอำเภอมา โดยใส่ข้อมูลตัวแปร จังหวัดที่เลือกไปด้วยเพื่อดึงอำเภอเฉพาะจังหวัดที่เลือกเท่านั้น ตัวแปรชื่อ provicne_id ตามบรรทัดที่ 13
– หลังจากยิง Request ไปที่ server แล้ว Server จะตอบกลับมาเป็นข้อมูลรายการของอำเภอจากจังหวัดที่เลือกใน Dropdown รูปแบบของการตอบกลับเป็น JSON ดังนั้นเราต้องทำการ parse data ก่อน ตามบรรทัด 14
– เมื่อ parse data แล้วข้อมูลจะอยู่ในรูปแบบนี้
1 2 3 4 5 6 7 8 9 |
[ { "id":1, "name_th": "ห้างฉัตร", "province_id": 324 }, {}, ... ] |
– ให้เราใช้คำสั่ง jQuery Append ข้อมูลลงใน HTML โดยข้อมูลมาเป็น Array ให้ทำการวนข้อมูล โดยใส่ value คือ item.id และ name คือ item.name_th ตามบรรทัด 17
บรรทัด 24-37 เป็นการดึงข้อมูลตำบลของอำเภอที่เราเลือกมาแสดงบน HTML โดย Event จะทำงานเมื่อคลิกเปลี่ยนอำเภอใน Dropdown การทำงานจะคล้ายกับ การเปลี่ยนจังหวัด แต่แตกต่างที่ ไฟล์ที่ดึงข้อมูลต้องเปลี่ยนเป็น get_district.php และ ตัวแปรที่ส่งไปเป็นตัวแปรของอำเภอที่ถูกเลือก และสุดท้าย ตอนได้รับข้อมูลจาก Server มาก็นำมาวนใส่ ใน Dropdown ตำบล ก็เป็นอันจบการทำงาน
7. สร้างไฟล์ get_amphure.php เพื่อดึงข้อมูล อำเภอ จากจังหวัดที่เลือกมา ดู code ตัวอย่างด้านล่าง
1 2 3 4 5 6 7 8 9 10 |
<?php include('connect.php'); $sql = "SELECT * FROM amphures WHERE province_id={$_GET['province_id']}"; $query = mysqli_query($conn, $sql); $json = array(); while($result = mysqli_fetch_assoc($query)) { array_push($json, $result); } echo json_encode($json); |
อธิบาย Code
เมื่อ ไฟล์ script.js request ขอข้อมูลจาก server โดยเรียกใช้ไฟล์ get_amphure.php และส่งตัวแปร province_id มาด้วย เป็นตัวแปร ได้จากการเลือกจังหวัด
บรรทัด 1 เชื่อมต่อฐานข้อมูล
บรรทัด 2-3 ดึงข้อมูลเอารายการอำเภอ จากจังหวัดที่เลือก โดย where province_id
บรรทัด 6-9 ดึงข้อมูลแล้วทำการ วนเก็บข้อมูลอำเภอ ไว้ใน $json ในรูปแบบ Array
บรรทัด 10 ทำการแปลงข้อมูล Array ไปเป็น JSON เพิ่มเตรียมส่งกลับไปให้กลับ Client ที่เรียกใช้(script.js)
8. สร้างไฟล์ get_district.php เพื่อดึงข้อมูล ตำบล จากอำเภอที่เลือกมา ดู code ตัวอย่างด้านล่าง
1 2 3 4 5 6 7 8 9 10 |
<?php include('connect.php'); $sql = "SELECT * FROM districts WHERE amphure_id={$_GET['amphure_id']}"; $query = mysqli_query($conn, $sql); $json = array(); while($result = mysqli_fetch_assoc($query)) { array_push($json, $result); } echo json_encode($json); |
อธิบาย Code
การทำงานคล้ายกับไฟล์ get_amphure.php แตกต่างกันในเรื่องของการดึงข้อมูลคนละตารางเท่านั้น และตัวแปรที่ใช้การ where เป็น amphure_id
ผลลัพท์
ดาวน์โหลด
สามารถดาวน์โหลด Code เต็มๆ หรือ clone code มาดูได้ที่ลิงค์ https://github.com/ipball/multiple_dropdown
สรุป
สำหรับบทความนี้ ผู้เขียนคิดว่า หลายๆคนน่าจะเข้าใจหลักการทำงาน ของ Client – Server มองเห็นภาพการทำงานชัดเจนในทำงานของโปรแกรม ซึ่งในปี 2020 อาจจะหลายๆคนบอกว่า ยังใช้ jQuery อยู่อีกเหรอ ยังใช้ PHP อยู่อีกเหรอ?
จริงๆแล้วไม่ว่าเราจะใช้ภาษาอะไรหรือเทคโนโลยีอะไรก็ตามแต่ เราจงหาสิ่งที่เราถนัดและเหมาะสมกับงาน แต่ไม่ได้หมายความว่าจะให้ทุกคนจะต้องใช้ PHP ตลอด เราก็ควรศึกษาเรียนรู้ภาษา เทคโนโลยีใหม่ด้วย เช่นกัน เหมือนกับผู้เขียนที่ยังต้องเขียน Node.js, ExpressJS, MongoDB, Angular อยู่เลย เราเป็นนักพัฒนา เราก็ต้องศึกษาพัฒนาตัวเองอยู่สม่ำเสมอ
[…] ตอนนี้มีบทความ การทำ listbox/dropdown แบบ 3 ชั้นแล้ว ละเอียดกว่าเดิม คลิกเพื่อดู […]
ลองทำแล้วออกแค่ 2 ชั้น ไม่ทราบว่าติดตรงไหน รบกวนดูให้หน่อยนะคะ
// on change group
sectionObject.on(‘change’, function(){
var sectionId = $(this).val();
groupObject.html(‘เลือกสถาน/ศูนย์/นิคม’);
$.get(‘getgroup.php?secID=’ + sectionId, function(data){
var result = JSON.parse(data);
$.each(result, function(index, item){
sectionObject.append(
$(”).val(item.id).html(item.groupname)
);
});
});
});
});
<?php
include('connDB.php');
$sql = "SELECT * FROM group WHERE secID={$_GET['secID']}";
$query = mysqli_query($conn, $sql);
$json = array();
while($result = mysqli_fetch_assoc($query)) {
array_push($json, $result);
}
echo json_encode($json);
ตอน javascript each ผิดเปล่า? ครับ
ไม่ได้เหมือนกันออกแค่ชั้นเดียวเอง มันฟ้องว่าตรง index ไม่ได้ใช้งาน
ถ้าจะเปลี่ยนค่าที่เก็บเข้าฐานข้อมูลต้องเปลี่ยนตรงไหนครับ เช่นออยากเก็บข้อมูลตำบลเป็นชื่อแทน ID
บทความนี้ ยังไม่ได้สอนเรื่องบันทึกเข้าฐานข้อมูลนะครับ
ถ้าจะนำไปใช้ในกรณี update ต้องเขียนไฟล์ js ใหม่ หรือ เพิ่มโค้ดตรงไหนครับ คือพอกดแก้ไขแล้วค่าเก่าไม่ขึ้นให้ครับ ขอบคุณครับ
จะเขียน ไว้ที่ไฟล์เดิมก็ได้ครับ แต่ต้องสร้าง ไฟล์ php ใหม่นะครับ
มีตัวอย่างโค้ดของส่วนนี้ไหมครับ พอดีลองทำแล้วค่าเก่าไม่ขึ้นครับ
เยี่ยม
ถ้าจะเพิ่มรหัสไปรษณีย์ด้วยทำยังไงครับ
ตามตัวอย่างมันจะทำงานก็ต่อเมื่อมี event onchange เท่านั้น ถ้าจะให้รองรับกรณีมีการบันทึกข้อมุลแล้วดึงข้อมุลมาแก้ไขจะต้องเพิ่มและปรับตรงไหนคะ
กราบขอบพระคุณครับ รอดตายเเล้ววว
ขอโทษนะครับ พอดีลองทำ edit แล้วข้อมูลเดิมไม่ขึ้นต้องแก้ไขส่วนไหนครับ ขอบคุณครับ
ลองดูโค๊ดตัวอย่างนี้นะครับ https://github.com/ipball/multiple_dropdown
ขั้นตอนนี้ลองทำได้แล้วครับแต่ในส่วนของ update ยังมีปัญหาอยู่ครับ
[
{
“id”:1,
“name_th”: “ห้างฉัตร”,
“province_id”: 324 <—————– ค่าที่ส่งมาตรงนี้เปลี่ยนเป็นตัวหนังสือแทนได้ไหมครับผมลองทำแล้วมันไม่ออก ออกเฉพาะตัวเลข ครับ
},
{},
…
]
จะเปลี่ยนก็ต้องเปลี่ยนตรง javascript ด้วยครับ
อยากเพิ่มรหัสไปรษณีด้วยต้องทำไงครับ
(1) เพิ่ม Code ต่อไปนี้ในหน้าหลัก ต่อจากบรรทัด </div> ของ Dropdown เลือกตำบล
<div class=”form-group col-md-4″>
<label for=”zip”>รหัสไปรษณีย์</label>
<select name=”zip_id” id=”zip” class=”form-control”>
<option value=””>เลือกรหัสไปรษณีย์</option>
</select>
</div>
(2) เพิ่ม Code ต่อไปนี้ในไฟล์ script.js ก่อน }); บรรทัดสุดท้าย
// on change district
districtObject.on(‘change’, function() {
var districtId = $(this).val();
zipObject.html(‘<option value=””>เลือกรหัสไปรษณีย์</option>’);
$.get(‘get_zip.php?district_id=’ + districtId, function(data) {
var result = JSON.parse(data);
$.each(result, function(index, item) {
zipObject.append(
$(‘<option></option>’).val(item.id).html(item.zip_code)
);
});
});
});
*สังเกตว่าเมื่อเสร็จสิ้นแล้ว ตอนสุดท้ายจะมี }); 4 บรรทัด จึงจะถูกต้อง
(3) สร้างไฟล์ get_zip.php โดยมี code ดังนี้
<?php
include(‘connect.php’);
$sql = “SELECT * FROM districts WHERE id={$_GET[‘district_id’]}”;
$query = mysqli_query($conn, $sql);
$json = array();
while($result = mysqli_fetch_assoc($query)) {
array_push($json, $result);
}
echo json_encode($json);
ผลลัพธ์จะทำให้เราได้ช่อง “เลือกรหัสไปรษณีย์” เพิ่มขึ้นมา โดยจะแสดงรหัสไปรษณีย์ของตำบลที่เราเลือกเท่านั้น
*ไฟล์ get_amphure.php , get_district.php และ get_zip.php ต้องเก็บไว้ในโฟลเดอร์ asset
**อย่าลืมตรวจสอบการเข้าถึงฐานข้อมูลให้ถูกต้อง
***ขอขอบคุณ คุณ benext ผู้เขียนบทความที่ช่วยจุดประกายให้ต่อยอดได้ด้วยนะครับ
ขออภัยครับ มึน ๆ เลยพิมพ์ผิด ขอแก้ไขดังนี้ครับ
*ไฟล์ get_amphure.php , get_district.php และ get_zip.php ต้องเก็บไว้ในโฟลเดอร์เดียวกันกับไฟล์หลักนะครับ
สุดยอดครับ จะลองเอามาปรับใช้ดู
อยากให้แจกโค้ดปฏิทินเชื่อมโยงฐานข้อมูล แบบ WordPress ด้วยครับ
ขอบคุณมากครับ อธิบายได้ชัดเจน