diff --git a/web_widget_dropdown_dynamic/__manifest__.py b/web_widget_dropdown_dynamic/__manifest__.py index 8ede2ec51..8a47e74b2 100644 --- a/web_widget_dropdown_dynamic/__manifest__.py +++ b/web_widget_dropdown_dynamic/__manifest__.py @@ -1,20 +1,14 @@ # Copyright 2019 Brainbean Apps (https://brainbeanapps.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). { - 'name': 'Dynamic Dropdown Widget', - 'summary': 'This module adds support for dynamic dropdown widget', - 'category': 'Web', - 'version': '12.0.1.0.0', - 'license': 'AGPL-3', - 'author': - 'Brainbean Apps OU, ' - 'Odoo Community Association (OCA)', - 'website': 'https://github.com/OCA/web/', - 'depends': [ - 'web', - ], - 'data': [ - 'templates/assets.xml', - ], - 'installable': True, + "name": "Dynamic Dropdown Widget", + "summary": "This module adds support for dynamic dropdown widget", + "category": "Web", + "version": "12.0.1.0.0", + "license": "AGPL-3", + "author": "Brainbean Apps OU, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/web/", + "depends": ["web"], + "data": ["templates/assets.xml"], + "installable": True, } diff --git a/web_widget_dropdown_dynamic/static/src/js/basic_model.js b/web_widget_dropdown_dynamic/static/src/js/basic_model.js index a059366ba..dbdfb4f23 100644 --- a/web_widget_dropdown_dynamic/static/src/js/basic_model.js +++ b/web_widget_dropdown_dynamic/static/src/js/basic_model.js @@ -1,11 +1,11 @@ -/* +/* * Copyright 2019 Brainbean Apps (https://brainbeanapps.com) * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). */ -odoo.define('web_widget_dropdown_dynamic.basic_model', function (require) { +odoo.define("web_widget_dropdown_dynamic.basic_model", function(require) { "use strict"; - var BasicModel = require('web.BasicModel'); + var BasicModel = require("web.BasicModel"); BasicModel.include({ /** @@ -20,7 +20,7 @@ odoo.define('web_widget_dropdown_dynamic.basic_model', function (require) { * (for the given parameters), no RPC is done and the promise * is resolved with the undefined value. */ - _fetchDynamicDropdownValues: function (record, fieldName, fieldInfo) { + _fetchDynamicDropdownValues: function(record, fieldName, fieldInfo) { var model = fieldInfo.options.model || record.model; var method = fieldInfo.values || fieldInfo.options.values; if (!method) { @@ -29,7 +29,7 @@ odoo.define('web_widget_dropdown_dynamic.basic_model', function (require) { var context = record.getContext({fieldName: fieldName}); - // avoid rpc if not necessary + // Avoid rpc if not necessary var hasChanged = this._saveSpecialDataCache(record, fieldName, { context: context, }); diff --git a/web_widget_dropdown_dynamic/static/src/js/field_dynamic_dropdown.js b/web_widget_dropdown_dynamic/static/src/js/field_dynamic_dropdown.js index 0a9443127..987793ba5 100644 --- a/web_widget_dropdown_dynamic/static/src/js/field_dynamic_dropdown.js +++ b/web_widget_dropdown_dynamic/static/src/js/field_dynamic_dropdown.js @@ -1,47 +1,47 @@ -/* +/* * Copyright 2019 Brainbean Apps (https://brainbeanapps.com) * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). */ -odoo.define('web_widget_dropdown_dynamic.field_dynamic_dropdown', function (require) { +odoo.define("web_widget_dropdown_dynamic.field_dynamic_dropdown", function(require) { "use strict"; - var core = require('web.core'); - var AbstractField = require('web.AbstractField'); - var field_registry = require('web.field_registry'); + var core = require("web.core"); + var AbstractField = require("web.AbstractField"); + var field_registry = require("web.field_registry"); var _lt = core._lt; var FieldDynamicDropdown = AbstractField.extend({ - description: _lt('Dynamic Dropdown'), - template: 'FieldSelection', - specialData: '_fetchDynamicDropdownValues', - supportedFieldTypes: ['selection', 'char', 'integer'], + description: _lt("Dynamic Dropdown"), + template: "FieldSelection", + specialData: "_fetchDynamicDropdownValues", + supportedFieldTypes: ["selection", "char", "integer"], events: _.extend({}, AbstractField.prototype.events, { - 'change': '_onChange', + change: "_onChange", }), /** * @override */ - init: function () { + init: function() { this._super.apply(this, arguments); this._setValues(); }, - - //-------------------------------------------------------------------------- + + // -------------------------------------------------------------------------- // Public - //-------------------------------------------------------------------------- - + // -------------------------------------------------------------------------- + /** * @override * @returns {jQuery} */ - getFocusableElement: function () { - return this.$el.is('select') ? this.$el : $(); + getFocusableElement: function() { + return this.$el.is("select") ? this.$el : $(); }, /** * @override */ - isSet: function () { + isSet: function() { return this.value !== false; }, /** @@ -50,25 +50,30 @@ odoo.define('web_widget_dropdown_dynamic.field_dynamic_dropdown', function (requ * * @override */ - updateModifiersValue: function () { + updateModifiersValue: function() { this._super.apply(this, arguments); - if (!this.attrs.modifiersValue.invisible && this.mode !== 'readonly') { + if (!this.attrs.modifiersValue.invisible && this.mode !== "readonly") { this._setValues(); this._renderEdit(); } }, - - //-------------------------------------------------------------------------- + + // -------------------------------------------------------------------------- // Private - //-------------------------------------------------------------------------- - + // -------------------------------------------------------------------------- + /** * @override * @private */ - _formatValue: function (value) { - var options = _.extend({}, this.nodeOptions, { data: this.recordData }, this.formatOptions); - var formattedValue = _.find(this.values, function (option) { + _formatValue: function(value) { + var options = _.extend( + {}, + this.nodeOptions, + {data: this.recordData}, + this.formatOptions + ); + var formattedValue = _.find(this.values, function(option) { return option[0] === value; }); if (!formattedValue) { @@ -84,13 +89,15 @@ odoo.define('web_widget_dropdown_dynamic.field_dynamic_dropdown', function (requ * @override * @private */ - _renderEdit: function () { + _renderEdit: function() { this.$el.empty(); - for (var i = 0 ; i < this.values.length ; i++) { - this.$el.append($('', { - value: JSON.stringify(this.values[i][0]), - text: this.values[i][1] - })); + for (var i = 0; i < this.values.length; i++) { + this.$el.append( + $("", { + value: JSON.stringify(this.values[i][0]), + text: this.values[i][1], + }) + ); } this.$el.val(JSON.stringify(this.value)); }, @@ -98,13 +105,13 @@ odoo.define('web_widget_dropdown_dynamic.field_dynamic_dropdown', function (requ * @override * @private */ - _renderReadonly: function () { + _renderReadonly: function() { this.$el.empty().text(this._formatValue(this.value)); }, /** * @override */ - _reset: function () { + _reset: function() { this._super.apply(this, arguments); this._setValues(); }, @@ -113,28 +120,30 @@ odoo.define('web_widget_dropdown_dynamic.field_dynamic_dropdown', function (requ * * @private */ - _setValues: function () { - this.values = _.reject(this.record.specialData[this.name], function (v) { - return v[0] === false && v[1] === ''; + _setValues: function() { + this.values = _.reject(this.record.specialData[this.name], function(v) { + return v[0] === false && v[1] === ""; }); if (!this.attrs.modifiersValue || !this.attrs.modifiersValue.required) { - this.values = [[false, this.attrs.placeholder || '']].concat(this.values); + this.values = [[false, this.attrs.placeholder || ""]].concat( + this.values + ); } }, - //-------------------------------------------------------------------------- + // -------------------------------------------------------------------------- // Handlers - //-------------------------------------------------------------------------- - + // -------------------------------------------------------------------------- + /** * @private */ - _onChange: function () { + _onChange: function() { var value = JSON.parse(this.$el.val()); this._setValue(value.toString()); }, }); - field_registry.add('dynamic_dropdown', FieldDynamicDropdown); + field_registry.add("dynamic_dropdown", FieldDynamicDropdown); return FieldDynamicDropdown; }); diff --git a/web_widget_dropdown_dynamic/static/tests/web_widget_dropdown_dynamic_tests.js b/web_widget_dropdown_dynamic/static/tests/web_widget_dropdown_dynamic_tests.js index f25ac6581..615534d79 100644 --- a/web_widget_dropdown_dynamic/static/tests/web_widget_dropdown_dynamic_tests.js +++ b/web_widget_dropdown_dynamic/static/tests/web_widget_dropdown_dynamic_tests.js @@ -1,147 +1,143 @@ -odoo.define('web_widget_dropdown_dynamic.web_widget_dropdown_dynamic_tests', function (require) { +odoo.define("web_widget_dropdown_dynamic.web_widget_dropdown_dynamic_tests", function( + require +) { "use strict"; - - var FormView = require('web.FormView'); - var testUtils = require('web.test_utils'); - QUnit.module('web_widget_dropdown_dynamic', {}, function () { + /* global QUnit*/ - QUnit.test('values are fetched w/o context (char)', async function (assert) { + var FormView = require("web.FormView"); + var testUtils = require("web.test_utils"); + + QUnit.module("web_widget_dropdown_dynamic", {}, function() { + QUnit.test("values are fetched w/o context (char)", async function(assert) { assert.expect(2); var form = await testUtils.createView({ View: FormView, - model: 'demo_entry', + model: "demo_entry", data: { demo_entry: { fields: { - test_field: {string: 'Test Field', type: 'char'}, + test_field: {string: "Test Field", type: "char"}, }, - records: [{id: 1, test_field: ''}], + records: [{id: 1, test_field: ""}], }, }, arch: - '
', - mockRPC: function (route, args) { - if (args.method === '_get_test_field_values') { - return $.when([ - ['value', 'Title'], - ]); + "", + mockRPC: function(route, args) { + if (args.method === "_get_test_field_values") { + return $.when([["value", "Title"]]); } return this._super.apply(this, arguments); }, }); - assert.containsN(form, 'option', 2); - assert.containsOnce(form, 'option[value=\'"value"\']'); + assert.containsN(form, "option", 2); + assert.containsOnce(form, "option[value='\"value\"']"); form.destroy(); }); - QUnit.test('values are fetched w/o context (integer)', async function (assert) { + QUnit.test("values are fetched w/o context (integer)", async function(assert) { assert.expect(2); var form = await testUtils.createView({ View: FormView, - model: 'demo_entry', + model: "demo_entry", data: { demo_entry: { fields: { - test_field: {string: 'Test Field', type: 'integer'}, + test_field: {string: "Test Field", type: "integer"}, }, records: [{id: 1, test_field: 0}], }, }, arch: - '', - mockRPC: function (route, args) { - if (args.method === '_get_test_field_values') { - return $.when([ - [0, 'Title'], - ]); + "", + mockRPC: function(route, args) { + if (args.method === "_get_test_field_values") { + return $.when([[0, "Title"]]); } return this._super.apply(this, arguments); }, }); - assert.containsN(form, 'option', 2); - assert.containsOnce(form, 'option[value=\'0\']'); + assert.containsN(form, "option", 2); + assert.containsOnce(form, "option[value='0']"); form.destroy(); }); - QUnit.test('values are fetched w/o context (selection)', async function (assert) { + QUnit.test("values are fetched w/o context (selection)", async function( + assert + ) { assert.expect(2); var form = await testUtils.createView({ View: FormView, - model: 'demo_entry', + model: "demo_entry", data: { demo_entry: { fields: { - test_field: {string: 'Test Field', type: 'selection'}, + test_field: {string: "Test Field", type: "selection"}, }, - records: [{id: 1, test_field: ''}], + records: [{id: 1, test_field: ""}], }, }, arch: - '', - mockRPC: function (route, args) { - if (args.method === '_get_test_field_values') { - return $.when([ - ['value', 'Title'], - ]); + "", + mockRPC: function(route, args) { + if (args.method === "_get_test_field_values") { + return $.when([["value", "Title"]]); } return this._super.apply(this, arguments); }, }); - assert.containsN(form, 'option', 2); - assert.containsOnce(form, 'option[value=\'"value"\']'); + assert.containsN(form, "option", 2); + assert.containsOnce(form, "option[value='\"value\"']"); form.destroy(); }); - QUnit.test('values are fetched with changing context', async function (assert) { + QUnit.test("values are fetched with changing context", async function(assert) { assert.expect(6); var form = await testUtils.createView({ View: FormView, - model: 'demo_entry', + model: "demo_entry", data: { demo_entry: { fields: { - other_field: {string: 'Other Field', type: 'char'}, - test_field: {string: 'Test Field', type: 'char'}, + other_field: {string: "Other Field", type: "char"}, + test_field: {string: "Test Field", type: "char"}, }, - records: [{id: 1, other_field: '', test_field: ''}], + records: [{id: 1, other_field: "", test_field: ""}], }, }, arch: - '', - mockRPC: function (route, args) { - if (args.method === '_get_test_field_values') { - if (args.kwargs.context.step === 'step-1') { + "", + mockRPC: function(route, args) { + if (args.method === "_get_test_field_values") { + if (args.kwargs.context.step === "step-1") { + return $.when([["value", "Title"]]); + } else if (args.kwargs.context.step === "step-2") { return $.when([ - ['value', 'Title'], + ["value", "Title"], + ["value_2", "Title 2"], ]); - } else if (args.kwargs.context.step === 'step-2') { - return $.when([ - ['value', 'Title'], - ['value_2', 'Title 2'], - ]); - } else { - return $.when([]); } + return $.when([]); } return this._super.apply(this, arguments); }, @@ -149,27 +145,27 @@ odoo.define('web_widget_dropdown_dynamic.web_widget_dropdown_dynamic_tests', fun await testUtils.fields.editAndTrigger( form.$('.o_field_widget[name="other_field"]'), - 'step-1', - ['input'] + "step-1", + ["input"] ); - assert.containsN(form, 'option', 2); - assert.containsOnce(form, 'option[value=\'"value"\']'); + assert.containsN(form, "option", 2); + assert.containsOnce(form, "option[value='\"value\"']"); await testUtils.fields.editAndTrigger( form.$('.o_field_widget[name="other_field"]'), - 'step-2', - ['input'] + "step-2", + ["input"] ); - assert.containsN(form, 'option', 3); - assert.containsOnce(form, 'option[value=\'"value"\']'); - assert.containsOnce(form, 'option[value=\'"value_2"\']'); + assert.containsN(form, "option", 3); + assert.containsOnce(form, "option[value='\"value\"']"); + assert.containsOnce(form, "option[value='\"value_2\"']"); await testUtils.fields.editAndTrigger( form.$('.o_field_widget[name="other_field"]'), - 'step-other', - ['input'] + "step-other", + ["input"] ); - assert.containsN(form, 'option', 1); + assert.containsN(form, "option", 1); form.destroy(); }); diff --git a/web_widget_dropdown_dynamic/templates/assets.xml b/web_widget_dropdown_dynamic/templates/assets.xml index 70b958e96..e8ed1dcad 100644 --- a/web_widget_dropdown_dynamic/templates/assets.xml +++ b/web_widget_dropdown_dynamic/templates/assets.xml @@ -1,19 +1,35 @@ - +