บทเรียน AngularJS กับการส่งข้อมูลจาก Form ด้วย POST Method ผ่าน Web Service ไปเก็บลงในฐานข้อมูล MySQL แบบง่าย พร้อม Validation Form ที่มีมาพร้อม AngularJS
บทความนี้เป็นบทความต่อเนื่องจากบทความ
ก่อนจะศึกษาบทความนี้แนะนำให้อ่านย้อนหลัง สำหรับผู้เริ่มต้น
- การเขียน Single Page Application ด้วย AngularJS
- AngularJS กับการวนซ้ำข้อมูลด้วย ng-repeat และกรองด้วย Filter
- AngularJS การแยก Controller และทำงานร่วมกับ Table
- AngularJS กับการทำงานร่วมกับ Web Service JSON
หากว่าเข้าใจ concept แล้วก็มาเริ่มทำงานต่อเนื่องจากบทความก่อนหน้าได้เลยครับ รอบนี้เราจะทำเมนู Register ขึ้นมาให้มีการลงทะเบียน
ให้ไปเพิ่ม หน้า register.html ใหม่ ครับ และทำการเพิ่มไฟล์ register.js ที่โฟลเดอร์ controller ด้วยครับ
HTML หน้า register.html เป็นตามนี้ครับ
<!doctype html> <html ng-app="registerModules"> <head> <meta charset="UTF-8"> <title>AngularJS</title> <link rel="stylesheet" href="css/bootstrap.min.css"> <script src="js/angular.min.js"></script> </head> <body> <div class="container"> <ul class="nav nav-pills" role="tablist"> <li role="presentation" class="active"><a href="index.html">Home</a></li> <li role="presentation"><a href="register.html">Register</a></li> <li role="presentation"><a href="#job">Jobs Report</a></li> </ul> <h3>Add New Driver</h3> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title">Register: </h3> </div> <div class="panel-body"> <form ng-controller="registerController" name="regForm" novalidate> </form> </div> </div> </div> <script src="controller/register.js"></script> </body> </html>
จะเห็นว่าเราได้สร้าง ng-app ชื่อ “registerModules” และเราได้สร้าง form สำหรับส่งค่าชื่อ “regForm” ที่มี ng-controller ชื่อ “registerController” ไว้ด้วยเช่นกัน และประกาศ controller/register.js ไว้ข้างล่างก่อนปิด </body> ครับ
ต่อมาให้เราเขียน form ของ Input ส่วนของ text ดังนี้ครับ
<p>First Name:<br> <input class="form-control" type="text" name="first_name" ng-model="first_name" required> <span class="alert alert-danger" ng-show="regForm.first_name.$dirty && regForm.first_name.$invalid"> <span ng-show="regForm.first_name.$error.required">First Name is required.</span> </span> </p>
จะเห็นว่า input ของ Textbox นั้นจะมีชื่อว่า first_name และชื่อ ng-model จะชื่เดียวกันคือ “first_name” ครับเป็นค่าที่ตรงกับ MySQL Table ส่วนของ drivers เลยครับ โดยมีการกำหนดให้ Fields ของ Textbox นี้เป็น required ครับ คือห้ามเป็นค่าว่าง หากเป็นค่าว่างจะเข้าเงื่อนไขการ Validation ที่ทาง AngularJS มีไว้ให้
<span class="alert alert-danger" ng-show="regForm.first_name.$dirty && regForm.first_name.$invalid"> <span ng-show="regForm.first_name.$error.required">First Name is required.</span>
จะโชว์ Message Alert เด้งเตือนครับถ้าเป็นค่าว่าง
ทำแบบนี้ให้ครบทุก Fields ครับ
<p>First Name:<br> <input class="form-control" type="text" name="first_name" ng-model="first_name" required> <span class="alert alert-danger" ng-show="regForm.first_name.$dirty && regForm.first_name.$invalid"> <span ng-show="regForm.first_name.$error.required">First Name is required.</span> </span> </p> <p>Last Name:<br> <input class="form-control" type="text" name="last_name" ng-model="last_name" required> <span class="alert alert-danger" ng-show="regForm.last_name.$dirty && regForm.last_name.$invalid"> <span ng-show="regForm.last_name.$error.required">Last Name is required.</span> </span> </p> <p>Telephone:<br> <input class="form-control" type="text" name="tel" ng-model="tel" required> <span class="alert alert-danger" ng-show="regForm.tel.$dirty && regForm.tel.$invalid"> <span ng-show="regForm.tel.$error.required">Telephone is required.</span> </span> </p> <p>TruckNo:<br> <input class="form-control" type="text" name="TruckNo" ng-model="TruckNo" required> <span class="alert alert-danger" ng-show="regForm.TruckNo.$dirty && regForm.TruckNo.$invalid"> <span ng-show="regForm.TruckNo.$error.required">TruckNo is required.</span> </span> </p> <p>TruckPV:<br> <input class="form-control" type="text" name="TruckPV" ng-model="TruckPV" required> <span class="alert alert-danger" ng-show="regForm.TruckPV.$dirty && regForm.TruckPV.$invalid"> <span ng-show="regForm.TruckPV.$error.required">TruckPV is required.</span> </span> </p>
สร้าง Input ที่เป็น Submit หรือปุ่มส่งข้อมูลขึ้นมาครับ
<p> <input type="submit" class="btn btn-sm btn-success" ng-click="submit_data()" ng-disabled="regForm.first_name.$dirty && regForm.first_name.$invalid || regForm.last_name.$dirty && regForm.last_name.$invalid || regForm.tel.$dirty && regForm.tel.$invalid || regForm.TruckNo.$dirty && regForm.TruckNo.$invalid || regForm.TruckPV.$dirty && regForm.TruckPV.$invalid"> </p>
ส่วนของการ Validation อยู่ตรงนี้ครับเป็นการเช็คว่า Text Input ไหนว่าง หรือตัวไหนห้ามว่าง
สร้าง <span> สำหรับโชว์ค่าคำเตือนขึ้นมาต่อท้ายเล็กน้อยเป็นการบอกว่า ระบบดำเนินการเสร็จหรือยัง
<p> <br/><span id="message" class="alert alert-success">{{message}}</span> </p>
ไฟล์ register.html จะเป็นแบบนี้
<!doctype html> <html ng-app="registerModules"> <head> <meta charset="UTF-8"> <title>AngularJS</title> <link rel="stylesheet" href="css/bootstrap.min.css"> <script src="js/angular.min.js"></script> </head> <body> <div class="container"> <ul class="nav nav-pills" role="tablist"> <li role="presentation" class="active"><a href="index.html">Home</a></li> <li role="presentation"><a href="register.html">Register</a></li> <li role="presentation"><a href="#job">Jobs Report</a></li> </ul> <h3>Add New Driver</h3> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title">Register: </h3> </div> <div class="panel-body"> <form ng-controller="registerController" name="regForm" novalidate> <p>First Name:<br> <input class="form-control" type="text" name="first_name" ng-model="first_name" required> <span class="alert alert-danger" ng-show="regForm.first_name.$dirty && regForm.first_name.$invalid"> <span ng-show="regForm.first_name.$error.required">First Name is required.</span> </span> </p> <p>Last Name:<br> <input class="form-control" type="text" name="last_name" ng-model="last_name" required> <span class="alert alert-danger" ng-show="regForm.last_name.$dirty && regForm.last_name.$invalid"> <span ng-show="regForm.last_name.$error.required">Last Name is required.</span> </span> </p> <p>Telephone:<br> <input class="form-control" type="text" name="tel" ng-model="tel" required> <span class="alert alert-danger" ng-show="regForm.tel.$dirty && regForm.tel.$invalid"> <span ng-show="regForm.tel.$error.required">Telephone is required.</span> </span> </p> <p>TruckNo:<br> <input class="form-control" type="text" name="TruckNo" ng-model="TruckNo" required> <span class="alert alert-danger" ng-show="regForm.TruckNo.$dirty && regForm.TruckNo.$invalid"> <span ng-show="regForm.TruckNo.$error.required">TruckNo is required.</span> </span> </p> <p>TruckPV:<br> <input class="form-control" type="text" name="TruckPV" ng-model="TruckPV" required> <span class="alert alert-danger" ng-show="regForm.TruckPV.$dirty && regForm.TruckPV.$invalid"> <span ng-show="regForm.TruckPV.$error.required">TruckPV is required.</span> </span> </p> <p> <input type="submit" class="btn btn-sm btn-success" ng-click="submit_data()" ng-disabled="regForm.first_name.$dirty && regForm.first_name.$invalid || regForm.last_name.$dirty && regForm.last_name.$invalid || regForm.tel.$dirty && regForm.tel.$invalid || regForm.TruckNo.$dirty && regForm.TruckNo.$invalid || regForm.TruckPV.$dirty && regForm.TruckPV.$invalid"> </p> <p> <br/> <span id="message" class="alert alert-success">{{message}}</span> </p> </form> </div> </div> </div> <script src="controller/register.js"></script> </body> </html>
ทีนี้ก็ได้เวลาไปจัดการส่วนของ controller แล้วครับ เพราะ View น่าจะเรียบร้อยแล้ว
angular.module('registerModules', []) .controller('registerController', function($scope,$http) { $scope.first_name = 'Banyapon'; $scope.last_name = 'Poolsawas'; $scope.tel = '+66887601413'; $scope.TruckNo = 'ภศ-4434'; $scope.TruckPV = 'กรุงเทพมหานคร'; $scope.submit_data = function () { $scope.message = ""; var request = $http({ method: "post", url: "api/submit_register.php", data: { first_name: $scope.first_name, last_name: $scope.last_name, tel: $scope.tel, TruckNo: $scope.TruckNo, TruckPV: $scope.TruckPV }, headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); request.success(function (data) { $scope.message = "Console : "+data; }); } });
ตัวอย่างผมได้ลองเขียนข้อมูลไปแสดงผล Binding กับ View สัก 1 ชุดผ่าน $Scope ของ registerController ครับ
$scope.first_name = 'Banyapon'; $scope.last_name = 'Poolsawas'; $scope.tel = '+66887601413'; $scope.TruckNo = 'ภศ-4434'; $scope.TruckPV = 'กรุงเทพมหานคร';
ฟังก์ชัน ของ Input type submit ที่ปุ่มบนหน้า register.html ให้เราไปพิจารณาส่วนนี้ครับ จะเห็นว่า ng-click เรียกฟังก์ชัน submit_data()
<input type="submit" class="btn btn-sm btn-success" ng-click="submit_data()"/>
มันจะตรงกับบน Controller เลยคือฟังก์ชัน submit_data()
$scope.submit_data = function () { $scope.message = ""; var request = $http({ method: "post", url: "api/submit_register.php", data: { first_name: $scope.first_name, last_name: $scope.last_name, tel: $scope.tel, TruckNo: $scope.TruckNo, TruckPV: $scope.TruckPV }, headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); request.success(function (data) { $scope.message = "Console : "+data; }); }
โดยฟังก์ชันของ submit_data() จะมีการส่ง Method เป็น POST ไปครับ แต่จะไม่ไปแบบ String Based ครับ มันจะทำการแปลงเป็น Key Value ก่อนให้อยู่ในรูปของ Object value ที่มี key อ้าง
data: { first_name: $scope.first_name, last_name: $scope.last_name, tel: $scope.tel, TruckNo: $scope.TruckNo, TruckPV: $scope.TruckPV }
พูดง่ายๆ คือการแปลง Input ใน textbox ให้อยู่ในรูปแบบของ JSON นั่นเองครับ แล้วส่งไปที่ไฟล์ api/submit_register.php
ดังนั้นเราต้องไปสร้าง API ภาษา PHP ในโฟลเดอร์ “api” ใหม่ขึ้นว่าชื่อว่า “submit_register.php” ครับ
<?php $postdata = file_get_contents("php://input"); $request = json_decode($postdata); @$first_name = $request->first_name; @$last_name = $request->last_name; @$tel = $request->tel; @$TruckNo = $request->TruckNo; @$TruckPV = $request->TruckPV; include"db.php"; $strSQL = "INSERT INTO driver "; $strSQL .="(first_name,last_name,tel,TruckNo,TruckPV)"; $strSQL .="VALUES"; $strSQL .="('".$first_name."','".$last_name."','".$tel."','".$TruckNo."','".$TruckPV."');"; $objQuery = mysql_query($strSQL) or die ("Error Query [".$strSQL."]"); echo 'Thank you: '.$first_name.' '.$last_name.' your car is'.$TruckNo.', '.$TruckPV.''; mysql_close($objConnect); ?>
รูปแบบการรับค่าต้องเป็น PHP รับค่า Object แบบ key value ของ POST Method ครับซึ่งเป็นดังนี้
$postdata = file_get_contents("php://input"); $request = json_decode($postdata); @$first_name = $request->first_name; @$last_name = $request->last_name; @$tel = $request->tel; @$TruckNo = $request->TruckNo; @$TruckPV = $request->TruckPV;
แล้วก็แค่จับไปใส่ MySQL ตามโครงสร้ง PHP ปรกติได้เลย เพียงแค่เราต้อง return String กลับไปว่าได้ดำเนินการเสร็จเรียบร้อย
echo 'Thank you: '.$first_name.' '.$last_name.' your car is'.$TruckNo.', '.$TruckPV.'';
ไว้ให้ controller/register.js ไปแสดงบน View register.html ที่ {{message}} ครับ
ทดสอบกันหน่อย
ข้อมูลเข้าเรียบร้อยไปเช็คที่ MySQL ได้เลยครับ
บทเรียนต่อไปเป็นการส่ง GET Parameter ที่เราจะไม่ GET แบบเดิมๆ แล้วเราจะใช้ $location ของ AngularJS ช่วยส่งไปครับ