GORAGOD.com

บทที่ 10 ใช้งาน Combobox ที่ทำงานสัมพันธ์กัน ด้วย AJAX

เป็นการใช้งาน Combobox 3 ตัวที่ทำงานสัมพันธ์กันครับ โดยที่เมื่อเราเลือกตัวที่ 1 ก็จะไปอ่านข้อมูลจากฐานข้อมูลมาใส่ตัวที่ 2 และเมื่อเราเลือกตัวที่ 2 ก็จะเป็นการอ่านข้อมูลมาแสดงยังตัวที่ 3 ครับ

ตัวอย่างเป็นการเลือกข้อมูล อำเภอ ตำบล หมู่บ้าน มาแสดง โดยต้องทำการเลือก อำเภอ ก่อน เมื่อเลือกแล้วก็จะมี รายการตำบลของอำเภอนั้นๆขึ้นมาให้เลือก และเมื่อเลือกตำบลแล้ว ก็จะมีรายการหมู่บ้านมาให้เลือกต่อไป

provincedemo.php หน้าหลักสำหรับแสดงผล

<?php
  //ค่าที่ได้รับมาจากการ Submit
  $amphur=$_POST['amphur'];
  $tumbon=$_POST['tumbon'];
  $ban=$_POST['ban'];
  if (!empty($amphur)) {
    echo "<br /><br />ค่าที่ได้จากการ Submit คือ :<br /><br />อำเภอที่เลือก : $amphur<br />ตำบลที่เลือก : $tumbon<br />หมู่บ้านที่เลือก : $ban<br /><br /><br /> ";
  }
  
  echo "<form name=sel action='' method=POST> ";
  echo "อำเภอ : <font id=amphur><select> ";
  echo "<option value='0'>--------------------</option> " ;
  echo "</select></font> ";
  
  echo "ตำบล : <font id=tumbon><select> ";
  echo "<option value='0'>--------------------</option> " ;
  echo "</select></font> ";
  
  echo "หมู่บ้าน : <font id=ban><select> ";
  echo "<option value='0'>--------------------</option> " ;
  echo "</select></font> ";
  
  echo "<br /><br /><br />แสดงผลลัพท์การเลือก เป็น ID ของแต่ละรายการ (เพื่อนำไปใช้ต่อ) : <font id=result color=red></font> ";
  echo "<br /><br /><br /><input type=submit value=ส่ง name=submit>";
  echo "</form> ";
?>

จากโค้ด เป็นการแสดง Combobox เปล่าๆ 3 ตัวสำหรับใส่ข้อมูล อำเภอ, ตำบล, หมู่บ้าน ตามลำดับครับ ผมเลือกใช้ tag Font เป็นพื้นที่แสดงผล (จะเห็นว่าผมกำหนด id ให้กับ tag Font) ก็เพื่อให้มันไม่ขึ้นบรรทัดใหม่ครับ ซึ่งในความเป็นจริงแล้วเราสามารถใช้ tag อะไรก็ได้เพื่อแสดงผลครับ (div, a, p หรืออะไรก็ได้) ซึงเมื่อใดที่ทำการโหลดหน้านี้ ก็จะให้ AJAX ไปทำการเรียกข้อมูล อำเภอ มาแสดงใน Combobox ตัวแรกทันทีครับ

<script language=Javascript>
function Inint_AJAX() {
   try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {} //IE
   try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {} //IE
   try { return new XMLHttpRequest(); } catch(e) {} //Native Javascript
   alert("XMLHttpRequest not supported");
   return null;
};

//dochange จะถูกเรียกเมื่อมีการเลือก รายการ Combobox ซึ่งจะทำให้ไปเรียก AJAX เพื่อร้องขอข้อมูลถัดไปจาก Server
function dochange(src, val) {
  var req = Inint_AJAX();
  req.onreadystatechange = function () {
    if (req.readyState==4) {
      if (req.status==200) {
        document.getElementById(src).innerHTML=req.responseText; //รับค่ากลับมา
      }
    }
  };
  req.open("GET", "province.php?data="+src+"&val="+val); //สร้าง connection
  req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); // set Header
  req.send(null); //ส่งค่า
}

