ตัวอย่างการใช้งาน AJAX กับเว็บไซต์ ตอนที่ 4

ตัวอย่างนี้จะว่าด้วยเรื่อง การส่งข้อมูลไปบันทึกยังฐานข้อมูลด้วย Ajax ซึ่งเป็นจุดเด่นที่สำคัญอีกเรื่องของ Ajax ซึ่งมีข้อสะดวกกว่าการ Submit ด้วฟอร์ม เนื่องจากหากมีการใช้งาน Ajax ในการส่งข้อมูลไปบันทึกยังฐานข้อมูลแล้ว เราจะสามารถทำได้ทันทีที่มีการเปลี่ยนแปลงข้อมูล โดยไม่ต้องรอให้กด Submit ก่อน เช่นการเลือก checkbox แล้วบันทึกข้อมูลที่เลือกลงฐานข้อมูลในทันที

โค้ด HTML ผมแบ่งออกเป็น 3 ส่วน เพื่อให้ง่ายต่อการทำความเข้าใจนะครับ
ส่วนแรกเป็น input แบบ Text พร้อมปุ่มกด ซึ่งจะมีลักษณะคล้ายๆฟอร์มทั่วๆไป
<label for="demo_txt">ข้อมูลที่จะส่ง</label>
<input type="text" id="demo_txt" value="">
<button id="demo_send" class="button send" name="submit">Save</button>

ส่วนที่สองเป็น input ชนิด Radio ซึ่งจะมีการอัปเดทอัตโนมัติเมื่อมีการคลิกที่ Radio ตัวใดตัวหนึ่ง
<p>อัปเดทอัตโนมัติเมื่อมีการคลิก Radio</p>
<label><input type="radio" name="test" value="1"> ตัวที่ 1</label>
<label><input type="radio" name="test" value="2"> ตัวที่ 2</label>
<label><input type="radio" name="test" value="3"> ตัวที่ 3</label>

ส่วนที่สามคือพื้นที่แสดงผลลัพท์ที่ได้จากการตอบกลับจาก Ajax
<div id="demo_result" class="center"></div>

สำหรับการทำงานในส่วนของ Javascript เริ่มต้นจากการวนลูปเพื่ออ่าน tag ทั้งหมด แล้วเลือกเอาเฉพาะปุ่มกด และ Radio มากำหนด Event Click
// วนลูปอ่าน tag ทั้งหมดใน div_elem
forEach($G('div_elem').elems('*'), function () {
   // ใช้ RegExp ตรวจสอบ name ของ tag ว่าเป็นรายการที่ต้องการหรือไม่ (test1-test4 และ submit)
   if (/(submit|test)/.test(this.name)) {
       // ถ้าใช่ตัวที่กำหนด ให้ดักจับอีเว้นต์ click
       $G(this).addEvent('click', doClick);
   }
});

เมื่อมีการคลิกที่ปุ่มกดหรือ Radio ก็จะมีการอ่านค่าและส่งต่อไปยังฟังก์ชั่น send เพื่อทำการส่งค่าไปยัง Server ด้วย Ajax
// ฟังก์ชั่นรับค่าจากการคลิก
var doClick = function (e) {
    if (this.type == 'radio') {
        // Radio
        send(this.name + '=' + this.value);
    } else {
        // มาจากการกดปุ่ม
        send('name=' + $E('demo_txt').value);
    }
};

ฟังก์ชั่นสุดท้ายเป็นชุดคำสั่งสำหรับการส่งข้อมูลด้วย Ajax และการรับค่ากลับมา ในตัวอย่างนี้เมื่อมีการส่งค่าไปยัง PHP แล้ว ค่าที่ตอบกลับมาจะอยู่ในรูปของ JSON String ซึ่งเราจะต้องแปลงให้เป็น JSON Object ที่ Javascript รู้จักก่อนถึงจะนำไปใช้งานได้
// ฟังก์ชั่นส่งข้อมูลด้วย Ajax
function send(q) {
    // create GAjax
    var req = new GAjax();
    // กำหนดการแสดงรูปรอโหลดไปที่ปุ่มกด
    req.initLoading('demo_txt');
    // เรียกข้อมูลด้วย Ajax โดยการส่งค่า url ที่ต้องการไปยัง Index\Web\Model->save()
    req.send('index.php/index/model/index/save', q, function (xhr) {
        // แปลงข้อความที่ตอบกลับมาจาก Server เป็น JSON
        var ds = xhr.responseText.toJSON();
        if (ds) {
            // ตรวจสอบค่าที่ส่งมา ถ้ามีให้ alert()
            if (ds.error) {
                // ข้อความแจ้งเตือน
                alert(ds.error);
                // highlight input ที่ error และส่งโฟกัสไปยัง input
                $G('demo_txt').invalid().focus();
            } else if (ds.sql) {
                // เขียนคำสั่งเพื่อจัดการแสดงผล ผลลัพท์ที่ส่งกลับมา
                var p = document.createElement('p');
                p.innerHTML = ds.sql;
                $E('demo_result').appendChild(p);
            }
        } else if (xhr.responseText != '') {
            // ถ้าข้อมูลที่ส่งค่ากลับไม่ใช่ JSON และ ไม่ได้เป็นข้อมูลว่าง
            alert(xhr.responseText)
        }
    });
}

