diff --git a/web_widget_numeric_step/README.rst b/web_widget_numeric_step/README.rst new file mode 100644 index 000000000..f61c24b4f --- /dev/null +++ b/web_widget_numeric_step/README.rst @@ -0,0 +1,115 @@ +======================= +Web Widget Numeric Step +======================= + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github + :target: https://github.com/OCA/web/tree/12.0/web_widget_numeric_step + :alt: OCA/web +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/web-12-0/web-12-0-web_widget_numeric_step + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/162/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This widget changes input number field and make it easier to increment the number thanks to 2 buttons (+ and -). +Use JS native logic for input number, so you can use the options ``min``, ``max``, ``step``, ``placeholder``. + +Demo available at `Settings > Users & Companies > Users > *Select One* > See 'Credit Limit' field` + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +In your xml view, add ``widget="numeric_step"`` +This will add the 2 buttons "+" and "-" just next to the input field in edit mode. +Iteration step by default is 1. + +.. figure:: https://raw.githubusercontent.com/OCA/web/12.0/web_widget_numeric_step/static/description/add_two_buttons.png + + +**Optional** + +Add an option to choose the step iteration and limits (min and max values). + +Example for an 0.25 step, min to -1 and max to 10 : + +.. code:: xml + + days + +**Examples** + +Iteration with 0.25 step, min to -1 and max to 10. + +Start to increment with button, continue incrementing with scrolling mouse. + +.. figure:: https://raw.githubusercontent.com/OCA/web/12.0/web_widget_numeric_step/static/description/step0,25andlimits.gif + +Iteration with 10 step, max limit 15, placeholder with onchange + +.. figure:: https://raw.githubusercontent.com/OCA/web/12.0/web_widget_numeric_step/static/description/step10_limit15_placeholder117_with_onchange.gif + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* GRAP +* Tecnativa + +Contributors +~~~~~~~~~~~~ + +* `GRAP `_: + + * Quentin DUPONT + +* `Tecnativa `_: + + * Alexandre Díaz + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/web `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/web_widget_numeric_step/__init__.py b/web_widget_numeric_step/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/web_widget_numeric_step/__manifest__.py b/web_widget_numeric_step/__manifest__.py new file mode 100644 index 000000000..092fc003f --- /dev/null +++ b/web_widget_numeric_step/__manifest__.py @@ -0,0 +1,25 @@ +# Copyright 2019 GRAP - Quentin DUPONT +# Copyright 2020 Tecnativa - Alexandre Díaz +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +{ + 'name': "Web Widget Numeric Step", + 'category': "web", + 'version': "12.0.1.0.0", + 'author': "GRAP, Tecnativa, " + "Odoo Community Association (OCA)", + 'license': 'AGPL-3', + 'website': 'https://github.com/OCA/web', + 'depends': ['web'], + 'data': [ + 'view/assets.xml' + ], + 'qweb': [ + 'static/src/xml/numeric_step.xml', + ], + 'demo': [ + 'demo/res_users_view.xml' + ], + 'auto_install': False, + 'installable': True, +} diff --git a/web_widget_numeric_step/demo/res_users_view.xml b/web_widget_numeric_step/demo/res_users_view.xml new file mode 100644 index 000000000..521affed0 --- /dev/null +++ b/web_widget_numeric_step/demo/res_users_view.xml @@ -0,0 +1,17 @@ + + + + + + res.users + + + + + + + + + + diff --git a/web_widget_numeric_step/i18n/fr.po b/web_widget_numeric_step/i18n/fr.po new file mode 100644 index 000000000..3be7542a9 --- /dev/null +++ b/web_widget_numeric_step/i18n/fr.po @@ -0,0 +1,31 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_number_ux_choice +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-08-30 12:07+0000\n" +"PO-Revision-Date: 2019-08-30 12:07+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: web_widget_number_ux_choice +#. openerp-web +#: code:addons/web_widget_number_ux_choice/static/src/xml/number_ux_choice.xml:12 +#, python-format +msgid "Minus" +msgstr "Moins" + +#. module: web_widget_number_ux_choice +#. openerp-web +#: code:addons/web_widget_number_ux_choice/static/src/xml/number_ux_choice.xml:12 +#, python-format +msgid "Plus" +msgstr "Plus" + diff --git a/web_widget_numeric_step/readme/CONTRIBUTORS.rst b/web_widget_numeric_step/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..de2b473bd --- /dev/null +++ b/web_widget_numeric_step/readme/CONTRIBUTORS.rst @@ -0,0 +1,7 @@ +* `GRAP `_: + + * Quentin DUPONT + +* `Tecnativa `_: + + * Alexandre Díaz diff --git a/web_widget_numeric_step/readme/DESCRIPTION.rst b/web_widget_numeric_step/readme/DESCRIPTION.rst new file mode 100644 index 000000000..4f251db10 --- /dev/null +++ b/web_widget_numeric_step/readme/DESCRIPTION.rst @@ -0,0 +1,4 @@ +This widget changes input number field and make it easier to increment the number thanks to 2 buttons (+ and -). +Use JS native logic for input number, so you can use the options ``min``, ``max``, ``step``, ``placeholder``. + +Demo available at `Settings > Users & Companies > Users > *Select One* > See 'Credit Limit' field` diff --git a/web_widget_numeric_step/readme/USAGE.rst b/web_widget_numeric_step/readme/USAGE.rst new file mode 100644 index 000000000..e272b8022 --- /dev/null +++ b/web_widget_numeric_step/readme/USAGE.rst @@ -0,0 +1,28 @@ +In your xml view, add ``widget="numeric_step"`` +This will add the 2 buttons "+" and "-" just next to the input field in edit mode. +Iteration step by default is 1. + +.. figure:: ../static/description/add_two_buttons.png + + +**Optional** + +Add an option to choose the step iteration and limits (min and max values). + +Example for an 0.25 step, min to -1 and max to 10 : + +.. code:: xml + + days + +**Examples** + +Iteration with 0.25 step, min to -1 and max to 10. + +Start to increment with button, continue incrementing with scrolling mouse. + +.. figure:: ../static/description/step0,25andlimits.gif + +Iteration with 10 step, max limit 15, placeholder with onchange + +.. figure:: ../static/description/step10_limit15_placeholder117_with_onchange.gif diff --git a/web_widget_numeric_step/static/description/add_two_buttons.png b/web_widget_numeric_step/static/description/add_two_buttons.png new file mode 100644 index 000000000..2670f06ec Binary files /dev/null and b/web_widget_numeric_step/static/description/add_two_buttons.png differ diff --git a/web_widget_numeric_step/static/description/icon.png b/web_widget_numeric_step/static/description/icon.png new file mode 100644 index 000000000..3a662b992 Binary files /dev/null and b/web_widget_numeric_step/static/description/icon.png differ diff --git a/web_widget_numeric_step/static/description/index.html b/web_widget_numeric_step/static/description/index.html new file mode 100644 index 000000000..ea4b4c5ed --- /dev/null +++ b/web_widget_numeric_step/static/description/index.html @@ -0,0 +1,455 @@ + + + + + + +Web Widget Numeric Step + + + +
+

