29 July 2005

AJAX: Simple sample

วันนี้นั่งลองเขียน php เพื่อลอง XMLHttpRequest โดยทำตามตัวอย่างเพื่อค้นหาข้อมูลในทันทีที่ผู้ใช้กรอกข้อมูล ที่นิยมทำกันในปัจจุบันโดยเฉพาะโปรแกรมดิกชันนารี เนื่องจากสามารถตอบสนองผู้ใช้ได้รวดเร็วกว่า ผู้ใช้ทราบได้ทันทีในขณะที่พิมพ์ว่ามีข้อมูลนี้อยู่หรือไม่ เว็บนี้ประกอบด้วยหลายส่วนคือ

  1. index.html ซึ่งเป็นส่วนติดต่อกับผู้ใช้
  2. ajax.js ซึ่งเป็น Javascript เพื่อติดต่อกับ server
  3. ajax.php เป็น php ส่วนติดต่อกับ database โดยส่วนนี้จะติดต่อกับ ajax.js เพื่อส่งผลลัพท์ไปแสดงผลใน index.html

ส่วนแรก index.html ก็เหมือนกับ html/php ทั่วๆไป คือเป็น form รับข้อมูลจากผู้ใช้

<html>
<head>
<title>Test Ajax</title>
<script language="javascript" src="ajax.js"></script>
</head>
<body>
<form action="search.php" method="post">
<strong>Book name:</strong> 
<input type="text" name="bkname" autocomplete="off" 
id="bkname" onKeyUp="preSearch()" />
<br />
</form>
<div id="filling">&nbsp;</div>
<div id="result">&nbsp;</div>
</body>
</html>

ส่วนที่สองคือ ajax.js ซึ่งทำหน้าที่ติดต่อกับ ajax.php เพื่อแสดงผลการค้นหา โดยจะถูกเรียกมาทำงานตามฟังก์ชัน preSearch() ซึ่งกำหนดไว้ที่ onKeyUp ซึ่งเป็น event ที่จะเกิดขึ้นทุกครั้งที่ผู้ใช้กรอกข้อมูลเข้าไปหนึ่งตัวอักษร เพราะต้องการให้เว็บแสดงผลลัพธ์ทันทีในขณะที่กำลังกรอกข้อมูล

var xmlhttp = false;

if (window.XMLHttpRequest) {
 xmlhttp = new XMLHttpRequest();
 xmlhttp.overrideMimeType('text/xml');
}
else if (window.ActiveXObject) {
 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

function preSearch() {
 var bkName = document.getElementById('bkname').value;
 if (bkName != "") {
   document.getElementById('filling').innerHTML = "Searching... ";
   var url = 'ajax.php?q='+bkName;
   xmlhttp.open('GET',url,true);
   xmlhttp.onreadystatechange = function() {
     if (xmlhttp.readystate == 4 && xmlhttp.status == 200) {
       document.getElementById('result').innerHTML = xmlhttp.responseText;
       document.getElementById('filling').innerHTML = "&nbsp;";
     }
     else {
       document.getElementById('result').innerHTML = "Error....";
       document.getElementById('filling').innerHTML = "&nbsp;";
     }
   };    
   xmlhttp.send(null);
 }
}

จากโปรแกรมข้างบน จะมีการเรียกใช้ XMLHttpRequest ซึ่งเป็น object จึงต้อง initialize ก่อน แต่ Internet Explorer กับ Gecko-based browser มีวิธีการเรียกใช้ XMLHttpRequest ไม่เหมือนกัน จึงต้องใช้วิธีข้างต้น ในการกำหนดค่าเริ่มต้น จากนั้น preSearch() จะเรียกข้อมูลที่ผู้ใช้กรอกไว้ โดยใช้ document.getElementById() ซึ่งฟังก์ชันนี้จัดว่าเป็นฟังก์ชันสำคัญฟังก์ชันหนึ่ง เพราะทำให้สามารถเข้าไปแก้ไขโครงสร้างส่วนต่างๆ ของเว็บได้ จากนั้นจะใช้ XMLHttpRequest เพื่อติดต่อไปยัง ajax.php และส่งข้อมูลที่ต้องการค้นหาไปให้ แล้วก็รอผลลัพธ์จาก ajax.php เพื่อนำมาแสดงผลใน id ที่ชื่อว่า result

ส่วนสุดท้ายคือ ajax.php ก็เป็นสคริปต์ php ทั่วๆ ไป ซึ่งจะรับ request แล้วก็จะไปค้นหาข้อมูลในฐานข้อมูล จัดรูปแบบให้เรียบร้อย เพื่อใช้เป็นผลลัพธ์

<?php 
 if (empty($_GET['q'])) {
       echo ' ';
   }
   else {
       $search = trim($_GET['q']);
       $link = mysql_connect('localhost', 'user', 'password')
           or die('Could not connect: '.mysql_error());
      mysql_select_db('bookstore') 
           or die('Could not select database:'.mysql_error());

      $query = "SELECT bkname,bkauthor FROM book WHERE bkname LIKE
'$search%'";
      $result = mysql_query($query) 
           or die('Query failed:'.mysql_error());
?>
       <table border="1"><tr><th>Title</th><th>Author</th></tr>
       <?php
       while($line = mysql_fetch_array($result, MYSQL_ASSOC)) {
           echo('<tr>');
           foreach($line as $col) {
               echo("<td>$col</td>");
           }
           echo('</tr>');
       }
       ?>
       </table>
<?php
       mysql_free_result($result);
       mysql_close($link);
   }
?>

สรุป จะเห็นว่าส่วนที่เพิ่มเติมของเทคนิค AJAX ก็คือ การใช้ XMLHttpRequest เพื่อร้องขอข้อมูลเพิ่มเติม และการเข้าถึง DOM โดยใช้ document.getElementById เพื่อให้สามารถแก้ไข หรือเพิ่มเติมโครงสร้างของเว็บได้ ช่วยให้เว็บมีการตอบสนองผู้ใช้ได้ดียิ่งขึ้น จากเดิมที่ต้องแสดงผลใหม่ทั้งหน้า เป็นแสดงผลเฉพาะส่วน ตัวอย่างนี้แค่แสดงลักษณะง่ายๆ ของ AJAX แต่การนำไปใช้งานจริง คงจะมีสิ่งที่ต้องคำนึงถึงมากกว่านี้ ทั้งในเรื่องการจัดการส่วนการแสดงผลให้เหมาะสม

No comments: