mirror of
https://github.com/grocy/grocy.git
synced 2025-08-20 04:12:59 +00:00
Implemented browser barcode scanning (closes #102)
This commit is contained in:
@@ -289,3 +289,11 @@ html {
|
||||
.tooltip {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Third party component customizations - QuaggaJS */
|
||||
canvas.drawing,
|
||||
canvas.drawingBuffer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
@@ -191,12 +191,12 @@ $("#consume_product_on_execution").on("click", function()
|
||||
{
|
||||
if (this.checked)
|
||||
{
|
||||
Grocy.Components.ProductPicker.GetInputElement().removeAttr("disabled");
|
||||
Grocy.Components.ProductPicker.Enable();
|
||||
$("#product_amount").removeAttr("disabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
Grocy.Components.ProductPicker.GetInputElement().attr("disabled", "");
|
||||
Grocy.Components.ProductPicker.Disable();
|
||||
$("#product_amount").attr("disabled", "");
|
||||
}
|
||||
|
||||
|
151
public/viewjs/components/barcodescanner.js
Normal file
151
public/viewjs/components/barcodescanner.js
Normal file
@@ -0,0 +1,151 @@
|
||||
Grocy.Components.BarcodeScanner = { };
|
||||
|
||||
Grocy.Components.BarcodeScanner.StartScanning = function()
|
||||
{
|
||||
Quagga.init({
|
||||
inputStream: {
|
||||
name: "Live",
|
||||
type: "LiveStream",
|
||||
target: document.querySelector("#barcodescanner-livestream"),
|
||||
constraints: {
|
||||
width: 436,
|
||||
height: 327,
|
||||
facingMode: "environment"
|
||||
}
|
||||
},
|
||||
locator: {
|
||||
patchSize: "medium",
|
||||
halfSample: false,
|
||||
debug: {
|
||||
showCanvas: true,
|
||||
showPatches: true,
|
||||
showFoundPatches: true,
|
||||
showSkeleton: true,
|
||||
showLabels: true,
|
||||
showPatchLabels: true,
|
||||
showRemainingPatchLabels: true,
|
||||
boxFromPatches: {
|
||||
showTransformed: true,
|
||||
showTransformedBox: true,
|
||||
showBB: true
|
||||
}
|
||||
}
|
||||
},
|
||||
numOfWorkers: 2,
|
||||
frequency: 10,
|
||||
decoder: {
|
||||
readers: [
|
||||
"code_128_reader",
|
||||
"ean_reader",
|
||||
"ean_8_reader",
|
||||
"code_39_reader",
|
||||
"code_39_vin_reader",
|
||||
"codabar_reader",
|
||||
"upc_reader",
|
||||
"upc_e_reader",
|
||||
"i2of5_reader"
|
||||
],
|
||||
debug: {
|
||||
showCanvas: true,
|
||||
showPatches: true,
|
||||
showFoundPatches: true,
|
||||
showSkeleton: true,
|
||||
showLabels: true,
|
||||
showPatchLabels: true,
|
||||
showRemainingPatchLabels: true,
|
||||
boxFromPatches: {
|
||||
showTransformed: true,
|
||||
showTransformedBox: true,
|
||||
showBB: true
|
||||
}
|
||||
}
|
||||
},
|
||||
locate: true
|
||||
}, function(error)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
Grocy.FrontendHelpers.ShowGenericError("Error while initializing the barcode scanning library", error.message);
|
||||
return;
|
||||
}
|
||||
Quagga.start();
|
||||
});
|
||||
}
|
||||
|
||||
Grocy.Components.BarcodeScanner.StopScanning = function()
|
||||
{
|
||||
Quagga.stop();
|
||||
bootbox.hideAll();
|
||||
}
|
||||
|
||||
Quagga.onDetected(function(result)
|
||||
{
|
||||
Grocy.Components.BarcodeScanner.StopScanning();
|
||||
$(document).trigger("Grocy.BarcodeScanned", [result.codeResult.code]);
|
||||
});
|
||||
|
||||
Quagga.onProcessed(function(result)
|
||||
{
|
||||
var drawingCtx = Quagga.canvas.ctx.overlay;
|
||||
var drawingCanvas = Quagga.canvas.dom.overlay;
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (result.boxes)
|
||||
{
|
||||
drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height")));
|
||||
result.boxes.filter(function(box)
|
||||
{
|
||||
return box !== result.box;
|
||||
}).forEach(function(box)
|
||||
{
|
||||
Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, { color: "green", lineWidth: 4 });
|
||||
});
|
||||
}
|
||||
|
||||
if (result.box)
|
||||
{
|
||||
Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, { color: "yellow", lineWidth: 4 });
|
||||
}
|
||||
|
||||
if (result.codeResult && result.codeResult.code)
|
||||
{
|
||||
Quagga.ImageDebug.drawPath(result.line, { x: 'x', y: 'y' }, drawingCtx, { color: "red", lineWidth: 4 });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on("click", "#barcodescanner-start-button", function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
bootbox.dialog({
|
||||
message: '<div id="barcodescanner-container" class="col"><div id="barcodescanner-livestream"></div></div>',
|
||||
title: __t('Scan a barcode'),
|
||||
onEscape: function()
|
||||
{
|
||||
Grocy.Components.BarcodeScanner.StopScanning();
|
||||
},
|
||||
size: 'big',
|
||||
backdrop: true,
|
||||
buttons: {
|
||||
cancel: {
|
||||
label: __t('Cancel'),
|
||||
className: 'btn-secondary responsive-button',
|
||||
callback: function()
|
||||
{
|
||||
Grocy.Components.BarcodeScanner.StopScanning();
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
Grocy.Components.BarcodeScanner.StartScanning();
|
||||
});
|
||||
|
||||
|
||||
setTimeout(function()
|
||||
{
|
||||
$(".barcodescanner-input:visible").after('<a id="barcodescanner-start-button" class="btn btn-sm btn-primary text-white" style="position: absolute; right: 0; margin-top: 4px; margin-right: 36px; z-index: 1000;"><i class="fas fa-camera"></i></a>');
|
||||
}, 50);
|
@@ -56,6 +56,20 @@ Grocy.Components.ProductPicker.HideCustomError = function()
|
||||
$("#custom-productpicker-error").addClass("d-none");
|
||||
}
|
||||
|
||||
Grocy.Components.ProductPicker.Disable = function()
|
||||
{
|
||||
Grocy.Components.ProductPicker.GetInputElement().attr("disabled", "");
|
||||
$("#barcodescanner-start-button").attr("disabled", "");
|
||||
$("#barcodescanner-start-button").addClass("disabled");
|
||||
}
|
||||
|
||||
Grocy.Components.ProductPicker.Enable = function()
|
||||
{
|
||||
Grocy.Components.ProductPicker.GetInputElement().removeAttr("disabled");
|
||||
$("#barcodescanner-start-button").removeAttr("disabled");
|
||||
$("#barcodescanner-start-button").removeClass("disabled");
|
||||
}
|
||||
|
||||
$('.product-combobox').combobox({
|
||||
appendId: '_text_input',
|
||||
bsVersion: '4',
|
||||
@@ -211,3 +225,21 @@ $('#product_id_text_input').on('blur', function(e)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on("Grocy.BarcodeScanned", function(e, barcode)
|
||||
{
|
||||
// Don't know why the blur event does not fire immediately ... this works...
|
||||
|
||||
Grocy.Components.ProductPicker.GetInputElement().focusout();
|
||||
Grocy.Components.ProductPicker.GetInputElement().focus();
|
||||
Grocy.Components.ProductPicker.GetInputElement().blur();
|
||||
|
||||
Grocy.Components.ProductPicker.GetInputElement().val(barcode);
|
||||
|
||||
setTimeout(function()
|
||||
{
|
||||
Grocy.Components.ProductPicker.GetInputElement().focusout();
|
||||
Grocy.Components.ProductPicker.GetInputElement().focus();
|
||||
Grocy.Components.ProductPicker.GetInputElement().blur();
|
||||
}, 200);
|
||||
});
|
||||
|
Reference in New Issue
Block a user