เนื้อหาต่อไปนี้ สำหรับสมาชิก เป็นการประยุกต์การดึงข้อมูล
จังหวัด อำเภอ/เขต ตำบล/แขวง และรหัสไปรษณีย์ ในประเทศไทย
เหมาะสำหรับการใช้ในฟอร์มข้อมูลของผู้ใช้ในเว็บไซต์ หรืออื่นๆ ตามประยุกต์
ดาวน์โหลด ไฟล์ sql ฐานข้อมูลจังหวัด อำเภอ ตำบล รหัสไปรษณีย์ในประเทศไทย
ฐานข้อมูลที่เราจัดให้มีการปรับแต่งให้เหมาะสมกับการใช้งาน ดังนั้นให้ใช้จากไฟล์ thailand_area_zipcode.sql
หลักของการประยุกต์ของเราก็คือ ให้การเลือกข้อมูลจังหวัด อำเภอ ตำบล และรหัสไปรษณีย์
มีความสัมพันธ์กัน โดยเขียนโค้ดให้ง่ายและน้อยที่สุด สำหรับใครจะเอาไปต่อยอด
ต้องดูหลักการทำงานให้เข้าใจก่อน แล้วค่อยปรับไปตามแนวของตัวเอง
ในที่นี้ใช้การเชื่อมต่อข้อมูลด้วย mysqli ใครที่ยังใช้แบบเก่าหรือ mysql
ต้องปรับก่อน อันนี้ลองหาข้อมูลเพิ่มเติมได้ทั่วไป รุปแบบไม่ต่างกันมากนัก
สำหรับไฟล์ db_connect.php ที่ใช้การเชื่อมต่อฐานข้อมูลด้วย mysqli
สามารถดาวน์โหลดได้ที่
ดาวน์โหลดไฟล์ พร้อมใช้ ชื่อ db_connect.php ได้ที่
1. เริ่มต้นให้ทำการดาวน์โหลดไฟล์ thailand_area_zipcode.sql
แล้วทำการ import เข้าไปในฐานข้อมูลที่ต้องการ หลังจากดำเนินการแล้ว
จะได้ตารางชื่อ
tbl_geography
tbl_provinces
tbl_amphures
tbl_districts
tbl_zipcodes
2. สร้างไฟล์ getAddress.php โค้ดตามด้านล่าง จะเป็นไฟล์สำหรับดึงข้อมูล
เพื่อสร้าง option ของ select ตามเงื่อนไขที่ส่งเข้ามาแบบ ajax
<?php header("Content-type:text/html; charset=UTF-8"); header("Expires: Tue, 03 Jul 2001 06:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); header("Connection: close"); include("db_connect.php"); $mysqli = connect(); // array ชื่อตารางในฐานข้อมูลที่เราจะใช้ $arr_tbl_name = array( "0"=>"tbl_geography", "1"=>"tbl_provinces", "2"=>"tbl_amphures", "3"=>"tbl_districts", "4"=>"tbl_zipcodes", ); // array คำนำหน้า สำหรับใช้เชื่อมฟิลด์ในตาราง $arr_data_prefix = array( "0"=>"geo", "1"=>"province", "2"=>"amphur", "3"=>"district", "4"=>"zipcode", ); // array สำหรับกำหนดฟิลด์ในตารางที่เราต้องการกำหนดเงื่อนไข $arr_field_where = array( "0"=>"geo_id", "1"=>"province_id", "2"=>"amphur_id", "3"=>"district_code", "4"=>"zipcode_id", ); // ข้อความสำหรับ option ให้เลือกข้อมูล $arr_choose_text = array( "0"=>"-- เลือกภาค --", "1"=>"-- เลือกจังหวัด --", "2"=>"-- เลือกอำเภอ/เขต --", "3"=>"-- เลือกตำบล/แขวง --", "4"=>"-- เลือกรหัสไปรษณีย์ -- ", ); $tbl_id=isset($_POST['IDTbl']) ? trim($_POST['IDTbl']) : NULL; $checkID=isset($_POST['IDCheck']) ? trim($_POST['IDCheck']) : NULL; $where_id=isset($_POST['IDWhere']) ? trim($_POST['IDWhere']) : NULL; $selected_id=isset($_POST['IDSelected']) ? trim($_POST['IDSelected']) : NULL; if(isset($tbl_id) && $tbl_id!="" || (isset($tbl_id) && $tbl_id!="" && isset($checkID) && $checkID!="" && isset($where_id) && $where_id!="") ){ if($where_id==2){ $keyData_id=$arr_data_prefix[$tbl_id]."_code"; }else{ $keyData_id=$arr_data_prefix[$tbl_id]."_id"; } $keyData_value=$arr_data_prefix[$tbl_id]."_name"; }else{ exit; } $sql=" SELECT * FROM ".$arr_tbl_name[$tbl_id]." WHERE 1 "; if($where_id!=""){ $sql.=" AND ".$arr_field_where[$where_id]."='".$checkID."' "; } // เรียงจาก id สามารถแก้เป็นเรียงตามชื่อได้ด้วยค่า $keyData_value // แต่เนื่องจากในฐานข้อมูล อาจจะมีบางรายการลำดับไม่ถูกต้อง แต่ก็สามารถกำหนดได้ $sql.=" ORDER BY ".$keyData_id." "; $result = $mysqli->query($sql); ?> <option value=""><?=$arr_choose_text[$tbl_id]?></option> <?php if($result->num_rows>0){ while($row = $result->fetch_assoc()){ ?> <option value="<?=$row[$keyData_id]?>" <?=($row[$keyData_id]==$selected_id)?" selected":""?> > <?=$row[$keyData_value]?> </option> <?php } } ?>
3. ไฟล์ทดสอบ หรือไฟล์ที่เรียกใช้งาน ในที่นี้ใช้ชื่อเป็น thailand_area.php
โค้ดตามด้านล่าง คำอธิบายแสดงในโค้ด
<?php include("db_connect.php"); $mysqli = connect(); ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <!-- ไฟล์ทดสอบนี้ใช้ css ของ boostrap--> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> <!-- มีการใช้งาน ajax ของ jquery--> <script src="//code.jquery.com/jquery-1.11.3.min.js"></script> </head> <body> <div class="container" style="width:300px;"> <br><br><br><br><br><br> <table class="table table-striped" style="width:300px;"> <tr class="active"> <td colspan="2" class="text-center"> จังหวัด อำเภอ ตำบล รหัสไปรษณีย์ </td> </tr> <tr> <td width="100" class="text-right"> จังหวัด </td> <td class="text-left"> <select name="province_name" data-where="2" class="ajax_address form-control input-sm"> <option value="">-- เลือกจังหวัด --</option> </select> </td> </tr> <tr> <td class="text-right"> อำเภอ/เขต </td> <td class="text-left"> <select name="amphur_name" data-where="3" class="ajax_address form-control input-sm"> <option value="">-- เลือกอำเภอ/เขต --</option> </select> </td> </tr> <tr> <td class="text-right"> ตำบล/แขวง </td> <td class="text-left"> <select name="district_name" data-where="4" class="ajax_address form-control input-sm"> <option value="">-- เลือกตำบล/แขวง --</option> </select> </td> </tr> <tr> <td class="text-right"> รหัสไปรษณีย์ </td> <td class="text-left"> <select name="zipcode_name" data-where="5" class="ajax_address form-control input-sm"> <option value="">-- เลือกรหัสไปรษณีย์ --</option> </select> </td> </tr> </table> </div> <script type="text/javascript"> $(function(){ // เมื่อโหลดขึ้นมาครั้งแรก ให้ ajax ไปดึงข้อมูลจังหวัดทั้งหมดมาแสดงใน // ใน select ที่ชื่อ province_name // หรือเราไม่ใช้ส่วนนี้ก็ได้ โดยไปใช้การ query ด้วย php แสดงจังหวัดทั้งหมดก็ได้ $.post("getAddress.php",{ IDTbl:1 },function(data){ $("select[name=province_name]").html(data); }); // สร้างตัวแปร สำหรับเก็บค่าข้อความให้เลือกรายการ เช่น เลือกจังหวัด // เราจะเก็บค่านี้ไว้ใช้กรณีมีการรีเซ็ต หรือเปลี่ยนแปลงรายการใหม่ var chooseText=[]; $(".ajax_address").each(function(i,k){ var initObj=$(".ajax_address").eq(i).find("option:eq(0)")[0]; chooseText[i]=initObj; }); // ส่วนของการตรวจสอบ และดึงข้อมูล ajax สังเกตว่าเราใช้ css คลาสชื่อ ajax_address // ดังนั้น css คลาสชื่อนี้จำเป็นต้องกำหนด หรือเราจะเปลี่ยนเป็นชื่ออื่นก็ได้ แต่จำไว้ว่า // ต้องเปลี่ยนในส่วนนี้ด้วย $(".ajax_address").on("change",function(){ var indexObj = $(".ajax_address").index(this); // เก็บค่า index ไว้ใช้งานสำหรับอ้างอิง // วนลูปรีเซ็ตค่า select ของแต่ละรายการ โดยเอาค่าจาก array ด้านบนที่เราได้เก็บไว้ $(".ajax_address").each(function(i,k){ if(i>indexObj){ // รีเซ็ตค่าของรายการที่ไม่ได้เลือก $(".ajax_address").eq(i).html(chooseText[i]); } }); var obj=$(this); var IDCheck=obj.val(); // ข้อมูลที่เราจะใช้เช็คกรณี where เช่น id ของจังหวัด var IDWhere=obj.data("where"); // ค่าจาก data-where ค่าน่าจะเป็นตัวฟิลด์เงื่อนไขที่เราจะใช้ var targetObj=$("select[data-where='"+(IDWhere+1)+"']"); // ตัวที่เราจะเปลี่ยนแปลงข้อมูล if(targetObj.length>0){ // ถ้ามี obj เป้าหมาย targetObj.html("<option>.. กำลังโหลดข้อมูล.. </option>"); // แสดงสถานะกำลังโหลด setTimeout(function(){ // หน่วงเวลานิดหน่อยให้เห็นการทำงาน ตัดเออกได้ // ส่งค่าไปทำการดึงข้อมูล option ตามเงื่อนไข $.post("getAddress.php",{ IDTbl:IDWhere, IDCheck:IDCheck, IDWhere:IDWhere-1 },function(data){ targetObj.html(data); // แสดงค่าผลลัพธ์ }); },1500); } }); }); </script> </body> </html>
อธิบายการใช้งานเพิ่มเติม
สังเกตค่า attribute ชื่อ data-where เราจะกำหนดค่านี้ให้สัมพันธ์กับข้อมูลใน array ของไฟล์
getAddress.php โดยค่านี้จะถุกนำไปใช้ ดังนี้
รุปแบบ ค่าที่ส่งไปหาไฟล์ ajax
var obj=$(this); var IDCheck=obj.val(); // ข้อมูลที่เราจะใช้เช็คกรณี where เช่น id ของจังหวัด var IDWhere=obj.data("where"); // ค่าจาก data-where ค่าน่าจะเป็นตัวฟิลด์เงื่อนไขที่เราจะใช้ var targetObj=$("select[data-where='"+(IDWhere+1)+"']"); // ตัวที่เราจะเปลี่ยนแปลงข้อมูล if(targetObj.length>0){ // ถ้ามี obj เป้าหมาย targetObj.html("<option>.. กำลังโหลดข้อมูล.. </option>"); // แสดงสถานะกำลังโหลด setTimeout(function(){ // หน่วงเวลานิดหน่อยให้เห็นการทำงาน ตัดเออกได้ // ส่งค่าไปทำการดึงข้อมูล option ตามเงื่อนไข $.post("getAddress.php",{ IDTbl:IDWhere, IDCheck:IDCheck, IDWhere:IDWhere-1 },function(data){ targetObj.html(data); // แสดงค่าผลลัพธ์ }); },1500); }
ถ้าเราเลือกจังหวัด หรือเปลี่ยนแปลงจังหวัด
ซึ่งมีค่า data-where=2
IDTbl:IDWhere, คือ ค่าที่เราจะไปเลือกตารางที่ต้องการ นั่นหมายถึง
เราต้องการดึงตาราง อำเภอ tbl_amphures ที่มีค่า index ของ arrray ชื่อ
$arr_tbl_name ในไฟล์ getAddress.php เท่ากับ 2
คำสั่ง sql ที่เราจะได้คือ
SELECT * FROM tbl_amphures WHERE 1
IDCheck:IDCheck, คือส่งค่าของข้อมูลที่เราต้องการตรวจสอบ IDCheck ในที่นี้คือค่าของ
province_id หรือ id ของจังหวัดที่เราเลือก คำส่ัง sql เราก็จะเป็น
SELECT * FROM tbl_amphures WHERE 1 AND ชื่อฟิลด์=IDCheck
IDWhere:IDWhere-1 คือชื่อฟิลด์ของตาราง ที่เราต้องการตรวจสอบ จากตัวอย่างสมมติ
เราให้ data-where=2 ดังนั้น IDWhere-1 จึงเท่ากับ 2-1 = 1
ค่า 1 ในไฟล์ getAddress.php ตรงกับฟิลด์ province_id ของ array ที่ชื่อ $arr_field_where
ดังนั้นเราจำได้คำสั่ง sql แบบเต็มเป็น
SELECT * FROM tbl_amphures WHERE 1 AND province_id=IDCheck
ซึ่งจะเป็นการไปดึงอำเภอทั้งหมดที่มี id จังหวัดตรงตามเงื่อนไขมาแสดง
รูปแบบส่วนอื่นๆ ก็ลักษณะเดียวกัน
เลือกจังหวัด ส่ง id จังหวัดไปตารางอำเภอ แล้วแสดงลิสอำเภอ
เลือกอำเภอ ส่ง id อำเภอไปตารางตำบล แล้วแสดงลิสตำบล
เลือกตำบล ส่ง code ตำบลไปตารางรหัสไปรษณีย์ แล้วแสดงลิสรหัสไปรษณีย์
หากเราต้องการใช้แค่ จังหวัด อำเภอ และตำบล
เราก็สามารถตัดส่วนของ รหัสไปษณีย์ออกไปได้เลย โดยไม่ต้องแก้ไขโค้ด ajax
นอกจากนั้นสามารถประยุกต์เพิ่มเติมได้เช่น อาจสร้าง input hidden เก็นที่อยู่
แบบรวมไว้ ยกตัวอย่าง "ตำบลในเมือง อำเภอเมือง จังหวัดขอนแก่น"
หรืออื่นๆ ตามแต่จัดประยุกต์ใช้งาน
รูปตัวอย่างผลลัพธ์