summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js
diff options
context:
space:
mode:
authorqsm-odoo <qsm@odoo.com>2017-03-08 16:43:44 +0100
committerAaron Bohy <aab@odoo.com>2017-04-11 19:44:38 +0200
commit29cd7154e66a30fb656b88e16b4301d17fa7d958 (patch)
tree4f1adf4c812aa38a1a9029c4e13d0beac26b45ee /addons/web/static/src/js
parentb5b649e5b21d41279f12f0dbe6cfa53ca2c52580 (diff)
[FIX] web: restore FieldStatus behavior
FieldStatus was broken: - With a selection, the statusbar_visible attribute forces the choices to display, the discarded ones do not appear at all (even folded) - With a m2o, the fold_field option tells the field to check in the relation to know if the choice has to be folded or not, this was not properly supported - Changing a m2o value was broken as the parseMany2one function did not exist - The status were misordered - ... * Also refactor the way the rendering is handled. * Also modify all statusbar tests so that the statusbar widget is placed in the form header tag (as it is the common use case).
Diffstat (limited to 'addons/web/static/src/js')
-rw-r--r--addons/web/static/src/js/fields/field_utils.js30
-rw-r--r--addons/web/static/src/js/fields/relational_fields.js85
-rw-r--r--addons/web/static/src/js/views/basic/basic_model.js9
-rw-r--r--addons/web/static/src/js/views/form/form_renderer.js7
4 files changed, 82 insertions, 49 deletions
diff --git a/addons/web/static/src/js/fields/field_utils.js b/addons/web/static/src/js/fields/field_utils.js
index c359a014b4e..406a86ac7a2 100644
--- a/addons/web/static/src/js/fields/field_utils.js
+++ b/addons/web/static/src/js/fields/field_utils.js
@@ -336,6 +336,34 @@ function parseMonetary(formatted_value) {
return parseFloat(value);
}
+/**
+ * Creates an object with id and display_name.
+ *
+ * @param {Array|number|string|Object} value
+ * The given value can be :
+ * - an array with id as first element and display_name as second element
+ * - a number or a string representing the id (the display_name will be
+ * returned as undefined)
+ * - an object, simply returned untouched
+ * @returns {Object} (contains the id and display_name)
+ * Note: if the given value is not an array, a string or a
+ * number, the value is returned untouched.
+ */
+function parseMany2one(value) {
+ if (_.isArray(value)) {
+ return {
+ id: value[0],
+ display_name: value[1],
+ };
+ }
+ if (_.isNumber(value) || _.isString(value)) {
+ return {
+ id: parseInt(value, 10),
+ };
+ }
+ return value;
+}
+
return {
format: {
binary: _.identity, // todo
@@ -368,7 +396,7 @@ return {
id: _.identity,
integer: parseInteger,
many2many: _.identity, // todo
- many2one: _.identity,
+ many2one: parseMany2one,
monetary: parseMonetary,
one2many: _.identity,
reference: _.identity, // todo
diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js
index 68bd7a52343..4663c40f755 100644
--- a/addons/web/static/src/js/fields/relational_fields.js
+++ b/addons/web/static/src/js/fields/relational_fields.js
@@ -1166,13 +1166,15 @@ var FieldMany2ManyCheckBoxes = AbstractField.extend({
//------------------------------------------------------------------------------
var FieldStatus = AbstractField.extend({
- template: "FieldStatus",
className: 'o_statusbar_status',
events: {
- 'click .o_arrow_button': '_onClickStage',
+ 'click button:not(.dropdown-toggle)': '_onClickStage',
},
specialData: "_fetchSpecialStatus",
supportedFieldTypes: ['selection', 'many2one'],
+ /**
+ * @override init from AbstractField
+ */
init: function () {
this._super.apply(this, arguments);
this._setState();
@@ -1183,6 +1185,7 @@ var FieldStatus = AbstractField.extend({
//--------------------------------------------------------------------------
/**
+ * @override _reset from AbstractField
* @private
*/
_reset: function () {
@@ -1190,45 +1193,51 @@ var FieldStatus = AbstractField.extend({
this._setState();
},
/**
+ * Prepares the rendering data from the field and record data.
* @private
*/
_setState: function () {
+ var self = this;
if (this.field.type === 'many2one') {
- this.status_information = this.record.specialData[this.name];
- var status = _.findWhere(this.status_information, {id: this.value.res_id});
- if (status) {
- status.selected = true;
- }
+ this.status_information = _.map(this.record.specialData[this.name], function (info) {
+ return _.extend({
+ selected: info.id === self.value.res_id,
+ }, info);
+ });
} else {
- var self = this;
- this.status_information = _.map(this.field.selection, function (val) {
- return { id: val[0], display_name: val[1], selected: val[0] === self.value };
+ var selection = this.field.selection;
+ if (this.attrs.statusbar_visible) {
+ var restriction = this.attrs.statusbar_visible.split(",");
+ selection = _.filter(selection, function (val) {
+ return _.contains(restriction, val[0]) || val[0] === self.value;
+ });
+ }
+ this.status_information = _.map(selection, function (val) {
+ return { id: val[0], display_name: val[1], selected: val[0] === self.value, fold: false };
});
}
},
/**
+ * @override _render from AbstractField
* @private
*/
_render: function () {
- var visible = this.attrs.statusbar_visible;
- var selection_folded = [];
- var selection_unfolded = [];
- _.each(this.status_information, function (info) {
- if (info.selected && (info.fold || visible && visible.indexOf(info.display_name) === -1)) {
- selection_folded.push(info);
- } else {
- selection_unfolded.push(info);
- }
- });
- var mobile = config.device.size_class <= config.device.SIZES.XS;
- // grep: FieldStatus.content.mobile, FieldStatus.content.desktop
- var content = qweb.render("FieldStatus.content." + (mobile ? 'mobile' : 'desktop'), {
- selection_folded: selection_folded.reverse(),
- selection_unfolded: selection_unfolded.reverse(),
- clickable: !!this.attrs.clickable,
- });
- this.$el.html(content);
- this.$('.disabled').prop('disabled', true);
+ if (config.device.size_class > config.device.SIZES.XS) {
+ var selections = _.partition(this.status_information, function (info) {
+ return (info.selected || !info.fold);
+ });
+ this.$el.html(qweb.render("FieldStatus.content.desktop", {
+ selection_unfolded: selections[0],
+ selection_folded: selections[1],
+ clickable: !!this.attrs.clickable,
+ }));
+ } else {
+ this.$el.html(qweb.render("FieldStatus.content.mobile", {
+ selection: this.status_information,
+ value: _.findWhere(this.status_information, {selected: true}).display_name,
+ clickable: !!this.attrs.clickable,
+ }));
+ }
},
//--------------------------------------------------------------------------
@@ -1236,22 +1245,14 @@ var FieldStatus = AbstractField.extend({
//--------------------------------------------------------------------------
/**
- * Note that this function is debounced...
+ * Called when on status stage is clicked -> sets the field value.
+ * Note: this function is debounced...
*
* @private
- * @param {MouseEvent} event
+ * @param {MouseEvent} e
*/
- _onClickStage: _.debounce(function (event) {
- var $stage = $(event.currentTarget);
- var val;
- if (this.field.type === "many2one") {
- val = parseInt($stage.data("value"), 10);
- } else {
- val = $stage.data("value");
- }
- if (val) {
- this._setValue(val);
- }
+ _onClickStage: _.debounce(function (e) {
+ this._setValue($(e.currentTarget).data("value"));
}, 300, true),
});
diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js
index cdb8bb61f7c..afac5c1c5ff 100644
--- a/addons/web/static/src/js/views/basic/basic_model.js
+++ b/addons/web/static/src/js/views/basic/basic_model.js
@@ -964,7 +964,7 @@ var BasicModel = AbstractModel.extend({
}
var rel_data = _.pick(data, 'id', 'display_name');
var def;
- if (!('display_name' in rel_data)) {
+ if (rel_data.display_name === undefined) {
var field = record.fields[fieldName];
def = this._rpc(field.relation, 'name_get')
.args([data.id])
@@ -1498,7 +1498,12 @@ var BasicModel = AbstractModel.extend({
_fetchSpecialStatus: function (record, fieldName) {
var foldField = record.fieldAttrs[fieldName].options.fold_field;
var fieldsToRead = foldField ? [foldField] : [];
- return this._fetchSpecialMany2ones(record, fieldName, fieldsToRead);
+ return this._fetchSpecialMany2ones(record, fieldName, fieldsToRead).then(function (m2os) {
+ _.each(m2os, function (m2o) {
+ m2o.fold = foldField ? m2o[foldField] : false;
+ });
+ return m2os;
+ });
},
/**
* Fetch all data in a ungrouped list
diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js
index a83c7d653b5..ce7c3b0bc16 100644
--- a/addons/web/static/src/js/views/form/form_renderer.js
+++ b/addons/web/static/src/js/views/form/form_renderer.js
@@ -477,14 +477,13 @@ return BasicRenderer.extend({
},
_renderTagHeader: function (node) {
var self = this;
- var $statusbar = $('<div>').addClass('o_form_statusbar');
- var $buttons = $('<div>').addClass('o_statusbar_buttons');
+ var $statusbar = $('<div>', {class: 'o_form_statusbar'});
+ var $buttons = $('<div>', {class: 'o_statusbar_buttons'});
$statusbar.append($buttons);
_.each(node.children, function (child) {
if (child.tag === 'button') {
$buttons.append(self._renderHeaderButton(child));
- }
- if (child.tag === 'field') {
+ } else if (child.tag === 'field') {
var widget = self._renderFieldWidget(child);
$statusbar.append(widget.$el);
}