+
Add new options for many2one field
+
+
+
Description
+
This modules modifies "many2one" and "many2manytags" form widgets so as to add some new display
+control options.
+
New: support many2manytags widget !
+
New: support global option management with ir.config_parameter !
+
Options provided includes possibility to remove "Create..." and/or "Create and
+Edit..." entries from many2one drop down. You can also change default number of
+proposition appearing in the drop-down. Or prevent the dialog box poping in
+case of validation error.
+
If not specified, the module will avoid proposing any of the create options
+if the current user have no permission rights to create the related object.
+
+
+
Requirements
+
Was tested on openerp 8.0, trunk, saas-5 branch. New way to import js file. (thanks to tfossoul)
+
+
+
New options
+
create boolean (Default: depends if user have create rights)
+
+Whether to display the "Create..." entry in dropdown panel.
+
create_edit boolean (Default: depends if user have create rights)
+
+Whether to display "Create and Edit..." entry in dropdown panel
+
m2o_dialog boolean (Default: depends if user have create rights)
+
+Whether to display the many2one dialog in case of validation error.
+
limit int (Default: openerp default value is 7)
+
+Number of displayed record in drop-down panel
+
+
+
ir.config_parameter options
+
Now you can disable "Create..." and "Create and Edit..." entry for all widgets in the odoo instance.
+If you disable one option, you can enable it for particular field by setting "create: True" option directly on the field definition.
+
web_m2x_options.create boolean (Default: depends if user have create rights)
+
+Whether to display the "Create..." entry in dropdown panel for all fields in the odoo instance.
+
web_m2x_options.create_edit boolean (Default: depends if user have create rights)
+
+Whether to display "Create and Edit..." entry in dropdown panel for all fields in the odoo instance.
+
web_m2x_options.limit int (Default: openerp default value is 7)
+
+Number of displayed record in drop-down panel for all fields in the odoo instance
+
To add these parameters go to Configuration -> Technical -> Parameters -> System Parameters and add new parameters like:
+
+- web_m2x_options.create: False
+- web_m2x_options.create_edit: False
+- web_m2x_options.limit: 10
+
+
+
+
Example
+
Your XML form view definition could contain:
+
+...
+<field name="partner_id" options="{'limit': 10, 'create': false, 'create_edit': false}"/>
+...
+
+
+
+
Note
+
Double check that you have no inherited view that remote options you set on a field !
+If nothing work, add a debugger in the first ligne of get_search_result method and enable debug mode in OpenERP. When you write something in a many2one field, javascript debugger should pause. If not verify your installation.
+
+
+
+
diff --git a/web_m2x_options/static/src/js/form.js b/web_m2x_options/static/src/js/form.js
new file mode 100644
index 000000000..c0f57463f
--- /dev/null
+++ b/web_m2x_options/static/src/js/form.js
@@ -0,0 +1,377 @@
+/* Copyright 2016 0k.io,ACSONE SA/NV
+ * * License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
+
+odoo.define('web_m2x_options.web_m2x_options', function (require) {
+ "use strict";
+
+ var core = require('web.core'),
+ data = require('web.data'),
+ Dialog = require('web.Dialog'),
+ view_dialogs = require('web.view_dialogs'),
+ relational_fields = require('web.relational_fields'),
+ rpc = require('web.rpc');
+
+ var _t = core._t,
+ FieldMany2ManyTags = relational_fields.FieldMany2ManyTags,
+ FieldMany2One = relational_fields.FieldMany2One,
+ FormFieldMany2ManyTags = relational_fields.FormFieldMany2ManyTags;
+
+ var web_m2x_options = rpc.query({
+ model: "ir.config_parameter",
+ method: 'get_web_m2x_options',
+ });
+
+ var M2ODialog = Dialog.extend({
+ template: "M2ODialog",
+ init: function (parent, name, value) {
+ this.name = name;
+ this.value = value;
+ this._super(parent, {
+ title: _.str.sprintf(_t("Create a %s"), this.name),
+ size: 'medium',
+ buttons: [{
+ text: _t('Create'),
+ classes: 'btn-primary',
+ click: function () {
+ if (this.$("input").val() !== '') {
+ this.trigger_up('quick_create', {value: this.$('input').val()});
+ this.close(true);
+ } else {
+ this.$("input").focus();
+ }
+ },
+ }, {
+ text: _t('Create and edit'),
+ classes: 'btn-primary',
+ close: true,
+ click: function () {
+ this.trigger_up('search_create_popup', {
+ view_type: 'form',
+ value: this.$('input').val(),
+ });
+ },
+ }, {
+ text: _t('Cancel'),
+ close: true,
+ }],
+ });
+ },
+ start: function () {
+ this.$("p").text(_.str.sprintf(_t("You are creating a new %s, are you sure it does not exist yet?"), this.name));
+ this.$("input").val(this.value);
+ },
+ /**
+ * @override
+ * @param {boolean} isSet
+ */
+ close: function (isSet) {
+ this.isSet = isSet;
+ this._super.apply(this, arguments);
+ },
+ /**
+ * @override
+ */
+ destroy: function () {
+ if (!this.isSet) {
+ this.trigger_up('closed_unset');
+ }
+ this._super.apply(this, arguments);
+ },
+ });
+
+ FieldMany2One.include({
+
+ start: function () {
+ this._super.apply(this, arguments);
+ return this.get_options();
+ },
+
+ get_options: function () {
+ var self = this;
+ if (_.isUndefined(this.ir_options_loaded)) {
+ this.ir_options_loaded = $.Deferred();
+ this.ir_options = {};
+ web_m2x_options.done(function (records) {
+ _(records).each(function(record) {
+ self.ir_options[record.key] = record.value;
+ });
+ self.ir_options_loaded.resolve();
+ });
+ }
+ return $.when();
+ },
+
+ is_option_set: function (option) {
+ if (_.isUndefined(option))
+ return false;
+ if (typeof option === 'string')
+ return option === 'true' || option === 'True';
+ if (typeof option === 'boolean')
+ return option;
+ return false
+ },
+
+ _onInputFocusout: function () {
+ var m2o_dialog_opt = this.is_option_set(this.nodeOptions.m2o_dialog) || _.isUndefined(this.nodeOptions.m2o_dialog) && this.is_option_set(this.ir_options['web_m2x_options.m2o_dialog']) || _.isUndefined(this.nodeOptions.m2o_dialog) && _.isUndefined(this.ir_options['web_m2x_options.m2o_dialog']);
+ if (this.can_create && this.floating && m2o_dialog_opt) {
+ new M2ODialog(this, this.string, this.$input.val()).open();
+ }
+ },
+
+ _search: function (search_val) {
+ var self = this;
+ var def = $.Deferred();
+ this.orderer.add(def);
+
+ // add options limit used to change number of selections record
+ // returned.
+ if (!_.isUndefined(this.ir_options['web_m2x_options.limit'])) {
+ this.limit = parseInt(this.ir_options['web_m2x_options.limit'], 10);
+ }
+
+ if (typeof this.nodeOptions.limit === 'number') {
+ this.limit = this.nodeOptions.limit;
+ }
+
+ // add options field_color and colors to color item(s) depending on field_color value
+ this.field_color = this.nodeOptions.field_color;
+ this.colors = this.nodeOptions.colors;
+
+ var context = this.record.getContext(this.recordParams);
+ var domain = this.record.getDomain(this.recordParams);
+
+ var blacklisted_ids = this._getSearchBlacklist();
+ if (blacklisted_ids.length > 0) {
+ domain.push(['id', 'not in', blacklisted_ids]);
+ }
+
+ this._rpc({
+ model: this.field.relation,
+ method: "name_search",
+ kwargs: {
+ name: search_val,
+ args: domain,
+ operator: "ilike",
+ limit: this.limit + 1,
+ context: context,
+ }
+ }).then(function (result) {
+ // possible selections for the m2o
+ var values = _.map(result, function (x) {
+ x[1] = self._getDisplayName(x[1]);
+ return {
+ label: _.str.escapeHTML(x[1].trim()) || data.noDisplayContent,
+ value: x[1],
+ name: x[1],
+ id: x[0],
+ };
+ });
+
+ // Search result value colors
+ if (self.colors && self.field_color) {
+ var value_ids = [];
+ for (var index in values) {
+ value_ids.push(values[index].id);
+ }
+ self._rpc({
+ model: self.field.relation,
+ method: 'search_read',
+ fields: [self.field_color],
+ domain: [['id', 'in', value_ids]]
+ }).then(function (objects) {
+ for (var index in objects) {
+ for (var index_value in values) {
+ if (values[index_value].id == objects[index].id) {
+ // Find value in values by comparing ids
+ var value = values[index_value];
+ // Find color with field value as key
+ var color = self.colors[objects[index][self.field_color]] || 'black';
+ value.label = '