Web Widget Numeric Step

+ + +

Beta License: AGPL-3 OCA/web Translate me on Weblate Try me on Runbot

+

This widget changes input number field and make it easier to increment the number thanks to 2 buttons (+ and -). +Use JS native logic for input number, so you can use the options min, max, step, placeholder.

+

Demo available at Settings > Users & Companies > Users > *Select One* > See ‘Credit Limit’ field

+

Table of contents

+ +
+

Usage

+

In your xml view, add widget="numeric_step" +This will add the 2 buttons “+” and “-” just next to the input field in edit mode. +Iteration step by default is 1.

+
+https://raw.githubusercontent.com/OCA/web/12.0/web_widget_numeric_step/static/description/add_two_buttons.png +
+

Optional

+

Add an option to choose the step iteration and limits (min and max values).

+

Example for an 0.25 step, min to -1 and max to 10 :

+
+<field name="sale_delay" widget="numeric_step" options="{'step': 0.25, 'min': -1, 'max': 10}" /> days
+
+

Examples

+

Iteration with 0.25 step, min to -1 and max to 10.

+

Start to increment with button, continue incrementing with scrolling mouse.

+
+https://raw.githubusercontent.com/OCA/web/12.0/web_widget_numeric_step/static/description/step0,25andlimits.gif +
+

Iteration with 10 step, max limit 15, placeholder with onchange

