ระบบงานต่าง ๆ ส่วนใหญ่เน้นการมาพัฒนาด้วย platform web รวมถึงลักษณะงานที่เป็นระบบ POS จากแต่ยุคเดิม ๆ ที่เป็นระบบ stanalone ติดตั้งไว้ที่เครื่อง client แต่ละเครื่อง ก็ปรับเปลี่ยนการทำงานบน web ด้วยความสะดวก และง่ายในการเข้าถึง ในยุคที่ internet เข้าถึงทุกคนในปัจจุบัน
อาจจะมองเป็นเรื่องยาก สำหรับนักพัฒนา สำหรับการที่จะให้ web สามารถทำงานร่วมกันได้กับ hardware device ต่าง ๆ ไม่ว่าจะเป็นเครื่องอ่านบาร์โค๊ด หรืออุปกรณ์อื่น มาทำความเข้าใจหลักการทำงานของการรับค่าจากอุปกรณ์เหล่านี้กันก่อน
เครื่องอ่านบาร์โค๊ด ก็เหมือนการรับค่าจาก keyboard แบบนึง
เมื่อเครื่องอ่านได้ทำการเริ่มอ่านค่า จนถึงอ่านค่าเสร็จ และได้ค่ามาแบบรวดเร็วมาก และจะได้รับข้อมูลข้อความชุดนึง แต่การทำงานอยู่เบื้องหลังจะมีการตรวจสอบ events ที่กระทำกับ web กล่าวคือ web จะ listener event keyboard และจะได้ค่าของตัวอักษรในแต่ละค่า และรวบรวมเป็นชุดข้อมูลพร้อมแสดง ค่านั้นออกมา เราก็จะใช้หลักการนี้ในการตรวจสอบค่านั้น ๆ โดย วันนี้จะแนะนำ javascript lib ที่ชื่อว่า onscan-js
แนะนำ onsacn-js คืออะไร
เครื่องสแกนบาร์โค้ดและ RFID ส่วนใหญ่ที่เชื่อมต่อผ่าน USB หรือบลูทูธ หรือติดตั้งไว้ในอุปกรณ์เคลื่อนที่ทำงานเหมือนกับแป้นพิมพ์ภายนอก พวกเขาเพียง “พิมพ์” สิ่งที่สแกน ทำให้ง่ายต่อการใช้งานกับแอปพลิเคชันใดๆ โดยไม่ต้องใช้ไดรเวอร์พิเศษ ตัวเชื่อมต่อ ฯลฯ ในทางกลับกัน ไม่มีวิธีใดที่จะตอบสนองต่อการสแกนโดยเฉพาะ – มันเป็นเพียงอินพุตที่พิมพ์เท่านั้น
onScan.js อนุญาตให้โค้ด Javascript แยกความแตกต่างระหว่างการพิมพ์ปกติและอินพุตการสแกน โดยจะวัดความเร็วในการพิมพ์ ค้นหาอักขระคำนำหน้าและคำต่อท้ายที่มักถูกส่งโดยเครื่องสแกนพร้อมกับข้อมูล ฯลฯ หากตรวจพบการสแกน onScan.js จะเริ่มการทำงานของเหตุการณ์ DOM แบบกำหนดเองที่เรียกว่าการสแกน
โดยความสามารถที่ช่วยในการจัดการเรื่อง Barcodescanner เป็นเรื่องง่าย
- callback (onScan) รับค่าหลังจากได้รบค่าจากการอ่าน
- callback (onScanError) เมื่อพบปัญหาในระหว่างการอ่าน
- onKeyDetect ตรวจสอบเพื่อทำงานบางอ่านในระหว่าอ่านแต่ละตัวอักษร
- singleScanQty กำหนดจำนวนครั้งในการอ่าน ถ้าต้องการให้ทำการอ่านครั้งเดียวเท่านั้น
- reactToPaste สามาถเลือกได้ว่าจะให้ทำงานร่วมกับ ctrl + v (true/false) สามารถกำหนดได้
- callback (keyCodeMapper ) เมื่อต้องการแทนค่าแต่ละวันอักษร โดยจะตรวจสอบ event.which ของ javascript event (ข่วยผมแก้ปัญหาเรื่องใหญ่ ๆ ของคนเริ่มใช้งาน onscan-js ได้ดีเลย เดี่ยวจะกล่าวในส่วนถัด ๆ ไป)
การติดตั้ง onscan-js
- ติดตั้งผ่าน npm install onscan.js หรือ bower install onscan-js หรือโคลน repo GitHub อย่างเป็นทางการ
- import onscan.min.js ไว้ในสคริปต์
- เพิ่มสคริปต์เริ่มต้นต่อไปนี้ที่ใดก็ได้ โดยที่สคริปต์จะทำงานเมื่อโหลดหน้าเว็บ (เช่น ที่ส่วนท้ายของ JavaScript อื่นๆ ของคุณรวมอยู่ด้วย)
- ลองใช้ตัวเลือกต่างๆ ในนี้ onscan-js playground
// Enable scan events for the entire document
onScan.attachTo(document);
// Register event listener
document.addEventListener('scan', function(sScancode, iQuatity) {
alert(iQuantity + 'x ' + sScancode);
});
โค๊ดในส่วนที่ผมลองเอาไปใช้งาน
onScan.attachTo(document, {
// minLength: 12,
// suffixKeyCodes: [13], // enter-key expected at the end of a scan
// reactToPaste: true, // Compatibility to built-in scanners in paste-mode (as opposed to keyboard-mode)
onScan: function (sCode, iQty) {
// Alternative to document.addEventListener('scan')
console.log("Scanned: " + iQty + "x " + sCode);
on['onDetected'](sCode)
},
onKeyDetect: function (iKeyCode) {
// output all potentially relevant key events - great for debugging!
// console.log("Pressed: " + iKeyCode);
},
keyCodeMapper: function(oEvent) {
// console.log(`oEvent.which ::==${oEvent.which}`)
// your hyphen-minus code is 45
if (KEYCODES.hasOwnProperty(oEvent.which)) {
return KEYCODES[oEvent.which]?.toUpperCase()
}
// Fall back to the default decoder in all other cases
return onScan.decodeKeyEvent(oEvent);
},
onScanError: function(oDebug){
if(on['onError']){
on['onError'](oDebug)
}
}
});
ปัญหาที่เจอเมื่อใช้งาน onscan-js
- ctrl-v มันจะตรวจสอบ หาก reactToPaste: true (แรก ๆ ผมกำหนดตรงนี้ มันน่าลำคาญมาก ผมก็เลย ไม่กำหนด หรือ reactToPaste: false ก็ได้
- onScanError ที่ให้มาถ้าอยากที่จะตรวจสอบ error ในระหว่าง scans มันจะทำงาน error นี้เยอะมาก ซึ่งไม่รู้ว่า onscan-js มองว่าอะไรคือ error
- ภาษาของเครื่อง client ภาษไทย/ภาษาอังกฤษ เมื่อตัวเครื่องเป็นภาษาอังกฤษ จะทำงานได้ปกติ แต่เมื่อเปลี่ยนภาษาเครื่องเป็นภาษไทย ค่าที่ได้จะเป็นค่าที่ไม่ถูกต้อง (ขอเอามาพูดในหัวข้อถัดไป)
จะทำงานได้ดีกับภาษเครื่อง English, Thai ทำงานผิดพลาด
จากข้อ 3. ข้างบน จะขออธิบาย เพิ่มเติม การที่บอกว่าทำงานผิดพลาดตอนภาษเครื่องเป็น Thai มันคือเวลา onscan-js ทำงาน ก็เหมือนการกดปุ่มคีย์บอร์ด ตอนที่เครื่องเป็นภาษไทย จะได้ค่าที่ได้ตามปุ่มคีย์บอร์ดของตัวอักษรไทย นั้น ๆ เช่น เลข 0 แทนที่จะได้ 0 ก็ได้ จ (จอจาน) แทน
แรก ๆ วิธีแก้ของผมคือตรวจสอบ regular expression ค่า /^[a-z0-9]+$/i เพื่อตรวจสอบข้อความที่เป็นตัวเลข และตัวอักษร และถ้าไม่ใช่ค่าเหล่านี้จะ ทำการแจ้งให้ user ใช้งานทราบว่าเครื่องของคุณเป็นภาษาไทย ให้ทำการเปลี่ยนภาษอังกฤษก่อน เบื้องต้น
*** แต่ในความเป็นจริง user จะทำงานไม่สะดวก เมื่อต้องเปลี่ยนภาษาของเครื่องเขาเองเมื่อต้องใช้งานกับภาษาไทยเป็นหลัก เรื่องนี้เลยต้องหาวิธีแก้แบบเร่งด่วน
การแก้ปัญหาเรื่อง English/Thai แบบถาวร (คิดว่ามันแก้ได้นะ)
ถ้าย้อนไปนึงความสามารถของ onscan-js อย่างนึงคือ callback (keyCodeMapper) ที่ทำหน้าที่ปรับเปลี่ยนแก้ไขอักษรค่าแต่ละอักษรได้ระหว่าง onscan-js ทำงานอยู่
const KEYCODES = {"48":"0","49":"1","50":"2","51":"3","52":"4","53":"5","54":"6","55":"7","56":"8","57":"9","65":"a","66":"b","67":"c","68":"d","69":"e","70":"f","71":"g","72":"h","73":"i","74":"j","75":"k","76":"l","77":"m","78":"n","79":"o","80":"p","81":"q","82":"r","83":"s","84":"t","85":"u","86":"v","87":"w","88":"x","89":"y","90":"z"}
keyCodeMapper: function(oEvent) {
// console.log(`oEvent.which ::==${oEvent.which}`)
// your hyphen-minus code is 45
if (KEYCODES.hasOwnProperty(oEvent.which)) {
return KEYCODES[oEvent.which]?.toUpperCase()
}
// Fall back to the default decoder in all other cases
return onScan.decodeKeyEvent(oEvent);
},
อธิบายการทำงาน ผมจะใส่เงื่อนไขว่าถ้า event.which มีอยู่ใน KEYCODES ผมจะแทนค่านั้นด้วยค่าของ KEYCODES แทน แต่ถ้าไม่มีใน KEYCODES ก็ให้ทำงานแบบเดิม ที่ละตัวอักษร
สรุปท้ายบทความ
onscan-js สำหรับผมตอนนี้ใช้งานได้ดี ยังไม่พบปัญหาอื่น ๆ เพิ่มเติม ยังคงจะใช้งานต่อไป ถ้าไปส่อง github star จะมีประมาณ 200+ ถือว่าไม่เยอะ แต่ก็ไม่ได้แย่ สำหรับมือใหม่แบบผม ถ้าเริ่มศึกษาเรื่องเกียวกับการอ่านบาร์โค๊ด search engine จะแนะนำ QR reader ทีเป็นแบบเปิดกล้องของ device แทน อาจจะไม่ค่อยตรงกับความต้องการสักเท่าไหร่ (หรือผมค้นหาด้วย keyword ไม่ตรงเองหว่า) สำหรับบทความนี้ ฝากไว้เท่านี้ครับ