ตัวอย่างนี้แสดงให้เห็นถึงความสามารถในการแจ้งเตือนในกรณีที่ไม่ได้มีการกรอกข้อมูลด้วย โดยการตรวจสอบจะไปทำการตรวจสอบที่ PHP ซึ่งถ้ามีข้อผิดพลาดก็จะส่งข้อผิดพลาดกลับมา รวมถึงการ highlight รายการที่มีปัญหาอีกด้วย
และสุดท้ายถ้าทุกอย่างถูกต้อง PHP ก็จะส่งค่าคำสั่ง SQL ที่ดำเนินการแล้วกลับมาแสดงผลยังพื้นที่แสดงผล (demo_result) ต่อไป

ในส่วนของ PHP ฟังก์ชั่น send ของ Javascript จะทำการส่งข้อมูลไปที่ Index\Index\Model->save() เนื่องจากค่าที่ส่งมาจาก Ajax อยู่ในรูป POST จึงมีการวนลูปอ่านค่า $_POST ที่ส่งมาก่อน (เนื่องจากเราไม่แน่ใจว่าจะมีข้อมูลใดส่งมาบ้าง จึงต้องใช้วิธีตรวจสอบค่าที่มีการส่งมาด้วยตัวเอง) ที่ค่าที่ส่งมาแต่ละรายการจะถูกอ่านจาก $request->post() อีกที ตามด้วยเมธอดสำหรับฟิลเตอร์ค่าที่ส่งมาเพื่อความปลอดภัยอีกชั้น เช่น toInt() จะทำให้มีการรับค่าเฉพาะที่เป็นตัวเลขเท่านั้น ส่วน topic() จะรับค่าข้อความปกติไม่รับแท็กใดๆและมีได้แค่บรรทัดเดียว เป็นต้น

ค่าที่รับมาจะมาทำการตรวจสอบว่ามีการกรอกหรือไม่ในกรณ๊ที่เป็น name (กรณีที่เป็นค่าอื่นจะข้ามการตรวจสอบ) ซึ่งถ้าไม่มีการกรอก name มาจะมีการส่ง Error กลับที่ตัวแปร $json
ในกรณีที่ไม่มีข้อผิดพลาด สุดท้ายก็จะเป็นการบันทึกข้อมูลลงฐานข้อมูล ซึ่งในตัวอย่างนี้ผมไม่ได้มีการบันทึกลงฐานข้อมูลจริงๆ (comment บรรทัด $query->execute() ไว้) โดยผมเลือกที่จะส่งคำสั่ง SQL ที่จะประมวลผลกลับไปแสดงเป็นผลลัพท์แทน
สุดท้าย คำสั่ง json_encode จะทำการแปลงข้อมูล $json ซึ่งอยู่ในรูปแบบ Array (เนื่องจาก PHP ไม่ได้รู้จักข้อมูลชนิด JSON ตรงๆ) ให้เป็นข้อมูลชนิด JSON เพื่อส่งกลับไปยัง Ajax ต่อไป
/** 
 * ส่งข้อมูลไปบันทึกด้วย Ajax
 *
 * @param Request $request
 */

public function save(Request $request)
{
  // ตรวจสอบว่าเรียกมาจากภายในไซต์
  if ($request->isReferer()) {
    // ดูค่าที่ส่งมา
    //print_r($_POST);
    // create Model
    $model = new \Kotchasan\Model;
    // วนลูปค่าที่ส่งมาจาก $_POST
    foreach ($_POST AS $key => $value) {
      if ($key == 'test') {
        // test รับค่าเป็นตัวเลข
        $save['test'] = $request->post($key)->toInt();
      } else {
        // name รับค่าเป็นข้อความบรรทัดเดียว
        $save['name'] = $request->post($key)->topic();
      }
    }
    if (!empty($save)) {
      if (isset($save['name']) && $save['name'] == '') {
        $json = array('error' => 'กรุณากรอกข้อความ');
      } else {
        // query INSERT
        $query = $model->db()->createQuery()->insert('world', $save);
        // ประมวลผลคำสั่ง SQL ในตอนใช้งานจริง
        //$query->execute();
        // ข้อมูล JSON สำหรับส่งกลับไปแสดงผล
        $json = array(
          // คืนค่าคำสั่ง SQL ที่สร้าง
          'sql' => $query->text()
        );
      }
      // คืนค่าเป็น JSON
      echo json_encode($json);
    }
  }
}

ตัวอย่างนี้ดูได้ที่นี่นะครับ https://projects.kotchasan.com/....php?module=database
หมายเหตุ ตัวอย่างนี้ต้องมีการกำหนดค่าฐานข้อมูลด้วย ดังนั้นก่อนการทดสอบตัวอย่างจะต้องแก้ไข settings/database.php ให้ตรงตามฐานข้อมูลที่มีอยู่ด้วย (ใช้ฐานข้อมุลใดก็ได้เนื่องจากสคริปต์ต้องการแค่การเชื่อมต่อฐานข้อมูล)
0SHAREFacebookLINE it!