+
+https://raw.githubusercontent.com/OCA/web/12.0/web_widget_numeric_step/static/description/step10_limit15_placeholder117_with_onchange.gif +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • GRAP
  • +
  • Tecnativa
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/web project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/web_widget_numeric_step/static/description/step0,25andlimits.gif b/web_widget_numeric_step/static/description/step0,25andlimits.gif new file mode 100644 index 000000000..1e5827236 Binary files /dev/null and b/web_widget_numeric_step/static/description/step0,25andlimits.gif differ diff --git a/web_widget_numeric_step/static/description/step10_limit15_placeholder117_with_onchange.gif b/web_widget_numeric_step/static/description/step10_limit15_placeholder117_with_onchange.gif new file mode 100644 index 000000000..eb0b6e815 Binary files /dev/null and b/web_widget_numeric_step/static/description/step10_limit15_placeholder117_with_onchange.gif differ diff --git a/web_widget_numeric_step/static/src/css/numeric_step.scss b/web_widget_numeric_step/static/src/css/numeric_step.scss new file mode 100644 index 000000000..5926a9152 --- /dev/null +++ b/web_widget_numeric_step/static/src/css/numeric_step.scss @@ -0,0 +1,3 @@ +.widget_numeric_step { + display: inline-flex; +} diff --git a/web_widget_numeric_step/static/src/js/numeric_step.js b/web_widget_numeric_step/static/src/js/numeric_step.js new file mode 100644 index 000000000..ac5249e63 --- /dev/null +++ b/web_widget_numeric_step/static/src/js/numeric_step.js @@ -0,0 +1,245 @@ +/* Copyright 2019 GRAP - Quentin DUPONT + * Copyright 2020 Tecnativa - Alexandre Díaz + * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) */ + +odoo.define('web_widget_numeric_step.field', function (require) { + "use strict"; + + var Registry = require('web.field_registry'); + var FieldFloat = require('web.basic_fields').FieldFloat; + + + var NumericStep = FieldFloat.extend({ + template: 'web_widget_numeric_step', + className: 'o_field_numeric_step o_field_number', + events: _.extend({}, FieldFloat.prototype.events, { + 'mousedown .btn_numeric_step': '_onStepMouseDown', + 'touchstart .btn_numeric_step': '_onStepMouseDown', + 'click .btn_numeric_step': '_onStepClick', + 'wheel .input_numeric_step': '_onWheel', + 'keydown .input_numeric_step': '_onKeyDown', + 'change .input_numeric_step': '_onChange', + }), + supportedFieldTypes: ['float', 'integer'], + + // Values in milliseconds used for mouse down smooth speed feature + DEF_CLICK_DELAY: 400, + MIN_DELAY: 50, + SUBSTRACT_DELAY_STEP: 25, + + init: function () { + this._super.apply(this, arguments); + + // Widget config + var max_val = this.nodeOptions.max; + var min_val = this.nodeOptions.min; + if (!_.isUndefined(min_val) && !_.isUndefined(max_val) && min_val > max_val) { + min_val = this.nodeOptions.max; + max_val = this.nodeOptions.min; + } + + this._config = { + 'step': Number(this.nodeOptions.step) || 1, + 'min': Number(min_val), + 'max': Number(max_val), + }; + }, + + /** + * Add global events listeners + * + * @override + */ + start: function () { + var self = this; + this._click_delay = this.DEF_CLICK_DELAY; + this._autoStep = false; + return this._super.apply(this, arguments).then(function () { + document.addEventListener( + 'mouseup', $.proxy(self, "_onMouseUp"), false); + document.addEventListener( + 'touchend', $.proxy(self, "_onMouseUp"), false); + }); + }, + + /** + * Transform database value to usable widget value + * + * @override + */ + _formatValue: function (value) { + if (this.mode === 'edit') { + return this._sanitizeNumberValue(value); + } + return this._super.apply(this, arguments); + }, + + /** + * Transform widget value to usable database value + * + * @override + */ + _parseValue: function () { + var parsedVal = this._super.apply(this, arguments); + if (this.mode === 'edit') { + return Number(parsedVal) || 0; + } + return parsedVal; + }, + + /** + * Adds HTML attributes to the input + * + * @override + */ + _prepareInput: function () { + var result = this._super.apply(this, arguments); + this.$input.attr(_.pick(this.nodeOptions, ['placeholder'])); + // InputField hard set the input type to 'text' or 'password', + // we force it again to be 'tel'. + // The widget uses 'tel' type because offers a good layout on + // mobiles and can accept alphanumeric characters. + // The bad news is that require implement all good 'number' type + // features like the minus and plus buttons, steps, min and max... + // Perhaps in a near future this can be improved to have the best of + // two types without hacky developments. + this.$input.attr('type', 'tel'); + return result; + }, + + /** + * Select the proper widget input + * + * @override + */ + _renderEdit: function () { + this._prepareInput(this.$el.find('input.input_numeric_step')); + }, + + /** + * Increase/Decrease widget input value + * + * @param {String} mode can be "plus" or "minus" + */ + _doStep: function (mode) { + var cval = Number(this.$input.val()); + if (_.isNaN(cval)) { + return; + } + if (mode === 'plus') { + cval += this._config.step; + } else if (mode === 'minus') { + cval -= this._config.step; + } + this.$input.val(this._sanitizeNumberValue(cval)); + this.isDirty = true; + this._doDebouncedAction(); + }, + + // Handle Events + _onStepClick: function (ev) { + if (!this._autoStep) { + var mode = ev.target.dataset.mode; + this._doStep(mode); + } + this._autoStep = false; + }, + + _onStepMouseDown: function (ev) { + this._interval = setTimeout( + $.proxy(this, "_whileMouseDown", ev), this._click_delay); + }, + + _onMouseUp: function () { + clearTimeout(this._interval); + this._interval = false; + this._click_delay = this.DEF_CLICK_DELAY; + }, + + _whileMouseDown: function (ev) { + this._autoStep = true; + var mode = ev.target.dataset.mode; + this._doStep(mode); + if (this._click_delay > this.MIN_DELAY) { + this._click_delay -= this.SUBSTRACT_DELAY_STEP; + } + + this._onStepMouseDown(ev); + }, + + /** + * Enable mouse wheel support + * + * @param {WheelEvent} ev + */ + _onWheel: function (ev) { + ev.preventDefault(); + if (ev.originalEvent.deltaY > 0) { + this._doStep('minus'); + } else { + this._doStep('plus'); + } + }, + + /** + * Enable keyboard arrows support + * + * @param {KeyEvent} ev + */ + _onKeyDown: function (ev) { + if (ev.keyCode === $.ui.keyCode.UP) { + this._doStep('plus'); + } else if (ev.keyCode === $.ui.keyCode.DOWN) { + this._doStep('minus'); + } + }, + + /** + * Sanitize user input value + * + * @param {ChangeEvent} ev + */ + _onChange: function (ev) { + ev.target.value = this._sanitizeNumberValue(ev.target.value); + }, + + // Helper Functions + /* + * Get field precision (really used by floats) + */ + _getPrecision: function () { + var field = this.record.fields[this.name]; + if (field && 'digits' in field && field.digits.length === 2) { + return field.digits[1]; + } + + return 0; + }, + + /** + * Check limits and precision of the value. + * If the value 'is not a number', the function does nothing to + * be good with other possible modules. + * + * @param {Number} value + * @returns {Number} + */ + _sanitizeNumberValue: function (value) { + var cval = Number(value); + if (_.isNaN(cval)) { + return value; + } + if (!_.isNaN(this._config.min) && cval < this._config.min) { + cval = this._config.min; + } else if (!_.isNaN(this._config.max) && cval > this._config.max) { + cval = this._config.max; + } + return cval.toFixed(this._getPrecision()); + }, + }); + + Registry.add('numeric_step', NumericStep); + + return NumericStep; + +}); diff --git a/web_widget_numeric_step/static/src/xml/numeric_step.xml b/web_widget_numeric_step/static/src/xml/numeric_step.xml new file mode 100644 index 000000000..08867f25c --- /dev/null +++ b/web_widget_numeric_step/static/src/xml/numeric_step.xml @@ -0,0 +1,28 @@ + + + + + + +
+
+
+ +
+
+
+
+ + + +
+ +
diff --git a/web_widget_numeric_step/view/assets.xml b/web_widget_numeric_step/view/assets.xml new file mode 100644 index 000000000..e8093acb0 --- /dev/null +++ b/web_widget_numeric_step/view/assets.xml @@ -0,0 +1,11 @@ + + + + + +