การคำนวณราคาสินค้าอัตโนมัติขณะกรอก
การคำนวณราคาสินค้าโดยที่ไม่ต้อง Sumit นั้น มีเทคนิคง่ายๆ โดยที่ไม่ต้องพึ่งพา Ajax แต่อย่างใด (หลายๆคนคิดว่ามันต้องใช้ Ajax) เพราะหลักการของมันจริงๆแล้ว มันไม่จำเป็นต้องมีอะไรติดต่อกับ Server เลย เพียงแค่เราเตรียมข้อมูลที่จำเป็นเท่านั้น ซึ่งข้อมูลที่จำเป็นที่เราต้องเตรียมก็คือ ข้อมูลราคาสินค้าต่อหน่วย ส่วน จำนวนนั้นเราจะให้ User เป็นผู้กรอก
ในตัวอย่างนี้ผมจะนำเสนอแค่การเขียนโค้ดเพื่อคำนวณเท่านั้นนะครับ..
อย่างแรกเลยเรามาดูโค้ดฟอร์มกันก่อน
ในตัวอย่างนี้ผมแบ่งช่องกรอกออกเป็น 3 แถว เพื่อแสดงให้เห็นว่าเราสามารถเขียนคำสั่งเพื่อจัดการข้อมูลทั้ง 3 แถวได้ในคราวเดียว ไม่ต้องมานั่งจัดการกับ input ทีละตัวหรือข้อมูลทีละชุด ซึ่งจะทำให้การเพิ่มหรือลดจำนวนแถวของข้อมูลสามารถทำได้สะดวก
โค้ดด้านบนจะเป็นโค้ด Javascript สำหรับทำให้ input รับค่าเป็น ตัวเลขเท่านั้น (สำหรับจำนวนสินค้า) หรือ สามารถรับจุดทศนิยมได้ด้วย (สำหรับจำนวนเงิน)
โค้ดด้านบน เป็นโค้ดส่วนคำนวณราคารวมในแต่ละแถว โดย input ในแต่ละแถว จะอยู่ในตัวแปรแอเรย์ inps โดยที่ inps[0] คือจำนวนสินค้า inps[1] คือราคาสินค้า และ inps[2] คือช่องเก็บผลรวมราคาสินค้าที่ได้จากการคำนวณ inps0]*inps[1]
หัวใจของโค้ดอยู่ที่คำสั่งด้านบน หลักการก็คือ เราจะทำการอ่าน input ออกมาทีละแถว โดยอาศัย tag p เสร็จแล้วในแต่ละ tag p ค่อยไปอ่านเอา input ต่างๆ ออกมาอีกที ซึ่งจะทำให้เราได้ input ที่เกี่ยวข้องกันเท่านั้นออกมาในแต่ละรอบ
ถ้าสังเกตุดีๆ โค้ดนี้จะมีจุดพิศดารอยู่หน่อยหนึ่งคือมีการใช้คำสั่งนี้ครอบอยู่
การใช้คำสั่งนี้ เพื่อจำกัดโสคปของตัวแปร ซึ่งหากไม่มีการใช้คำสั่งนี้ ตัวแปร inps ที่ใช้ส่งค่าให้กับฟังก์ชั่น calc จะเป็นตัวแปรสุดท้ายเสมอ เพราะตัวแปรทั้งหมดอยู่ในสโคปเดียวกัน (ใน for) จึงมีการสร้างฟังก์ชั่นที่ไม่มีชื่อขึ้น
ตัวอย่าง
ในตัวอย่างนี้ผมจะนำเสนอแค่การเขียนโค้ดเพื่อคำนวณเท่านั้นนะครับ..
อย่างแรกเลยเรามาดูโค้ดฟอร์มกันก่อน
<form method="get" action="calc.php" id="calc_frm">
<p>
<input type="text" name="amount[]" value="1"> *
<input type="text" name="price[]" value="10"> =
<input type="text" name="sum[]"> </p>
<p>
<input type="text" name="amount[]" value="10"> *
<input type="text" name="price[]" value="1"> =
<input type="text" name="sum[]"> </p>
<p>
<input type="text" name="amount[]" value="10"> *
<input type="text" name="price[]" value="1"> =
<input type="text" name="sum[]"> </p>
</form>
ในตัวอย่างนี้ผมแบ่งช่องกรอกออกเป็น 3 แถว เพื่อแสดงให้เห็นว่าเราสามารถเขียนคำสั่งเพื่อจัดการข้อมูลทั้ง 3 แถวได้ในคราวเดียว ไม่ต้องมานั่งจัดการกับ input ทีละตัวหรือข้อมูลทีละชุด ซึ่งจะทำให้การเพิ่มหรือลดจำนวนแถวของข้อมูลสามารถทำได้สะดวก
/* ตัวเลขเท่านั้น */
var numberOnly = function (event) {
var key = event.which || event.keyCode;
if (!((key > 47 && key < 58) || key == 8 || key == 9 || key == 37 || key == 39)) {
event.preventDefault();
}
};
/* ตัวเลขและจุดเท่านั้น */
var currencyOnly = function (event) {
var key = event.which || event.keyCode;
if (!((key > 47 && key < 58) || key == 8 || key == 9 || key == 37 || key == 39 || key == 46)) {
event.preventDefault();
}
};
โค้ดด้านบนจะเป็นโค้ด Javascript สำหรับทำให้ input รับค่าเป็น ตัวเลขเท่านั้น (สำหรับจำนวนสินค้า) หรือ สามารถรับจุดทศนิยมได้ด้วย (สำหรับจำนวนเงิน)
/* หาผลคูณ */
function calc(inps) {
var amount = parseFloat(inps[0].value);
amount = isNaN(amount) ? 0 : amount;
var price = parseFloat(inps[1].value);
price = isNaN(price) ? 0 : price;
inps[2].value = amount * price;
};
โค้ดด้านบน เป็นโค้ดส่วนคำนวณราคารวมในแต่ละแถว โดย input ในแต่ละแถว จะอยู่ในตัวแปรแอเรย์ inps โดยที่ inps[0] คือจำนวนสินค้า inps[1] คือราคาสินค้า และ inps[2] คือช่องเก็บผลรวมราคาสินค้าที่ได้จากการคำนวณ inps0]*inps[1]
// form, p
var frm = document.getElementById('calc_frm'),
ps = frm.getElementsByTagName('p');
for (var i = 0; i < ps.length; i++) {
// อ่าน input ทีละแถว
var inps = ps[i].getElementsByTagName('input');
(function (inps) {
// จำนวน ตัวเลขเท่านั้น
inps[0].addEventListener('keypress', numberOnly);
// ราคา ตัวเลขและจุด
inps[1].addEventListener('keypress', currencyOnly);
// จำนวน คำนวนราคา
inps[0].addEventListener('keyup', function () {
calc(inps);
});
// ราคา คำนวนราคา
inps[1].addEventListener('keyup', function () {
calc(inps);
});
// สั่งคำนวณในครั้งแรก
calc(inps);
})(inps);
}
หัวใจของโค้ดอยู่ที่คำสั่งด้านบน หลักการก็คือ เราจะทำการอ่าน input ออกมาทีละแถว โดยอาศัย tag p เสร็จแล้วในแต่ละ tag p ค่อยไปอ่านเอา input ต่างๆ ออกมาอีกที ซึ่งจะทำให้เราได้ input ที่เกี่ยวข้องกันเท่านั้นออกมาในแต่ละรอบ
- inps[0] หรือ input ตัวแรกที่อ่านเจอ ก็จะเป็นจำนวนสินค้า เราก็ส่งไปตรวจจับ event keypress เพื่อให้รับค่าการกดเฉพาะตัวเลขเท่านั้น ด้วยฟังก์ชั่น numberOnly
- inps[1] หรือ input ตัวที่สอง ก็จะเป็นราคาสินค้า เราก็ส่งไปตรวจจับ event keypress เพื่อให้รับค่าการกดเฉพาะตัวเลขและจุดทศนิยม ด้วยฟังก์ชั่น currencyOnly
ถ้าสังเกตุดีๆ โค้ดนี้จะมีจุดพิศดารอยู่หน่อยหนึ่งคือมีการใช้คำสั่งนี้ครอบอยู่
(function (inps) {
......
})(inps);
การใช้คำสั่งนี้ เพื่อจำกัดโสคปของตัวแปร ซึ่งหากไม่มีการใช้คำสั่งนี้ ตัวแปร inps ที่ใช้ส่งค่าให้กับฟังก์ชั่น calc จะเป็นตัวแปรสุดท้ายเสมอ เพราะตัวแปรทั้งหมดอยู่ในสโคปเดียวกัน (ใน for) จึงมีการสร้างฟังก์ชั่นที่ไม่มีชื่อขึ้น
ตัวอย่าง