diff options
| author | Aaron Bohy <aab@odoo.com> | 2015-06-18 08:13:57 +0200 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2015-06-18 13:51:56 +0200 |
| commit | 5f72fb8e10f5d432900926746ff19c97b977e6e4 (patch) | |
| tree | a0187bdaeba2c5dc3c8b3ef3b6e98dae6491becb /addons/web/static/src | |
| parent | 6070dc201e632c9553138edd138762ac910f0834 (diff) | |
[IMP] web: pager: editable feature + documentation
Pager's state can now be edited (mainly to change the limit,
but the range of values as well).
Diffstat (limited to 'addons/web/static/src')
| -rw-r--r-- | addons/web/static/src/js/framework/utils.js | 12 | ||||
| -rw-r--r-- | addons/web/static/src/js/widgets/pager.js | 160 | ||||
| -rw-r--r-- | addons/web/static/src/xml/base.xml | 6 |
3 files changed, 143 insertions, 35 deletions
diff --git a/addons/web/static/src/js/framework/utils.js b/addons/web/static/src/js/framework/utils.js index 50a35fbbbea..f99d99ccc14 100644 --- a/addons/web/static/src/js/framework/utils.js +++ b/addons/web/static/src/js/framework/utils.js @@ -341,6 +341,17 @@ function float_is_zero (value, decimals) { return Math.abs(round_precision(value, epsilon)) < epsilon; }; +/** + * Confines a value inside an interval + * @param {Number} [val] the value to confine + * @param {Number} [min] the minimum of the interval + * @param {Number} [max] the maximum of the interval + * @return val if val is in [min, max], min if val < min and max otherwise + */ +function confine (val, min, max) { + return Math.max(min, Math.min(max, val)); +} + function assert (bool) { if (!bool) { throw new Error("AssertionError"); @@ -413,6 +424,7 @@ return { round_precision: round_precision, round_decimals: round_decimals, float_is_zero: float_is_zero, + confine: confine, assert: assert, xor: xor, DropMisordered: DropMisordered, diff --git a/addons/web/static/src/js/widgets/pager.js b/addons/web/static/src/js/widgets/pager.js index c195aaf530d..ee576e923a4 100644 --- a/addons/web/static/src/js/widgets/pager.js +++ b/addons/web/static/src/js/widgets/pager.js @@ -1,6 +1,7 @@ odoo.define('web.Pager', function (require) { "use strict"; +var utils = require('web.utils'); var Widget = require('web.Widget'); var direction = { @@ -12,13 +13,22 @@ var Pager = Widget.extend({ template: "Pager", events: { - 'click .o-pager-previous': 'previous', - 'click .o-pager-next': 'next', + 'click .o_pager_previous': 'previous', + 'click .o_pager_next': 'next', + 'click .o_pager_value': '_edit', }, - // pager goes from 1 to size (included). - // current value is current_min (if limit === 1) - // or the interval [current_min, current_min + limit[ if limit > 1 + /** + * The pager goes from 1 to size (included). + * The current value is current_min if limit === 1 + * or the interval [current_min, current_min + limit[ if limit > 1 + * @param {Widget} [parent] the parent widget + * @param {int} [size] the total number of elements + * @param {int} [current_min] the first element of the current_page + * @param {int} [limit] the number of elements per page + * @param {boolean} [options.can_edit] editable feature of the pager + * @param {boolean} [options.single_page_hidden] (not) to display the pager if only one page + */ init: function (parent, size, current_min, limit, options) { this.state = { size: size, @@ -30,68 +40,124 @@ var Pager = Widget.extend({ return Math.min(this.current_min + this.limit - 1, this.size); } }); - this.options = options || {}; + this.options = _.defaults({}, options, { + can_edit: true, // editable + single_page_hidden: false, // displayed even if there is a single page + }); this._super(parent); }, + /** + * Renders the pager + * @returns {jQuery.Deferred} + */ start: function () { - this.$content = this.$('.o-pager-value'); + this.$value = this.$('.o_pager_value'); + this.$limit = this.$('.o_pager_limit'); this._render(); return this._super(); }, - set_state: function (options) { - _.extend(this.state, options); + /** + * Sets the state of the pager and renders it + * @param {Object} [state] the values to update (size, current_min and limit) + */ + update_state: function (state) { + _.extend(this.state, state); this._render(); }, - previous: function(e) { + /** + * Executes the previous action on the pager + */ + previous: function() { this._change_selection(direction.previous); }, + /** + * Executes the next action on the pager + */ next: function() { this._change_selection(direction.next); }, + /** + * Disables the pager's arrows + */ disable: function() { this.$('button').prop("disabled", true); }, + /** + * Enables the pager's arrows + */ enable: function() { this.$('button').prop("disabled", false); }, - _render: function () { - var state; - var size = this.state.size; - var current_min = this.state.current_min; - var current_max = this.state.current_max; - var single_page = 1 === current_min && current_max === size; - - if (size === 0 || (single_page && this.options.single_page_hidden)) { - this.$el.hide(); - } else { - this.$el.show(); - - if (single_page) { - this.disable(); - } else { - this.enable(); - } + /** + * Private function that displays an input to edit the pager's state + */ + _edit: function() { + if (this.options.can_edit) { + var self = this; + var $input = $('<input>').val(this.$value.html()); + + this.$value.html($input); + $input.focus(); + + // Event handlers + $input.click(function(ev) { + ev.stopPropagation(); // ignore clicks on the input + }); + $input.blur(function(ev) { + self._save($(ev.target)); // save the state when leaving the input + }); + $input.on('keydown', function (ev) { + ev.stopPropagation(); + if (ev.which === $.ui.keyCode.ENTER) { + self._save($(ev.target)); // save on enter + } else if (ev.which === $.ui.keyCode.ESCAPE) { + self._render(); // leave on escape + } + }); + } + }, - if (this.state.limit === 1) { - state = "" + current_min + " / " + size; + /** + * Private function that saves the state from the content of the input + * @param {jQuery} [$input] the jQuery element containing the new state + */ + _save: function($input) { + var value = $input.val().split("-"); + var min = utils.confine(parseInt(value[0], 10), 1, this.state.size); + var max = utils.confine(parseInt(value[1], 10), 1, this.state.size); + + if (!isNaN(min)) { + this.state.current_min = min; + if (!isNaN(max)) { + this.state.limit = utils.confine(max-min+1, 1, this.state.size); } else { - state = "" + current_min + "-" + current_max + " / " + size; + // The state has been given as a single value -> set the limit to 1 + this.state.limit = 1; } - this.$content.html(state); + this.trigger('pager_changed', _.clone(this.state)); } + + // Render the pager's new state (removes the input) + this._render(); }, + /** + * Private function that updates the pager's state according to a pager action + * @param {int} [direction] the action (previous or next) on the pager + */ _change_selection: function (direction) { var size = this.state.size; var current_min = this.state.current_min; var limit = this.state.limit; + + // Compute the new current_min current_min = (current_min + limit*direction); if (current_min > size) { current_min = 1; @@ -100,12 +166,42 @@ var Pager = Widget.extend({ } else if ((current_min < 1) && (limit > 1)) { current_min = size - ((size % limit) || limit) + 1; } + this.state.current_min = current_min; this.trigger('pager_changed', _.clone(this.state)); this._render(); }, + + /** + * Private function that renders the pager's state + */ + _render: function () { + var size = this.state.size; + var current_min = this.state.current_min; + var current_max = this.state.current_max; + var single_page = 1 === current_min && current_max === size; + + if (size === 0 || (single_page && this.options.single_page_hidden)) { + this.$el.hide(); + } else { + this.$el.show(); + + if (single_page) { + this.disable(); + } else { + this.enable(); + } + + var value = "" + current_min; + if (this.state.limit > 1) { + value += "-" + current_max; + } + this.$value.html(value); + this.$limit.html(size); + } + }, }); return Pager; -});
\ No newline at end of file +}); diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index a4b669e9fe8..65b835e63f7 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -1907,10 +1907,10 @@ </button> <div t-name="Pager"> - <span class="o-pager-value"></span> + <span class="o_pager_value"></span> / <span class="o_pager_limit"></span> <span class="btn-group btn-group-sm"> - <button type="button" class="fa fa-chevron-left btn btn-icon o-pager-previous" accesskey="O"/> - <button type="button" class="fa fa-chevron-right btn btn-icon o-pager-next" accesskey="P"/> + <button type="button" class="fa fa-chevron-left btn btn-icon o_pager_previous" accesskey="O"/> + <button type="button" class="fa fa-chevron-right btn btn-icon o_pager_next" accesskey="P"/> </span> </div> |
