summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorAaron Bohy <aab@odoo.com>2015-06-18 08:13:57 +0200
committerAaron Bohy <aab@odoo.com>2015-06-18 13:51:56 +0200
commit5f72fb8e10f5d432900926746ff19c97b977e6e4 (patch)
treea0187bdaeba2c5dc3c8b3ef3b6e98dae6491becb /addons/web/static/src
parent6070dc201e632c9553138edd138762ac910f0834 (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.js12
-rw-r--r--addons/web/static/src/js/widgets/pager.js160
-rw-r--r--addons/web/static/src/xml/base.xml6
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>