[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).
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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,39 +40,142 @@ 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);
|
||||
},
|
||||
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
// The state has been given as a single value -> set the limit to 1
|
||||
this.state.limit = 1;
|
||||
}
|
||||
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;
|
||||
} else if ((current_min < 1) && (limit === 1)) {
|
||||
current_min = size;
|
||||
} 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 state;
|
||||
var size = this.state.size;
|
||||
var current_min = this.state.current_min;
|
||||
var current_max = this.state.current_max;
|
||||
@@ -79,33 +192,16 @@ var Pager = Widget.extend({
|
||||
this.enable();
|
||||
}
|
||||
|
||||
if (this.state.limit === 1) {
|
||||
state = "" + current_min + " / " + size;
|
||||
} else {
|
||||
state = "" + current_min + "-" + current_max + " / " + size;
|
||||
var value = "" + current_min;
|
||||
if (this.state.limit > 1) {
|
||||
value += "-" + current_max;
|
||||
}
|
||||
this.$content.html(state);
|
||||
this.$value.html(value);
|
||||
this.$limit.html(size);
|
||||
}
|
||||
},
|
||||
|
||||
_change_selection: function (direction) {
|
||||
var size = this.state.size;
|
||||
var current_min = this.state.current_min;
|
||||
var limit = this.state.limit;
|
||||
current_min = (current_min + limit*direction);
|
||||
if (current_min > size) {
|
||||
current_min = 1;
|
||||
} else if ((current_min < 1) && (limit === 1)) {
|
||||
current_min = size;
|
||||
} 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();
|
||||
},
|
||||
});
|
||||
|
||||
return Pager;
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user