//ฟังก์ชั่นนี้ใช้แสดงผล id ของ Combobox แต่ละตัวที่เลือก
function banchange() {
  document.getElementById('result').innerHTML=sel.amphur.value+', '+sel.tumbon.value+', '+sel.ban.value;
}

//เรียกครั้งแรกไปทำการโหลด อำเภอ มาแสดง
window.onLoad=dochange('amphur', -1);
</script>

AJAX หัวใจของการทำงานของโค้ดนี้ เพื่อทำการเรียกดูข้อมูล โดยที่ไม่ต้องทำการ Reload ทั้งหน้า

province.php หน้าที่ถูก Ajax เรียกไปเพื่อขอข้อมูล

<?php
  //กำหนดให้ IE อ่าน page นี้ทุกครั้ง ไม่ไปเอาจาก cache
  header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
  header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  header ("Cache-Control: no-cache, must-revalidate");
  header ("Pragma: no-cache");
  
  header("content-type: text/html; charset=tis-620");
  
  //ค่าที่ถูกส่งมาด้วยจาก AJAX
  $data=$_GET['data'];
  $val=$_GET['val'];
  
  //ค่ากำหนดของ ฐานข้อมูล
  $host="localhost";
  $username="root";
  $password="";
  $dbname="province";

  //เชื่อมต่อกับ MySQL
  $connect= mysql_connect($host, $username, $password) or die("ไม่สามารถเชื่อมต่อฐานข้อมูลได้");
  $db=mysql_select_db($dbname) or die("ฐานข้อมูลไม่ถูกต้อง");
  
  if ($data=='amphur') { //เมื่อมีการโหลดครั้งแรก อ่านข้อมูล อำเภอ
    $sql="select * from amphur order by id";
    $result = mysql_query($sql);
    echo "<select name='amphur' onChange=\"dochange('tumbon', this.value)\"> ";
    echo "<option value='0'>-กรุณาเลือกอำเภอ-</option> ";
    echo "<option value='0'>--------------------</option> ";
    while($fetcharr = mysql_fetch_array($result)) {
      $val = $fetcharr['amp_code'];
      $label = $fetcharr['amp_name'];
      echo "<option value=\"$val\">$label</option> " ;
    }
  } else if ($data=='tumbon') { //เมื่อทำการเลือก อำเภอ แสดงข้อมูล ตำบล
    echo "<select name='tumbon' onChange=\"dochange('ban', this.value)\"> ";
    $sql="select * from tumbon where amp_code = '$val'";
    $result = mysql_query($sql);
    echo "<option value='0'>-กรุณาเลือกตำบล-</option> ";
    echo "<option value='0'>--------------------</option> ";
    while($fetcharr = mysql_fetch_array($result)) {
      $val = $fetcharr['tum_code'];
      $label = $fetcharr['tum_name'];
      echo "<option value=\"$val\">$label</option> " ;
    }
  } else if ($data=='ban') { //เมื่อมีการเลือก ตำบล แสดงข้อมูล หมู่บ้าน
    echo "<select name='ban' onChange=\"banchange()\"> ";
    $sql="select * from ban where tum_code = '$val'";
    $result = mysql_query($sql);
    echo "<option value='0'>-กรุณาเลือกหมู่บ้าน-</option> ";
    echo "<option value='0'>--------------------</option> ";
    while($fetcharr = mysql_fetch_array($result)) {
      $val = $fetcharr['ban_code'];
      $label = $fetcharr['ban_name'];
      echo "<option value=\"$val\">$label</option> " ;
    }
  }
  echo "</select> ";
?>

โค้ดนี้แบ่งการทำงานออกเป็น 3 ส่วน คือครั้งแรกเมื่อโหลดให้ส่ง 'amphur' มายัง data ซึ่งเป็นการบอกให้โค้ดไปเลือกรายการ อำเภอ ต่างๆมาสร้างรายการ Combobox และแสดงผล ซึ่งก็จะนำไปแสดงผลยัง id 'amphur' ที่กำหนดไว้แต่แรก และต่อมาเมื่อเลือกรายการ 'amphur' ก็จะเรียก AJAX ให้ส่ง 'tumbon' มายัง data และส่ง ID ของอำเภอที่เลือก มายัง 'val' เพื่อให้ PHP ทำการค้นหาและสร้าง Combobox เพื่อแสดง 'tumbon' ที่สัมพันธ์กับ อำเภอที่เลือกมาแสดง ต่อไป ซึ่งในกรณีของ 'ban' ก็เช่นเดียวกันครับ

