[ADD] stock_barcode: field widget with barcodes scan + manual input
Barcodes are detected by catching keypresses. When a keypress is not part of a barcode, it is 'released' by forging a keypress event. For security reasons, a non-native keypress doesn't trigger the native input mechanism. So in order to make both barcode-scanning and manual keypresses work in a field, it is necessary to have a handler listen to the 'false' keypresses and simulate the native input behaviour.
This commit is contained in:
committed by
Simon Lejeune
parent
27e237346d
commit
cdb30b507a
@@ -0,0 +1,46 @@
|
||||
odoo.define('barcodes.FieldFloatScannable', function(require) {
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var form_widgets = require('web.form_widgets');
|
||||
|
||||
// Field in which the user can both type normally and scan barcodes
|
||||
|
||||
var FieldFloatScannable = form_widgets.FieldFloat.extend({
|
||||
events: {
|
||||
// The barcode_events component intercepts keypresses and releases them when it
|
||||
// appears they are not part of a barcode. But since released keypresses don't
|
||||
// trigger native behaviour (like characters input), we must simulate it.
|
||||
'keypress': 'simulateKeypress',
|
||||
},
|
||||
|
||||
simulateKeypress: function (e) {
|
||||
var character = String.fromCharCode(e.which);
|
||||
var current_str = e.target.value;
|
||||
var str_before_carret = current_str.substring(0, e.target.selectionStart);
|
||||
var str_after_carret = current_str.substring(e.target.selectionEnd);
|
||||
e.target.value = str_before_carret + character + str_after_carret;
|
||||
var new_carret_index = str_before_carret.length + character.length;
|
||||
e.target.setSelectionRange(new_carret_index, new_carret_index);
|
||||
// Note: FieldChar (that FieldFloat extends) calls store_dom_value upon change
|
||||
// event, which is triggered when the input loses focus and its internal dirty
|
||||
// flag is set. But here, we directly modify the value property of the input,
|
||||
// which doesn't set the dirty flag. So we could call store_dom_value upon blur.
|
||||
// But we also want the DOM value to be stored when a barcode_event occurs and
|
||||
// triggers an onchange. We could listen to barcode_event in order to call
|
||||
// store_dom_value, but that would have to happen before the onchange is triggered.
|
||||
// So the safest method is still to store the value each time it changes.
|
||||
// This long explanation is here to avoid having to do the thinking all over agan
|
||||
// in case this strategy doesn't work / breaks.
|
||||
// TL;DR Safest way not to lose the value when a barcode scan triggers an onchange.
|
||||
this.store_dom_value();
|
||||
},
|
||||
});
|
||||
|
||||
core.form_widget_registry.add('field_float_scannable', FieldFloatScannable);
|
||||
|
||||
return {
|
||||
FieldFloatScannable: FieldFloatScannable,
|
||||
};
|
||||
|
||||
});
|
||||
@@ -9,6 +9,7 @@
|
||||
<script type="text/javascript" src="/barcodes/static/src/js/barcode_handler_mixin.js"></script>
|
||||
<script type="text/javascript" src="/barcodes/static/src/js/form_view_barcode_handler.js"></script>
|
||||
<script type="text/javascript" src="/barcodes/static/src/js/inherited_form_widget_button.js"></script>
|
||||
<script type="text/javascript" src="/barcodes/static/src/js/field_float_scannable.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1663,6 +1663,7 @@ core.form_tag_registry.add('button', WidgetButton);
|
||||
|
||||
return {
|
||||
FieldChar: FieldChar,
|
||||
FieldFloat: FieldFloat,
|
||||
FieldMonetary: FieldMonetary,
|
||||
WidgetButton: WidgetButton
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user