summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js
diff options
context:
space:
mode:
authorniv-openerp <nicolas.vanhoren@openerp.com>2013-06-21 15:52:07 +0200
committerniv-openerp <nicolas.vanhoren@openerp.com>2013-06-21 15:52:07 +0200
commitd57bbfd2ffc43d0f3f5b8c0dbe385a2ab549349f (patch)
treee52365d007531c6173831d306b39b69065370472 /addons/web/static/src/js
parent6a82e64e4d119f3aecaa21bc39b70e46723f0f45 (diff)
parent5157561cb12719e15994ab418a2e84f84f454182 (diff)
merge trunk
bzr revid: nicolas.vanhoren@openerp.com-20130621135207-7oq7v2ubzfdrkrbr
Diffstat (limited to 'addons/web/static/src/js')
-rw-r--r--addons/web/static/src/js/chrome.js23
-rw-r--r--addons/web/static/src/js/coresetup.js8
-rw-r--r--addons/web/static/src/js/data.js73
-rw-r--r--addons/web/static/src/js/data_export.js88
-rw-r--r--addons/web/static/src/js/search.js64
-rw-r--r--addons/web/static/src/js/view_form.js30
-rw-r--r--addons/web/static/src/js/view_list.js25
-rw-r--r--addons/web/static/src/js/view_list_editable.js1
-rw-r--r--addons/web/static/src/js/views.js4
9 files changed, 198 insertions, 118 deletions
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index 884dc41a9f9..0c73a9b8a3c 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -430,7 +430,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({
var fetch_langs = this.rpc("/web/session/get_lang_list", {}).done(function(result) {
self.lang_list = result;
});
- return $.when(fetch_db, fetch_langs).done(self.do_render);
+ return $.when(fetch_db, fetch_langs).always(self.do_render);
},
do_render: function() {
var self = this;
@@ -950,7 +950,7 @@ instance.web.Menu = instance.web.Widget.extend({
},
do_load_needaction: function (menu_ids) {
var self = this;
- menu_ids = _.reject(menu_ids, _.isEmpty);
+ menu_ids = _.compact(menu_ids);
if (_.isEmpty(menu_ids)) {
return $.when();
}
@@ -1184,6 +1184,25 @@ instance.web.UserMenu = instance.web.Widget.extend({
});
}
},
+ on_menu_account: function() {
+ var self = this;
+ if (!this.getParent().has_uncommitted_changes()) {
+ var P = new instance.web.Model('ir.config_parameter');
+ P.call('get_param', ['database.uuid']).then(function(dbuuid) {
+ var state = {
+ 'd': instance.session.db,
+ 'u': window.location.protocol + '//' + window.location.host,
+ };
+ var params = {
+ response_type: 'token',
+ client_id: dbuuid || '',
+ state: JSON.stringify(state),
+ scope: 'userinfo',
+ };
+ instance.web.redirect('https://accounts.openerp.com/oauth2/auth?'+$.param(params));
+ });
+ }
+ },
on_menu_about: function() {
var self = this;
self.rpc("/web/webclient/version_info", {}).done(function(res) {
diff --git a/addons/web/static/src/js/coresetup.js b/addons/web/static/src/js/coresetup.js
index dedb4a49710..6fc837333b6 100644
--- a/addons/web/static/src/js/coresetup.js
+++ b/addons/web/static/src/js/coresetup.js
@@ -555,19 +555,19 @@ instance.web.qweb.default_dict = {
instance.web.qweb.preprocess_node = function() {
// Note that 'this' is the Qweb Node
switch (this.node.nodeType) {
- case 3:
- case 4:
+ case Node.TEXT_NODE:
+ case Node.CDATA_SECTION_NODE:
// Text and CDATAs
var translation = this.node.parentNode.attributes['t-translation'];
if (translation && translation.value === 'off') {
return;
}
- var match = /^(\s*)(.+?)(\s*)$/.exec(this.node.data);
+ var match = /^(\s*)([\s\S]+?)(\s*)$/.exec(this.node.data);
if (match) {
this.node.data = match[1] + instance.web._t(match[2]) + match[3];
}
break;
- case 1:
+ case Node.ELEMENT_NODE:
// Element
var attr, attrs = ['label', 'title', 'alt', 'placeholder'];
while (attr = attrs.pop()) {
diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js
index f1b043bacf9..679afe77bcd 100644
--- a/addons/web/static/src/js/data.js
+++ b/addons/web/static/src/js/data.js
@@ -112,24 +112,27 @@ instance.web.Query = instance.web.Class.extend({
* @returns {jQuery.Deferred<Array<openerp.web.QueryGroup>> | null}
*/
group_by: function (grouping) {
- if (grouping === undefined) {
- return null;
+ var ctx = instance.web.pyeval.eval(
+ 'context', this._model.context(this._context));
+
+ // undefined passed in explicitly (!)
+ if (_.isUndefined(grouping)) {
+ grouping = [];
}
if (!(grouping instanceof Array)) {
grouping = _.toArray(arguments);
}
- if (_.isEmpty(grouping)) { return null; }
+ if (_.isEmpty(grouping) && !ctx['group_by_no_leaf']) {
+ return null;
+ }
var self = this;
-
- var ctx = instance.web.pyeval.eval(
- 'context', this._model.context(this._context));
return this._model.call('read_group', {
groupby: grouping,
fields: _.uniq(grouping.concat(this._fields || [])),
domain: this._model.domain(this._filter),
- context: this._model.context(this._context),
+ context: ctx,
offset: this._offset,
limit: this._limit,
orderby: instance.web.serialize_sort(this._order_by) || false
@@ -325,7 +328,7 @@ instance.web.Model = instance.web.Class.extend({
* Fetches the model's domain, combined with the provided domain if any
*
* @param {Array} [domain] to combine with the model's internal domain
- * @returns The model's internal domain, or the AND-ed union of the model's internal domain and the provided domain
+ * @returns {instance.web.CompoundDomain} The model's internal domain, or the AND-ed union of the model's internal domain and the provided domain
*/
domain: function (domain) {
if (!domain) { return this._domain; }
@@ -337,7 +340,7 @@ instance.web.Model = instance.web.Class.extend({
* combined with the provided context if any
*
* @param {Object} [context] to combine with the model's internal context
- * @returns The union of the user's context and the model's internal context, as well as the provided context if any. In that order.
+ * @returns {instance.web.CompoundContext} The union of the user's context and the model's internal context, as well as the provided context if any. In that order.
*/
context: function (context) {
return new instance.web.CompoundContext(
@@ -487,7 +490,12 @@ instance.web.DataSet = instance.web.Class.extend(instance.web.PropertiesMixin,
* @returns {$.Deferred}
*/
create: function(data, options) {
- return this._model.call('create', [data], {context: this.get_context()});
+ var self = this;
+ return this._model.call('create', [data], {
+ context: this.get_context()
+ }).done(function () {
+ self.trigger('dataset_changed', data, options)
+ });
},
/**
* Saves the provided data in an existing db record
@@ -502,7 +510,12 @@ instance.web.DataSet = instance.web.Class.extend(instance.web.PropertiesMixin,
*/
write: function (id, data, options) {
options = options || {};
- return this._model.call('write', [[id], data], {context: this.get_context(options.context)}).done(this.trigger('dataset_changed', id, data, options));
+ var self = this;
+ return this._model.call('write', [[id], data], {
+ context: this.get_context(options.context)
+ }).done(function () {
+ self.trigger('dataset_changed', id, data, options)
+ });
},
/**
* Deletes an existing record from the database
@@ -510,7 +523,12 @@ instance.web.DataSet = instance.web.Class.extend(instance.web.PropertiesMixin,
* @param {Number|String} ids identifier of the record to delete
*/
unlink: function(ids) {
- return this._model.call('unlink', [ids], {context: this.get_context()}).done(this.trigger('dataset_changed', ids));
+ var self = this;
+ return this._model.call('unlink', [ids], {
+ context: this.get_context()
+ }).done(function () {
+ self.trigger('dataset_changed', ids)
+ });
},
/**
* Calls an arbitrary RPC method
@@ -604,6 +622,13 @@ instance.web.DataSet = instance.web.Class.extend(instance.web.PropertiesMixin,
alter_ids: function(n_ids) {
this.ids = n_ids;
},
+ remove_ids: function (ids) {
+ this.alter_ids(_(this.ids).difference(ids));
+ },
+ add_ids: function(ids, at) {
+ var args = [at, 0].concat(_.difference(ids, this.ids));
+ this.ids.splice.apply(this.ids, args);
+ },
/**
* Resequence records.
*
@@ -701,22 +726,28 @@ instance.web.DataSetSearch = instance.web.DataSet.extend({
get_domain: function (other_domain) {
this._model.domain(other_domain);
},
+ alter_ids: function (ids) {
+ this._super(ids);
+ if (this.index !== null && this.index >= this.ids.length) {
+ this.index = this.ids.length > 0 ? this.ids.length - 1 : 0;
+ }
+ },
+ remove_ids: function (ids) {
+ var before = this.ids.length;
+ this._super(ids);
+ if (this._length) {
+ this._length -= (before - this.ids.length);
+ }
+ },
unlink: function(ids, callback, error_callback) {
var self = this;
return this._super(ids).done(function(result) {
- self.ids = _(self.ids).difference(ids);
- if (self._length) {
- self._length -= 1;
- }
- if (self.index !== null) {
- self.index = self.index <= self.ids.length - 1 ?
- self.index : (self.ids.length > 0 ? self.ids.length -1 : 0);
- }
+ self.remove_ids( ids);
self.trigger("dataset_changed", ids, callback, error_callback);
});
},
size: function () {
- if (this._length !== undefined) {
+ if (this._length != null) {
return this._length;
}
return this._super();
diff --git a/addons/web/static/src/js/data_export.js b/addons/web/static/src/js/data_export.js
index e38d21d1cd2..fb5e391effd 100644
--- a/addons/web/static/src/js/data_export.js
+++ b/addons/web/static/src/js/data_export.js
@@ -4,15 +4,34 @@ var QWeb = instance.web.qweb,
instance.web.DataExport = instance.web.Dialog.extend({
template: 'ExportTreeView',
dialog_title: {toString: function () { return _t("Export Data"); }},
+ events: {
+ 'click #add_field': function () {
+ var self = this;
+ this.$('#field-tree-structure tr.ui-selected')
+ .removeClass('ui-selected')
+ .find('a').each(function () {
+ var id = $(this).attr('id').split('-')[1];
+ var string = $(this).attr('string');
+ self.add_field(id, string);
+ });
+ },
+ 'click #remove_field': function () {
+ this.$('#fields_list option:selected').remove();
+ },
+ 'click #remove_all_field': function () {
+ this.$('#fields_list').empty();
+ },
+ 'click #export_new_list': 'on_show_save_list',
+ },
init: function(parent, dataset) {
var self = this;
- options = {
- buttons : [
- {text: _t("Close"), click: function() { self.close(); }},
- {text: _t("Export To File"), click: function() { self.on_click_export_data(); }}
+ var options = {
+ buttons: [
+ {text: _t("Close"), click: function () { self.close(); }},
+ {text: _t("Export To File"), click: function () { self.on_click_export_data(); }}
],
- close: function(event, ui){ self.close();}
- }
+ close: function () { self.close();}
+ };
this._super(parent, options);
this.records = {};
this.dataset = dataset;
@@ -23,24 +42,6 @@ instance.web.DataExport = instance.web.Dialog.extend({
var self = this;
this._super.apply(this, arguments);
self.$el.removeClass('ui-dialog-content ui-widget-content');
- self.$el.find('#add_field').click(function() {
- if ($('#field-tree-structure tr.ui-selected')) {
- var fld = self.$el.find('#field-tree-structure tr.ui-selected').find('a');
- for (var i = 0; i < fld.length; i++) {
- var id = $(fld[i]).attr('id').split('-')[1];
- var string = $(fld[i]).attr('string');
- self.add_field(id, string);
- }
- self.$el.find('#field-tree-structure tr').removeClass('ui-selected');
- }
- });
- self.$el.find('#remove_field').click(function() {
- self.$el.find('#fields_list option:selected').remove();
- });
- self.$el.find('#remove_all_field').click(function() {
- self.$el.find('#fields_list').empty();
- });
- this.$el.find('#export_new_list').click(this.on_show_save_list);
var got_fields = new $.Deferred();
this.$el.find('#import_compat').change(function() {
@@ -49,7 +50,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
var import_comp = self.$el.find("#import_compat").val();
self.rpc("/web/export/get_fields", {
model: self.dataset.model,
- import_compat: Boolean(import_comp)
+ import_compat: !!import_comp,
}).done(function (records) {
got_fields.resolve();
self.on_show_data(records);
@@ -79,7 +80,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
var self = this;
if (self.$el.find('#saved_export_list').is(':hidden')) {
self.$el.find('#ExistsExportList').show();
- return;
+ return $.when();
}
return this.exports.read_slice(['name'], {
domain: [['resource', '=', this.dataset.model]]
@@ -192,7 +193,6 @@ instance.web.DataExport = instance.web.Dialog.extend({
},
on_show_data: function(result, after) {
var self = this;
- var imp_cmpt = Boolean(self.$el.find("#import_compat").val());
if (after) {
var current_tr = self.$el.find("tr[id='treerow-" + after + "']");
@@ -220,15 +220,16 @@ instance.web.DataExport = instance.web.Dialog.extend({
frst_click = self.$el.find("tr[id^='treerow-']")[self.row_index-1];
$(frst_click).addClass("ui-selected");
} else {
+ var i;
if (this.rowIndex >=self.row_index) {
- for (var i = (self.row_index-1); i < this.rowIndex; i++) {
+ for (i = (self.row_index-1); i < this.rowIndex; i++) {
scnd_click = self.$el.find("tr[id^='treerow-']")[i];
if (!$(scnd_click).find('#tree-column').hasClass("oe_export_readonlyfield")) {
$(scnd_click).addClass("ui-selected");
}
}
} else {
- for (var i = (self.row_index-1); i >= (this.rowIndex-1); i--) {
+ for (i = (self.row_index-1); i >= (this.rowIndex-1); i--) {
scnd_click = self.$el.find("tr[id^='treerow-']")[i];
if (!$(scnd_click).find('#tree-column').hasClass("oe_export_readonlyfield")) {
$(scnd_click).addClass("ui-selected");
@@ -263,6 +264,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
self.$el.find("tr[id='treerow-" + record.id + "']").keydown(function(e) {
var keyCode = e.keyCode || e.which;
var arrow = {left: 37, up: 38, right: 39, down: 40 };
+ var elem;
switch (keyCode) {
case arrow.left:
if ($(this).hasClass('open')) {
@@ -275,7 +277,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
}
break;
case arrow.up:
- var elem = this;
+ elem = this;
$(elem).removeClass("ui-selected");
while (!$(elem).prev().is(":visible")) {
elem = $(elem).prev();
@@ -286,7 +288,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
$(elem).prev().find('a').focus();
break;
case arrow.down:
- var elem = this;
+ elem = this;
$(elem).removeClass("ui-selected");
while(!$(elem).next().is(":visible")) {
elem = $(elem).next();
@@ -353,14 +355,13 @@ instance.web.DataExport = instance.web.Dialog.extend({
}
},
get_fields: function() {
- var export_field = [];
- this.$el.find("#fields_list option").each(function() {
- export_field.push($(this).val());
- });
- if (!export_field.length) {
+ var export_fields = this.$("#fields_list option").map(function() {
+ return $(this).val();
+ }).get();
+ if (!export_fields.length) {
alert(_t("Please select fields to save export list..."));
}
- return export_field;
+ return export_fields;
},
on_click_export_data: function() {
var self = this;
@@ -374,21 +375,24 @@ instance.web.DataExport = instance.web.Dialog.extend({
alert(_t("Please select fields to export..."));
return;
}
-
exported_fields.unshift({name: 'id', label: 'External ID'});
+
var export_format = this.$el.find("#export_format").val();
+ var ids_to_export = this.$('#export_selection_only').prop('checked')
+ ? this.getParent().get_selected_ids()
+ : this.dataset.ids;
+
instance.web.blockUI();
this.session.get_file({
url: '/web/export/' + export_format,
data: {data: JSON.stringify({
model: this.dataset.model,
fields: exported_fields,
- ids: this.dataset.ids,
+ ids: ids_to_export,
domain: this.dataset.domain,
- import_compat: Boolean(
- this.$el.find("#import_compat").val())
+ import_compat: !!this.$el.find("#import_compat").val(),
})},
- complete: instance.web.unblockUI
+ complete: instance.web.unblockUI,
});
},
close: function() {
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index f5449ed8bba..cef92ccf293 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -131,6 +131,7 @@ my.InputView = instance.web.Widget.extend({
paste: 'onPaste',
},
getSelection: function () {
+ this.el.normalize();
// get Text node
var root = this.el.childNodes[0];
if (!root || !root.textContent) {
@@ -139,6 +140,16 @@ my.InputView = instance.web.Widget.extend({
return {start: 0, end: 0};
}
var range = window.getSelection().getRangeAt(0);
+ // In Firefox, depending on the way text is selected (drag, double- or
+ // triple-click) the range may start or end on the parent of the
+ // selected text node‽ Check for this condition and fixup the range
+ // note: apparently with C-a this can go even higher?
+ if (range.startContainer === this.el && range.startOffset === 0) {
+ range.setStart(root, 0);
+ }
+ if (range.endContainer === this.el && range.endOffset === 1) {
+ range.setEnd(root, root.length)
+ }
assert(range.startContainer === root,
"selection should be in the input view");
assert(range.endContainer === root,
@@ -149,6 +160,7 @@ my.InputView = instance.web.Widget.extend({
}
},
onKeydown: function (e) {
+ this.el.normalize();
var sel;
switch (e.which) {
// Do not insert newline, but let it bubble so searchview can use it
@@ -186,6 +198,7 @@ my.InputView = instance.web.Widget.extend({
}
},
setCursorAtEnd: function () {
+ this.el.normalize();
var sel = window.getSelection();
sel.removeAllRanges();
var range = document.createRange();
@@ -196,13 +209,14 @@ my.InputView = instance.web.Widget.extend({
// from about half the link to half the text, paste in search box then
// hit the left arrow key, getSelection would blow up).
//
- // Explicitly selecting only the inner text node (only child node at
- // this point, though maybe we should assert that) avoiids the issue
+ // Explicitly selecting only the inner text node (only child node
+ // since we've normalized the parent) avoids the issue
range.selectNode(this.el.childNodes[0]);
range.collapse(false);
sel.addRange(range);
},
onPaste: function () {
+ this.el.normalize();
// In MSIE and Webkit, it is possible to get various representations of
// the clipboard data at this point e.g.
// window.clipboardData.getData('Text') and
@@ -224,6 +238,7 @@ my.InputView = instance.web.Widget.extend({
var data = this.$el.text();
// paste raw text back in
this.$el.empty().text(data);
+ this.el.normalize();
// Set the cursor at the end of the text, so the cursor is not lost
// in some kind of error-spawning limbo.
this.setCursorAtEnd();
@@ -326,7 +341,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
}
},
'autocompleteopen': function () {
- this.$el.autocomplete('widget').css('z-index', 3);
+ this.$el.autocomplete('widget').css('z-index', 1004);
},
},
/**
@@ -449,11 +464,12 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
var autocomplete = this.$el.autocomplete({
source: this.proxy('complete_global_search'),
select: this.proxy('select_completion'),
+ search: function () { self.$el.autocomplete('close'); },
focus: function (e) { e.preventDefault(); },
html: true,
autoFocus: true,
minLength: 1,
- delay: 0
+ delay: 0,
}).data('autocomplete');
// MonkeyPatch autocomplete instance
@@ -526,7 +542,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
var val = this.$el.val();
this.$el.val('');
var complete = this.$el.data('autocomplete');
- if ((val && complete.term === undefined) || complete.previous !== undefined) {
+ if ((val && complete.term === undefined) || complete.previous) {
throw new Error("new jquery.ui version altering implementation" +
" details relied on");
}
@@ -1039,7 +1055,9 @@ instance.web.search.FilterGroup = instance.web.search.Input.extend(/** @lends in
facet.values.each(function (v) {
var i = _(self.filters).indexOf(v.get('value'));
if (i === -1) { return; }
- $filters.eq(i).addClass('oe_selected');
+ $filters.filter(function () {
+ return Number($(this).data('index')) === i;
+ }).addClass('oe_selected');
});
},
/**
@@ -1129,7 +1147,7 @@ instance.web.search.FilterGroup = instance.web.search.Input.extend(/** @lends in
});
},
toggle_filter: function (e) {
- this.toggle(this.filters[$(e.target).index()]);
+ this.toggle(this.filters[Number($(e.target).data('index'))]);
},
toggle: function (filter) {
this.view.query.toggle(this.make_facet([this.make_value(filter)]));
@@ -1337,20 +1355,22 @@ instance.web.search.CharField = instance.web.search.Field.extend( /** @lends ins
}
});
instance.web.search.NumberField = instance.web.search.Field.extend(/** @lends instance.web.search.NumberField# */{
- value_from: function () {
- if (!this.$el.val()) {
- return null;
- }
- var val = this.parse(this.$el.val()),
- check = Number(this.$el.val());
- if (isNaN(val) || val !== check) {
- this.$el.addClass('error');
- throw new instance.web.search.Invalid(
- this.attrs.name, this.$el.val(), this.error_message);
- }
- this.$el.removeClass('error');
- return val;
- }
+ complete: function (value) {
+ var val = this.parse(value);
+ if (isNaN(val)) { return $.when(); }
+ var label = _.str.sprintf(
+ _t("Search %(field)s for: %(value)s"), {
+ field: '<em>' + this.attrs.string + '</em>',
+ value: '<strong>' + _.str.escapeHTML(value) + '</strong>'});
+ return $.when([{
+ label: label,
+ facet: {
+ category: this.attrs.string,
+ field: this,
+ values: [{label: value, value: val}]
+ }
+ }]);
+ },
});
/**
* @class
@@ -1888,7 +1908,7 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @
this._super(parent);
this.fields = _(fields).chain()
.map(function(val, key) { return _.extend({}, val, {'name': key}); })
- .filter(function (field) { return !field.deprecated; })
+ .filter(function (field) { return !field.deprecated && (field.store === void 0 || field.store || field.fnct_search); })
.sortBy(function(field) {return field.string;})
.value();
this.attrs = {_: _, fields: this.fields, selected: null};
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 32e86d69bed..d2f55c0901e 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -213,9 +213,9 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
}
});
//bounce effect on red button when click on statusbar.
- this.$el.on('click', '.oe_form_field_status:not(.oe_form_status_clickable)', function (e) {
- if(self.get("actual_mode") == "view") {
- var $button = self.$el.find(".oe_highlight:not(.oe_form_invisible)").css({'float':'left','margin-left':'3px','margin-right':'2px','white-space':'nowrap'});
+ this.$el.find(".oe_form_field_status:not(.oe_form_status_clickable)").on('click', function (e) {
+ if((self.get("actual_mode") == "view")) {
+ var $button = self.$el.find(".oe_highlight:not(.oe_form_invisible)").css({'float':'left','clear':'none'});
$button.openerpBounce();
e.stopPropagation();
}
@@ -2721,6 +2721,11 @@ instance.web.form.FieldTextHtml = instance.web.form.AbstractField.extend(instanc
self.internal_set_value(self.$textarea.val());
}
});
+ if (this.field.translate) {
+ var $img = $('<img class="oe_field_translate oe_input_icon" src="/web/static/src/img/icons/terp-translate.png" width="16" height="16" border="0"/>')
+ .click(this.on_translate);
+ this.$cleditor.$toolbar.append($img);
+ }
}
},
render_value: function() {
@@ -3241,6 +3246,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
self.display_value_backup = {};
self.render_value();
self.focus();
+ self.view.do_onchange(self);
});
});
@@ -4217,7 +4223,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
ext: {
autocomplete: {
selectFromDropdown: function() {
- $(this).trigger('hideDropdown');
+ this.trigger('hideDropdown');
var index = Number(this.selectedSuggestionElement().children().children().data('index'));
var data = self.search_result[index];
if (data.id) {
@@ -4226,6 +4232,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
ignore_blur = true;
data.action();
}
+ this.trigger('setSuggestions', {result : []});
},
},
tags: {
@@ -4762,13 +4769,13 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.extend({
this.dataset.index = null;
}
var options = _.clone(self.options.form_view_options) || {};
+ if (this.row_id !== null) {
+ options.initial_mode = this.options.readonly ? "view" : "edit";
+ }
_.extend(options, {
$buttons: this.$buttonpane,
});
this.view_form = new instance.web.FormView(this, this.dataset, this.options.view_id || false, options);
- if (this.row_id !== null) {
- options.initial_mode = this.options.readonly ? "view" : this.view_form.options.initial_mode;
- }
if (this.options.alternative_form_view) {
this.view_form.set_embedded_view(this.options.alternative_form_view);
}
@@ -4960,7 +4967,7 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
this.searchview.hide();
}
if (this.view_list) {
- this.view_list.$el.hide();
+ this.view_list.do_hide();
}
this.setup_form_view();
},
@@ -5546,7 +5553,12 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
on_click_stage: function (ev) {
var self = this;
var $li = $(ev.currentTarget);
- var val = parseInt($li.data("id"));
+ if (this.field.type == "many2one") {
+ var val = parseInt($li.data("id"));
+ }
+ else {
+ var val = $li.data("id");
+ }
if (val != self.get('value')) {
this.view.recursive_save().done(function() {
var change = {};
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index 840effa9221..4f58b002328 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -503,12 +503,9 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
var reloaded = $.Deferred();
this.$el.find('.oe_list_content').append(
this.groups.render(function () {
- if (self.dataset.index == null) {
- var has_one = false;
- self.records.each(function () { has_one = true; });
- if (has_one) {
+ if (self.dataset.index == null && self.records.length ||
+ self.dataset.index >= self.records.length) {
self.dataset.index = 0;
- }
}
self.compute_aggregates();
reloaded.resolve();
@@ -530,12 +527,13 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
return r.tag === 'field';
}), 'name')
).done(function (records) {
- if (!records[0]) {
+ var values = records[0];
+ if (!values) {
self.records.remove(record);
return;
}
- _(records[0]).each(function (value, key) {
- record.set(key, value, {silent: true});
+ _(_.keys(values)).each(function(key){
+ record.set(key, values[key], {silent: true});
});
record.trigger('change', record);
});
@@ -896,7 +894,7 @@ instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web.
this.record_callbacks = {
'remove': function (event, record) {
var id = record.get('id');
- self.dataset.remove_ids([id])
+ self.dataset.remove_ids([id]);
var $row = self.$current.children('[data-id=' + id + ']');
var index = $row.data('index');
$row.remove();
@@ -909,12 +907,7 @@ instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web.
throw new Error(_.str.sprintf( _t("Setting 'id' attribute on existing record %s"),
JSON.stringify(record.attributes) ));
}
- if (!_.contains(self.dataset.ids, value)) {
- // add record to dataset if not already in (added by
- // the form view?)
- self.dataset.ids.splice(
- self.records.indexOf(record), 0, value);
- }
+ self.dataset.add_ids([value], self.records.indexOf(record));
// Set id on new record
$row = self.$current.children('[data-id=false]');
} else {
@@ -925,6 +918,8 @@ instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web.
},
'add': function (ev, records, record, index) {
var $new_row = $(self.render_record(record));
+ var id = record.get('id');
+ if (id) { self.dataset.add_ids([id], index); }
if (index === 0) {
$new_row.prependTo(self.$current);
diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js
index 4e042b60c5d..512fc4ff373 100644
--- a/addons/web/static/src/js/view_list_editable.js
+++ b/addons/web/static/src/js/view_list_editable.js
@@ -429,7 +429,6 @@ openerp.web.list_editable = function (instance) {
var index = this.records.indexOf(source_record) + 1;
record = this.make_empty_record(id);
this.records.add(record, {at: index});
- this.dataset.ids.splice(index, 0, id);
}
return this.reload_record(record);
},
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index fdb2eeee329..78d733110d8 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -1363,8 +1363,8 @@ instance.web.View = instance.web.Widget.extend({
}
args.push(context);
return dataset.call_button(action_data.name, args).then(handler).then(function () {
- if (self.ViewManager.ActionManager) {
- self.ViewManager.ActionManager.__parentedParent.menu.do_reload_needaction();
+ if (instance.webclient) {
+ instance.webclient.menu.do_reload_needaction();
}
});
} else if (action_data.type=="action") {