ในการแสดงผลรายการที่ถูกเลือกเป็นการรายงานรายการ ID ของ อำเภอ, ตำบล, หมู่บ้านที่ถูกเลือกครับ (เพื่อเอา ID ไปใช้งานต่อ)

สำหรับฐานข้อมูลที่ผมแนบมาด้วย ให้ทำการ copy ไดเร็คทอรี่ province ไปไว้ยัง C:\AppServ\mysql\data\ ครับ จะเรียกใช้งานฐานข้อมูลได้ทันที (ป้องกันปัญหาเกี่ยวกับ ภาษาเป็น ???? ครับ)

เนื่องจากผมไม่มีฐานข้อมูล จังหวัดครบถ้วน เลยไม่สามารถออกแบบให้แสดงครบทั้ง จังหวัด, อำเภอ, ตำบล, หมู่บ้าน ได้ จึงอยากให้ใครก็ตามที่มีฐานข้อมูลครบถ้วนจะส่งมาให้ผมเพื่อเผยแพร่ต่อไปก็จะดีครับ

*ดาวน์โหลด เป็นฐานข้อมูล MySQL นะครับ
 
 (1,563)
 
ตัวอย่าง

ซอร์สโค้ด province.rar ที่เป็นฐานข้อมูล Text ตามตัวอย่างครับ (อัปเดท)
 
 (1,004)

ทฤษฎีของการใช้งาน combobox หรือ listbox แบบนี้มีอยู่ว่า
  1. ไม่ว่าจะมี combobox กี่ตัว parameter ทั้งหมดที่ส่งจะต้องเท่าจำนวน combobox เช่นต้องการ combobox ทั้งหมด 6 ตัวก็จะเป็นว่ามี $value1-$value6 จากตัวอย่างผมมี 3 combobox ผมก็รับค่า 3 รายการ คือ
    $amphur=$_POST['amphur'];
    $tumbon=$_POST['tumbon'];
    $ban=$_POST['ban'];
  2. วิธีการเลือกว่าจะให้ แสดง combobox ใดบ้างก็อยู่ที่การตรวจสอบค่าที่ส่งมา คือ
    1. โหลดครั้งแรก ไม่มี parameter ใดๆ เลย ก็จะแสดงข้อมูลของ อำเภอ
      if ($data=='amphur') {
    2. เมื่อทำการเลือกรายการแรก ก็จะมี parameter $amphur ส่งกลับไปให้ AJAX ซึ่งมันก็จะเรียกเอารายการ combobox ที่ 2 ซึ่งก็คือ tambol ออกมา
      } else if ($data=='tumbon') {
    3. และเช่นกันเมื่อทำการเลือก tambon ก็จะมี parameter 2 ตัวที่ถูกเลือกแล้ว ส่งกลับไป คือ tumbonและ amphur ที่ทำการเลือกไว้ก่อนหน้า ซึ่งในขั้นตอนนี้ก็ให้ไปทำการเลือกข้อมูล ban ซึ่งมีความสัมพันธ์กันกับ tambon และ amphur ที่เลือกไว้ก่อนหน้ามาแสดง ในลำดับถัดไป
      } else if ($data=='ban') {
    จะเห็นได้ว่าถ้ามี parameter มากขึ้นก็จะมีการรับส่งค่าหลายๆตัว มากขึ้นตาม โดยที่ตามปกติ เราก็จะมีลำดับชั้นอยู่แล้วว่า ตัวที่ 1 ข้อมูลอะไร เมื่อเลือกแล้ว จะแสดงข้อมูลอะไร ซึ่งเราก็ใช้ if แยกออกแล้วไป query เอาข้อมูลออกมาตามที่เราต้องการต่อไป