Add ability to add transaction items using barcode scanner
This commit is contained in:
@ -13,6 +13,10 @@ export default class ModalController extends Controller {
|
||||
if (!this.element.open) {
|
||||
return;
|
||||
}
|
||||
if (event.type === "turbo:submit-end" && (event.detail.formSubmission.method === 0 || !event.detail.success)) {
|
||||
// Don't close modal if form method was GET or submission failed
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
|
@ -1,7 +1,26 @@
|
||||
import { Controller } from "/lib/hotwired/stimulus/dist/stimulus.js";
|
||||
|
||||
export default class TransactionItemFormController extends Controller {
|
||||
static targets = ["option", "price", "quantity"];
|
||||
static targets = ["barcodeButton", "barcodeData", "barcodeFormat", "barcodeFormField", "brand", "option", "price", "quantity"];
|
||||
|
||||
#scanning = false;
|
||||
#scanIntervalId;
|
||||
#stream;
|
||||
|
||||
connect() {
|
||||
if ('BarcodeDetector' in globalThis) {
|
||||
this.barcodeFormFieldTarget.hidden = false;
|
||||
if (this.barcodeDataTarget.value) {
|
||||
this.brandTarget.autofocus = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
this.barcodeFormFieldTarget.hidden = true;
|
||||
this.brandTarget.autofocus = true;
|
||||
this.stopScanning();
|
||||
}
|
||||
|
||||
filterNames(event) {
|
||||
for (const option of this.optionTargets) {
|
||||
@ -36,4 +55,54 @@ export default class TransactionItemFormController extends Controller {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async scanBarcode(event) {
|
||||
event?.preventDefault();
|
||||
|
||||
if (this.#scanning) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.#scanning = true;
|
||||
this.barcodeDataTarget.value = "";
|
||||
this.barcodeFormatTarget.value = "";
|
||||
|
||||
this.#stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" } });
|
||||
|
||||
const video = document.createElement("video");
|
||||
video.srcObject = this.#stream;
|
||||
await video.play();
|
||||
|
||||
const detector = new BarcodeDetector();
|
||||
|
||||
this.#scanIntervalId = setInterval(async () => {
|
||||
const barcodes = await detector.detect(video);
|
||||
if (barcodes.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const barcode = barcodes[0];
|
||||
this.barcodeDataTarget.value = barcode.rawValue;
|
||||
this.barcodeFormatTarget.value = barcode.format;
|
||||
|
||||
this.stopScanning();
|
||||
|
||||
const form = this.element.closest("form");
|
||||
for (const element of form.elements) {
|
||||
element.disabled = !element.name.startsWith("barcode");
|
||||
}
|
||||
|
||||
form.requestSubmit(this.barcodeButtonTarget);
|
||||
}, 250);
|
||||
}
|
||||
|
||||
stopScanning() {
|
||||
if (this.#scanning) {
|
||||
this.#stream?.getTracks()
|
||||
.forEach(track => track.stop());
|
||||
|
||||
clearInterval(this.#scanIntervalId);
|
||||
this.#scanning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user