summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorAkash Bhavsar <abh@odoo.com>2017-06-26 17:24:01 +0530
committerAaron Bohy <aab@odoo.com>2017-08-25 15:54:56 +0200
commitb131e9b0ef458e8cc00b0a2eb6c1b4d8dfe889a0 (patch)
tree51589b025dffc424e6e67dfac5c11a35fe88ea42 /addons
parent7095c32f1cd17a86606e4137ece8baa3034fe74a (diff)
[FIX] barcodes: fix several issues when scanning barcodes
Since the new views, most of the barcodes feature was broken. This commit re-enables the support of commands like 'edit', 'save', 'cancel', 'previous' and 'next'. Also changed javascript event handler to jquery event handler to make barcodes testable in phantomjs.
Diffstat (limited to 'addons')
-rw-r--r--addons/barcodes/static/src/js/barcode_events.js22
-rw-r--r--addons/barcodes/static/src/js/barcode_field.js2
-rw-r--r--addons/barcodes/static/src/js/barcode_form_view.js55
-rw-r--r--addons/barcodes/static/tests/barcode_tests.js121
-rw-r--r--addons/barcodes/views/barcodes_templates.xml6
-rw-r--r--addons/web/static/tests/helpers/test_utils.js15
6 files changed, 197 insertions, 24 deletions
diff --git a/addons/barcodes/static/src/js/barcode_events.js b/addons/barcodes/static/src/js/barcode_events.js
index 04c03a41308..0f13c59fe66 100644
--- a/addons/barcodes/static/src/js/barcode_events.js
+++ b/addons/barcodes/static/src/js/barcode_events.js
@@ -77,13 +77,7 @@ var BarcodeEvents = core.Class.extend(mixins.PropertiesMixin, {
'bubbles': old_event.bubbles,
'cancelable': old_event.cancelable,
};
- try {
- new_event = new Event("keypress", params);
- } catch(error) {
- // For IE >= 9, use new CustomEvent(), instead of new Event()
- new_event = new CustomEvent("keypress", params);
- }
-
+ new_event = $.Event('keypress', params);
new_event.viewArg = old_event.viewArg;
new_event.ctrl = old_event.ctrl;
new_event.alt = old_event.alt;
@@ -96,7 +90,7 @@ var BarcodeEvents = core.Class.extend(mixins.PropertiesMixin, {
new_event.which = old_event.which;
new_event.dispatched_by_barcode_reader = true;
- old_event.target.dispatchEvent(new_event);
+ $(old_event.target).trigger(new_event);
}
}
},
@@ -173,17 +167,17 @@ var BarcodeEvents = core.Class.extend(mixins.PropertiesMixin, {
},
start: function(prevent_key_repeat){
- document.body.addEventListener('keypress', this.__handler, true);
+ $('body').bind("keypress", this.__handler);
if (prevent_key_repeat === true) {
- document.body.addEventListener('keydown', this.__keydown_handler, true);
- document.body.addEventListener('keyup', this.__keyup_handler, true);
+ $('body').bind("keydown", this.__keydown_handler);
+ $('body').bind('keyup', this.__keyup_handler);
}
},
stop: function(){
- document.body.removeEventListener('keypress', this.__handler, true);
- document.body.removeEventListener('keydown', this.__keydown_handler, true);
- document.body.removeEventListener('keyup', this.__keyup_handler, true);
+ $('body').unbind("keypress", this.__handler);
+ $('body').unbind("keydown", this.__keydown_handler);
+ $('body').unbind('keyup', this.__keyup_handler);
},
});
diff --git a/addons/barcodes/static/src/js/barcode_field.js b/addons/barcodes/static/src/js/barcode_field.js
index aa31b4d8261..9b0f2391e3a 100644
--- a/addons/barcodes/static/src/js/barcode_field.js
+++ b/addons/barcodes/static/src/js/barcode_field.js
@@ -40,7 +40,7 @@ var FieldFloatScannable = basicFields.FieldFloat.extend({
*/
_onKeypress: function (e) {
/* only simulate a keypress if it has been previously prevented */
- if (e.originalEvent.dispatched_by_barcode_reader !== true) {
+ if (e.dispatched_by_barcode_reader !== true) {
e.preventDefault();
this.$input.blur();
return;
diff --git a/addons/barcodes/static/src/js/barcode_form_view.js b/addons/barcodes/static/src/js/barcode_form_view.js
index 69a59fdaafa..37fa34dcf95 100644
--- a/addons/barcodes/static/src/js/barcode_form_view.js
+++ b/addons/barcodes/static/src/js/barcode_form_view.js
@@ -26,19 +26,21 @@ FormController.include({
this.activeBarcode = {
form_view: {
commands: {
- 'O-CMD.NEW': 'createRecord',
- 'O-CMD.EDIT': 'toEditMode',
- 'O-CMD.CANCEL': 'discardChange',
- 'O-CMD.SAVE': function () { return this.saveRecord({reload: true}); },
- // 'O-CMD.PAGER-PREV':
- // 'O-CMD.PAGER-NEXT':
- }
- }
+ 'O-CMD.EDIT': this._onEdit.bind(this),
+ 'O-CMD.CANCEL': this._onDiscard.bind(this),
+ 'O-CMD.SAVE': this._onCommandSave.bind(this),
+ 'O-CMD.PAGER-PREV': this._onCommandPrevious.bind(this),
+ 'O-CMD.PAGER-NEXT': this._onCommandNext.bind(this),
+ },
+ },
};
this.barcodeMutex = new concurrency.Mutex();
this._barcodeStartListening();
},
+ /**
+ * @override
+ */
destroy: function () {
this._barcodeStopListening();
this._super();
@@ -70,6 +72,8 @@ FormController.include({
}
},
/**
+ * Returns true iff the given barcode matches the given record (candidate).
+ *
* @private
* @param {Object} candidate: record in the x2m
* @param {string} barcode sent by the scanner (string generate from keypress series)
@@ -128,7 +132,7 @@ FormController.include({
*/
_getBarCodeRecord: function (record, barcode, activeBarcode) {
var self = this;
- if (!activeBarcode.fieldName) {
+ if (!activeBarcode.fieldName || !record.data[activeBarcode.fieldName]) {
return;
}
return _.find(record.data[activeBarcode.fieldName].data, function (record) {
@@ -239,6 +243,24 @@ FormController.include({
},
/**
* @private
+ */
+ _onCommandNext: function () {
+ return this.mutex.exec(function () {}).then(this.pager.next.bind(this.pager));
+ },
+ /**
+ * @private
+ */
+ _onCommandPrevious: function () {
+ return this.mutex.exec(function () {}).then(this.pager.previous.bind(this.pager));
+ },
+ /**
+ * @private
+ */
+ _onCommandSave: function () {
+ return this.saveRecord();
+ },
+ /**
+ * @private
* @param {KeyEvent} event
*/
_quantityListener: function (event) {
@@ -359,6 +381,21 @@ FormRenderer.include({
}
return $button;
},
+ /**
+ * Add barcode event handler
+ *
+ * @override
+ * @private
+ * @param {Object} node
+ * @returns {jQueryElement}
+ */
+ _renderTagButton: function (node) {
+ var $button = this._super.apply(this, arguments);
+ if (node.attrs.barcode_trigger) {
+ this._barcodeButtonHandler($button, node);
+ }
+ return $button;
+ }
});
BarcodeEvents.ReservedBarcodePrefixes.push('O-BTN');
diff --git a/addons/barcodes/static/tests/barcode_tests.js b/addons/barcodes/static/tests/barcode_tests.js
new file mode 100644
index 00000000000..09daebcd976
--- /dev/null
+++ b/addons/barcodes/static/tests/barcode_tests.js
@@ -0,0 +1,121 @@
+odoo.define('barcodes.tests', function (require) {
+"use strict";
+
+var testUtils = require('web.test_utils');
+var FormView = require('web.FormView');
+
+var createView = testUtils.createView;
+var triggerKeypressEvent = testUtils.triggerKeypressEvent;
+
+QUnit.module('Barcodes', {
+ beforeEach: function () {
+ this.data = {
+ product: {
+ fields: {
+ name: {string : "Product name", type: "char"},
+ },
+ records: [
+ {id: 1, name: "iPad Mini"},
+ {id: 2, name: "Mouse, Optical"},
+ ],
+ },
+ };
+ }
+});
+
+QUnit.test('Button with barcode_trigger', function (assert) {
+ assert.expect(1);
+
+ var form = createView({
+ View: FormView,
+ model: 'product',
+ data: this.data,
+ arch: '<form>' +
+ '<header>' +
+ '<button name="do_something" string="Validate" type="object" barcode_trigger="doit"/>' +
+ '</header>' +
+ '</form>',
+ res_id: 2,
+ intercepts: {
+ execute_action: function (event) {
+ assert.strictEqual(event.data.action_data.name, 'do_something',
+ "do_something method call verified");
+ },
+ },
+ });
+
+ // O-BTN.doit
+ _.each(['O','-','B','T','N','.','d','o','i','t','Enter'], triggerKeypressEvent);
+
+ form.destroy();
+});
+
+QUnit.test('edit, save and cancel buttons', function (assert) {
+ assert.expect(6);
+
+ var form = createView({
+ View: FormView,
+ model: 'product',
+ data: this.data,
+ arch: '<form><field name="display_name"/></form>',
+ mockRPC: function (route, args) {
+ if (args.method === 'write') {
+ assert.step('save');
+ }
+ return this._super.apply(this, arguments);
+ },
+ res_id: 1,
+ });
+
+ // O-CMD.EDIT
+ _.each(["O","-","C","M","D",".","E","D","I","T","Enter"], triggerKeypressEvent);
+ assert.strictEqual(form.$(".o_form_editable").length, 1,
+ "should have switched to 'edit' mode");
+ // dummy change to check that it actually saves
+ form.$('.o_field_widget').val('test').trigger('input');
+ // O-CMD.SAVE
+ _.each(["O","-","C","M","D",".","S","A","V","E","Enter"], triggerKeypressEvent);
+ assert.strictEqual(form.$(".o_form_readonly").length, 1,
+ "should have switched to 'readonly' mode");
+ assert.verifySteps(['save'], 'should have saved');
+
+ // O-CMD.EDIT
+ _.each(["O","-","C","M","D",".","E","D","I","T","Enter"], triggerKeypressEvent);
+ // dummy change to check that it correctly discards
+ form.$('.o_field_widget').val('test').trigger('input');
+ // O-CMD.CANCEL
+ _.each(["O","-","C","M","D",".","C","A","N","C","E","L","Enter"], triggerKeypressEvent);
+ assert.strictEqual(form.$(".o_form_readonly").length, 1,
+ "should have switched to 'readonly' mode");
+ assert.verifySteps(['save'], 'should not have saved');
+
+ form.destroy();
+});
+
+QUnit.test('pager buttons', function (assert) {
+ assert.expect(3);
+
+ var form = createView({
+ View: FormView,
+ model: 'product',
+ data: this.data,
+ arch: '<form><field name="display_name"/></form>',
+ res_id: 1,
+ viewOptions: {
+ ids: [1, 2],
+ index: 0,
+ },
+ });
+
+ assert.strictEqual(form.$('.o_field_widget').text(), 'iPad Mini');
+ // O-CMD.PAGER-NEXT
+ _.each(["O","-","C","M","D",".","P","A","G","E","R","-","N","E","X","T","Enter"], triggerKeypressEvent);
+ assert.strictEqual(form.$('.o_field_widget').text(), 'Mouse, Optical');
+ // O-CMD.PAGER-PREV
+ _.each(["O","-","C","M","D",".","P","A","G","E","R","-","P","R","E","V","Enter"], triggerKeypressEvent);
+ assert.strictEqual(form.$('.o_field_widget').text(), 'iPad Mini');
+
+ form.destroy();
+});
+
+});
diff --git a/addons/barcodes/views/barcodes_templates.xml b/addons/barcodes/views/barcodes_templates.xml
index 420a069a491..cb16a40c178 100644
--- a/addons/barcodes/views/barcodes_templates.xml
+++ b/addons/barcodes/views/barcodes_templates.xml
@@ -10,4 +10,10 @@
</xpath>
</template>
+ <template id="qunit_suite" name="barcode_tests" inherit_id="web.qunit_suite">
+ <xpath expr="//t[@t-set='head']" position="inside">
+ <script type="text/javascript" src="/barcodes/static/tests/barcode_tests.js"/>
+ </xpath>
+ </template>
+
</odoo>
diff --git a/addons/web/static/tests/helpers/test_utils.js b/addons/web/static/tests/helpers/test_utils.js
index 0115dfc9152..f7003faaf5c 100644
--- a/addons/web/static/tests/helpers/test_utils.js
+++ b/addons/web/static/tests/helpers/test_utils.js
@@ -458,6 +458,20 @@ function triggerPositionalMouseEvent(x, y, type){
}
/**
+ * simulate a keypress event for a given character
+ * @param {string} the character
+ */
+function triggerKeypressEvent(char) {
+ var keycode;
+ if (char === "Enter") {
+ keycode = $.ui.keyCode.ENTER;
+ } else {
+ keycode = char.charCodeAt(0);
+ }
+ return $('body').trigger($.Event('keypress', {which: keycode, keyCode: keycode}));
+}
+
+/**
* Removes the src attribute on images and iframes to prevent not found errors,
* and optionally triggers an rpc with the src url as route on a widget.
*
@@ -498,6 +512,7 @@ return session.is_bound.then(function () {
dragAndDrop: dragAndDrop,
triggerMouseEvent: triggerMouseEvent,
triggerPositionalMouseEvent: triggerPositionalMouseEvent,
+ triggerKeypressEvent: triggerKeypressEvent,
removeSrcAttribute: removeSrcAttribute,
};
});