summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js
diff options
context:
space:
mode:
authorParamjit Singh Sahota <psa@tinyerp.com>2012-07-09 14:26:35 +0530
committerParamjit Singh Sahota <psa@tinyerp.com>2012-07-09 14:26:35 +0530
commit2774263ddda67b6983d1c00a04da00e18ff53b85 (patch)
tree3b2a8ec5fdccacc2983905f191167d5efdfeddc3 /addons/web/static/src/js
parent202238473c6eb90e539028d553265eb1ec43c87a (diff)
parent4d2255a2b3390653f58a17502f7be37b5ec15089 (diff)
[MERGE] Merged from openerp-web.
bzr revid: psa@tinyerp.com-20120709085635-g0tcm7nlqe7wd3n3
Diffstat (limited to 'addons/web/static/src/js')
-rw-r--r--addons/web/static/src/js/chrome.js90
-rw-r--r--addons/web/static/src/js/corelib.js6
-rw-r--r--addons/web/static/src/js/coresetup.js45
-rw-r--r--addons/web/static/src/js/search.js72
-rw-r--r--addons/web/static/src/js/view_form.js112
-rw-r--r--addons/web/static/src/js/view_list.js16
-rw-r--r--addons/web/static/src/js/views.js7
7 files changed, 216 insertions, 132 deletions
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index 76a6b561f64..b87ebe56856 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -136,14 +136,18 @@ instance.web.Dialog = instance.web.Widget.extend({
},
on_close: function() {
if (this.dialog_options.destroy_on_close) {
- this.$element.dialog('destroy');
+ this.destroy();
}
},
on_resized: function() {
},
destroy: function () {
- this.close();
- this.$element.dialog('destroy');
+ _.each(this.getChildren(), function(el) {
+ el.destroy();
+ });
+ if (! this.isDestroyed()) {
+ this.$element.dialog('destroy');
+ }
this._super();
}
});
@@ -401,7 +405,14 @@ instance.web.DatabaseManager = instance.web.Widget.extend({
success: function () {
self.do_notify(_t("Backed"), _t("Database backed up successfully"));
},
- error: instance.webclient.crashmanager.on_rpc_error,
+ error: function(error){
+ if(error){
+ self.display_error({
+ title: 'Backup Database',
+ error: 'AccessDenied'
+ });
+ }
+ },
complete: function() {
self.unblockUI();
}
@@ -538,6 +549,7 @@ instance.web.Login = instance.web.Widget.extend({
do_login: function (db, login, password) {
var self = this;
this.$element.removeClass('oe_login_invalid');
+ self.$(".oe_login_pane").fadeOut("slow");
return this.session.session_authenticate(db, login, password).pipe(function() {
if (self.has_local_storage) {
if(self.remember_credentials) {
@@ -552,9 +564,9 @@ instance.web.Login = instance.web.Widget.extend({
localStorage.setItem('last_password_login_success', '');
}
}
- self.$(".oe_login_pane").fadeOut("slow");
self.trigger("login");
},function () {
+ self.$(".oe_login_pane").fadeIn("fast");
self.$element.addClass("oe_login_invalid");
});
}
@@ -571,6 +583,7 @@ instance.web.Menu = instance.web.Widget.extend({
start: function() {
this._super.apply(this, arguments);
this.$secondary_menus = this.getParent().$element.find('.oe_secondary_menus_container');
+ this.$secondary_menus.on('click', 'a[data-menu]', this.on_menu_click);
return this.do_reload();
},
do_reload: function() {
@@ -583,7 +596,6 @@ instance.web.Menu = instance.web.Widget.extend({
this.limit_entries();
this.$secondary_menus.html(QWeb.render("Menu.secondary", { widget : this }));
this.$element.on('click', 'a[data-menu]', this.on_menu_click);
- this.$secondary_menus.on('click', 'a[data-menu]', this.on_menu_click);
// Hide second level submenus
this.$secondary_menus.find('.oe_menu_toggler').siblings('.oe_secondary_submenu').hide();
if (self.current_menu) {
@@ -665,32 +677,37 @@ instance.web.Menu = instance.web.Widget.extend({
* Process a click on a menu item
*
* @param {Number} id the menu_id
+ * @param {Boolean} [needaction=false] whether the triggered action should execute in a `needs action` context
*/
- menu_click: function(id) {
- if (id) {
- // find back the menuitem in dom to get the action
- var $item = this.$element.find('a[data-menu=' + id + ']');
- if (!$item.length) {
- $item = this.$secondary_menus.find('a[data-menu=' + id + ']');
- }
- var action_id = $item.data('action-id');
- // If first level menu doesnt have action trigger first leaf
- if (!action_id) {
- if(this.$element.has($item).length) {
- $sub_menu = this.$secondary_menus.find('.oe_secondary_menu[data-menu-parent=' + id + ']');
- $items = $sub_menu.find('a[data-action-id]').filter('[data-action-id!=""]');
- if($items.length) {
- action_id = $items.data('action-id');
- id = $items.data('menu');
- }
+ menu_click: function(id, needaction) {
+ if (!id) { return; }
+
+ // find back the menuitem in dom to get the action
+ var $item = this.$element.find('a[data-menu=' + id + ']');
+ if (!$item.length) {
+ $item = this.$secondary_menus.find('a[data-menu=' + id + ']');
+ }
+ var action_id = $item.data('action-id');
+ // If first level menu doesnt have action trigger first leaf
+ if (!action_id) {
+ if(this.$element.has($item).length) {
+ var $sub_menu = this.$secondary_menus.find('.oe_secondary_menu[data-menu-parent=' + id + ']');
+ var $items = $sub_menu.find('a[data-action-id]').filter('[data-action-id!=""]');
+ if($items.length) {
+ action_id = $items.data('action-id');
+ id = $items.data('menu');
}
}
- this.open_menu(id);
- this.current_menu = id;
- this.session.active_id = id;
- if (action_id) {
- this.trigger('menu_click', action_id, id, $item);
- }
+ }
+ this.open_menu(id);
+ this.current_menu = id;
+ this.session.active_id = id;
+ if (action_id) {
+ this.trigger('menu_click', {
+ action_id: action_id,
+ needaction: needaction,
+ id: id
+ }, $item);
}
},
/**
@@ -700,7 +717,8 @@ instance.web.Menu = instance.web.Widget.extend({
*/
on_menu_click: function(ev) {
ev.preventDefault();
- this.menu_click($(ev.currentTarget).data('menu'));
+ var needaction = $(ev.target).is('div.oe_menu_counter');
+ this.menu_click($(ev.currentTarget).data('menu'), needaction);
},
});
@@ -1010,8 +1028,16 @@ instance.web.WebClient = instance.web.Widget.extend({
this._current_state = _.clone(state);
$.bbq.pushState(url);
},
- on_menu_action: function(action) {
- this.action_manager.do_action(action);
+ on_menu_action: function(options) {
+ var self = this;
+ this.rpc("/web/action/load", { action_id: options.action_id })
+ .then(function (result) {
+ var action = result.result;
+ if (options.needaction) {
+ action.context.search_default_needaction_pending = true;
+ }
+ self.action_manager.do_action(action);
+ });
},
do_action: function(action) {
var self = this;
diff --git a/addons/web/static/src/js/corelib.js b/addons/web/static/src/js/corelib.js
index 988c419182b..a200f272a91 100644
--- a/addons/web/static/src/js/corelib.js
+++ b/addons/web/static/src/js/corelib.js
@@ -1314,19 +1314,19 @@ instance.web.JsonRPC = instance.web.CallbackEnabled.extend({
} else {
// Indirect jsonp request
var ifid = _.uniqueId('oe_rpc_iframe');
- var display = options.openerp.debug ? 'block' : 'none';
+ var display = self.debug ? 'block' : 'none';
var $iframe = $(_.str.sprintf("<iframe src='javascript:false;' name='%s' id='%s' style='display:%s'></iframe>", ifid, ifid, display));
var $form = $('<form>')
.attr('method', 'POST')
.attr('target', ifid)
.attr('enctype', "multipart/form-data")
- .attr('action', ajax.url + '?' + $.param(data))
+ .attr('action', ajax.url + '?jsonp=1&' + $.param(data))
.append($('<input type="hidden" name="r" />').attr('value', payload_str))
.hide()
.appendTo($('body'));
var cleanUp = function() {
if ($iframe) {
- $iframe.unbind("load").attr("src", "javascript:false;").remove();
+ $iframe.unbind("load").remove();
}
$form.remove();
};
diff --git a/addons/web/static/src/js/coresetup.js b/addons/web/static/src/js/coresetup.js
index 955a46e6923..a00ca4002e5 100644
--- a/addons/web/static/src/js/coresetup.js
+++ b/addons/web/static/src/js/coresetup.js
@@ -334,11 +334,14 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess
.appendTo(document.body)
.load(function () {
try {
- if (options.error) {
- options.error(JSON.parse(
- this.contentDocument.body.childNodes[1].textContent
- ));
- }
+ if (options.error) {
+ if (!this.contentDocument.body.childNodes[1]) {
+ options.error(this.contentDocument.body.childNodes);
+ }
+ else {
+ options.error(JSON.parse(this.contentDocument.body.childNodes[1].textContent));
+ }
+ }
} finally {
complete();
}
@@ -605,15 +608,31 @@ instance.web.qweb.preprocess_node = function() {
};
/** Setup jQuery timeago */
-var timeago_setup = function () {
- var s = $.timeago.settings.strings;
- _.each(s, function(v,k) {
- if(_.isString(v)) {
- s[k] = instance.web._t(v);
- }
- });
+var _t = instance.web._t;
+/*
+ * Strings in timeago are "composed" with prefixes, words and suffixes. This
+ * makes their detection by our translating system impossible. Use all literal
+ * strings we're using with a translation mark here so the extractor can do its
+ * job.
+ */
+{
+ _t('less than a minute ago');
+ _t('about a minute ago');
+ _t('%d minutes ago');
+ _t('about an hour ago');
+ _t('%d hours ago');
+ _t('a day ago');
+ _t('%d days ago');
+ _t('about a month ago');
+ _t('%d months ago');
+ _t('about a year ago');
+ _t('%d years ago');
}
-instance.connection.on('module_loaded', this, timeago_setup);
+
+instance.connection.on('module_loaded', this, function () {
+ // provide timeago.js with our own translator method
+ $.timeago.settings.translator = instance.web._t;
+});
/**
* Registry for all the client actions key: tag value: widget
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index 169c7053575..c8b6f797dba 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -352,6 +352,11 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
e.stopImmediatePropagation();
self.$element.toggleClass('oe_searchview_open_drawer');
});
+ instance.web.bus.on('click', this, function(ev) {
+ if ($(ev.target).parents('.oe_searchview').length === 0) {
+ self.$element.removeClass('oe_searchview_open_drawer');
+ }
+ });
// Focus last input if the view itself is clicked (empty section of
// facets element)
this.$element.on('click', function (e) {
@@ -635,12 +640,13 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
(new instance.web.search.CustomFilters(this));
// add Advanced to this.inputs
(new instance.web.search.Advanced(this));
- (new instance.web.search.AddToDashboard(this));
// build drawer
var drawer_started = $.when.apply(
null, _(this.select_for_drawer()).invoke(
'appendTo', this.$element.find('.oe_searchview_drawer')));
+
+ new instance.web.search.AddToDashboard(this).appendTo($('.oe_searchview_drawer', this.$element));
// load defaults
var defaults_fetched = $.when.apply(null, _(this.inputs).invoke(
@@ -1188,7 +1194,7 @@ instance.web.search.Field = instance.web.search.Input.extend( /** @lends instanc
var self = this;
// A field needs a context to send when active
var context = this.attrs.context;
- if (!context || !facet.values.length) {
+ if (_.isEmpty(context) || !facet.values.length) {
return;
}
var contexts = facet.values.map(function (facetValue) {
@@ -1484,6 +1490,15 @@ instance.web.search.ManyToOneField = instance.web.search.CharField.extend({
return [[name, '=', facetValue.get('value')]];
}
return this._super(name, operator, facetValue);
+ },
+ get_context: function (facet) {
+ var values = facet.values;
+ if (_.isEmpty(this.attrs.context) && values.length === 1) {
+ var c = {};
+ c['default_' + this.attrs.name] = values.at(0).get('value');
+ return c;
+ }
+ return this._super(facet);
}
});
@@ -1638,7 +1653,7 @@ instance.web.search.Filters = instance.web.search.Input.extend({
}));
}
});
-instance.web.search.AddToDashboard = instance.web.search.Input.extend({
+instance.web.search.AddToDashboard = instance.web.Widget.extend({
template: 'SearchView.addtodashboard',
_in_drawer: true,
start: function () {
@@ -1646,44 +1661,18 @@ instance.web.search.AddToDashboard = instance.web.search.Input.extend({
this.data_loaded = $.Deferred();
this.dashboard_data =[];
this.$element
- .on('click', 'h4', this.proxy('show_option'))
- .on('submit', 'form', function (e) {e.preventDefault(); self.add_dashboard();});
+ .on('click', 'h4', this.proxy('show_option'))
+ .on('submit', 'form', function (e) {
+ e.preventDefault();
+ self.add_dashboard();
+ });
return $.when(this.load_data(),this.data_loaded).pipe(this.proxy("render_data"));
},
load_data:function(){
- // get from database if dashboard position change than also works(from Reporting to else).
- /*var self = this,
- ir_actions_act_window = new instance.web.Model('ir.actions.act_window',{},[['res_model','=',"board.board"],['view_id','!=',false]])
- .query(['name','id']),
- map_data = function(){
- var ir_actions_values = arguments[0],ir_values = arguments[1];
- _(ir_values).each(function(res){
- var get_name = _.detect(ir_actions_values,function(name){ return name.id == parseInt((res.value).split(",")[1]);});
- self.dashboard_data.push({"res_id":res.res_id,"name":get_name.name})
- });
- self.data_loaded.resolve();
- },
- make_domain = function(result){
- var domain = [];
- _(result).map(function(value,key){
- domain.push(["value","=","ir.actions.act_window,"+value.id]);
- ((result.length)- 1 !== key)?domain.unshift("|"):false;
- })
- return domain;
- };
- return ir_actions_act_window._execute().then(function(ir_actions_values){
- if(!ir_actions_values.length) {self.data_loaded.resolve();return;}
- var ir_value = new instance.web.Model('ir.values',{},make_domain(ir_actions_values)).query(['res_id','value']);
- ir_value._execute().done(function(ir_values){
- map_data(ir_actions_values,ir_values);
- })
- });*/
-
- //===============================get from instance.webclient.menu (with less rpc call)
- var self = this,dashbaord_menu = instance.webclient.menu.data.data.children,
- ir_model_data = new instance.web.Model('ir.model.data',{},[['name','=','menu_reporting_dashboard']]).query(['res_id']),
- map_data = function(result){
- _.detect(dashbaord_menu,function(dash){
+ var self = this,dashboard_menu = instance.webclient.menu.data.data.children;
+ var ir_model_data = new instance.web.Model('ir.model.data',{},[['name','=','menu_reporting_dashboard']]).query(['res_id']);
+ var map_data = function(result){
+ _.detect(dashboard_menu, function(dash){
var id = _.pluck(dash.children, "id"),indexof = _.indexOf(id, result.res_id);
if(indexof !== -1){
self.dashboard_data = dash.children[indexof].children
@@ -1701,8 +1690,10 @@ instance.web.search.AddToDashboard = instance.web.search.Input.extend({
this.$element.find("input").before(selection)
},
add_dashboard:function(){
- var self = this,getParent = this.getParent(),view_parent = this.view.getParent();
- if(!view_parent.action || !this.$element.find("select").val())
+ var self = this;
+ var getParent = this.getParent();
+ var view_parent = this.getParent().getParent();
+ if (! view_parent.action || ! this.$element.find("select").val())
return this.do_warn("Can't find dashboard action");
data = getParent.build_search_data(),
context = new instance.web.CompoundContext(getParent.dataset.get_context() || []),
@@ -1732,6 +1723,7 @@ instance.web.search.AddToDashboard = instance.web.search.Input.extend({
this.$element.find("input").val(this.getParent().fields_view.name || "" );
}
});
+
instance.web.search.Advanced = instance.web.search.Input.extend({
template: 'SearchView.advanced',
_in_drawer: true,
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index a2d849d5172..a65e471c6bf 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -333,9 +333,6 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
if (self.sidebar) {
self.sidebar.do_attachement_update(self.dataset, self.datarecord.id);
}
- if (self.default_focus_field) {
- self.default_focus_field.focus();
- }
if (record.id) {
self.do_push_state({id:record.id});
}
@@ -584,6 +581,16 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
_.each(this.fields,function(field){
field.set({"force_readonly": false});
});
+ var fields_order = self.fields_order.slice(0);
+ if (self.default_focus_field) {
+ fields_order.unshift(self.default_focus_field);
+ }
+ for (var i = 0; i < fields_order.length; i += 1) {
+ var field = self.fields[fields_order[i]];
+ if (!field.get('effective_invisible') && !field.get('effective_readonly') && field.focus() !== false) {
+ break;
+ }
+ }
}
},
on_button_save: function() {
@@ -728,7 +735,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
var msg = "<ul>";
_.each(this.fields, function(f) {
if (!f.is_valid()) {
- msg += "<li>" + (f.node.attrs.string || f.field.string) + "</li>";
+ msg += "<li>" + f.string + "</li>";
}
});
msg += "</ul>";
@@ -872,7 +879,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
return {
name: name,
- string: field.node.attrs.string || field.field.string,
+ string: field.string,
value: value,
displayed: displayed,
// convert undefined to false
@@ -921,6 +928,9 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
register_field: function(field, name) {
this.fields[name] = field;
this.fields_order.push(name);
+ if (field.node.attrs.default_focus == '1') {
+ this.default_focus_field = field;
+ }
field.on('focused', null, this.proxy('widgetFocused'))
.on('blurred', null, this.proxy('widgetBlurred'));
@@ -1525,7 +1535,9 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi
this._super.apply(this, arguments);
},
/**
- * Sets up blur/focus forwarding from DOM elements to a widget (`this`)
+ * Sets up blur/focus forwarding from DOM elements to a widget (`this`).
+ *
+ * This method is an utility method that is meant to be called by child classes.
*
* @param {jQuery} $e jQuery object of elements to bind focus/blur on
*/
@@ -1774,7 +1786,7 @@ instance.web.form.FieldInterface = {
*/
is_syntax_valid: function() {},
/**
- * Must set the focus on the field.
+ * Must set the focus on the field. Return false if field is not focusable.
*/
focus: function() {},
};
@@ -1804,6 +1816,7 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w
this.name = this.node.attrs.name;
this.field = this.field_manager.get_field(this.name);
this.widget = this.node.attrs.widget;
+ this.string = this.node.attrs.string || this.field.string || this.name;
this.set({'value': false});
this.set({required: this.modifiers['required'] === true});
@@ -1876,7 +1889,7 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w
is_false: function() {
return this.get('value') === false;
},
- _check_css_flags: function(show_invalid) {
+ _check_css_flags: function() {
if (this.field.translate) {
this.$element.find('.oe_field_translate').toggle(!this.field_manager.is_create_mode());
}
@@ -2458,15 +2471,16 @@ instance.web.form.CompletionFieldMixin = {
return this.orderer.add(dataset.name_search(
search_val, new instance.web.CompoundDomain(self.build_domain(), [["id", "not in", blacklist]]),
- 'ilike', this.limit + 1)).pipe(function(data) {
+ 'ilike', this.limit + 1, self.build_context())).pipe(function(data) {
self.last_search = data;
// possible selections for the m2o
var values = _.map(data, function(x) {
+ x[1] = x[1].split("\n")[0];
return {
label: _.str.escapeHTML(x[1]),
- value:x[1],
- name:x[1],
- id:x[0]
+ value: x[1],
+ name: x[1],
+ id: x[0],
};
});
@@ -2522,7 +2536,7 @@ instance.web.form.CompletionFieldMixin = {
pop.select_element(
self.field.relation,
{
- title: (view === 'search' ? _t("Search: ") : _t("Create: ")) + (this.string || this.name),
+ title: (view === 'search' ? _t("Search: ") : _t("Create: ")) + this.string,
initial_ids: ids ? _.map(ids, function(x) {return x[0]}) : undefined,
initial_view: view,
disable_multiple_selection: true
@@ -2591,7 +2605,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
self.get("value"),
self.build_context(),
{
- title: _t("Open: ") + (self.string || self.name)
+ title: _t("Open: ") + self.string
}
);
pop.on_write_completed.add_last(function() {
@@ -2720,7 +2734,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
return;
}
if (! no_recurse) {
- var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.view.dataset.get_context());
+ var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.build_context());
dataset.name_get([self.get("value")], function(data) {
self.display_value["" + self.get("value")] = data[0][1];
self.render_value(true);
@@ -2730,11 +2744,12 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
display_string: function(str) {
var self = this;
if (!this.get("effective_readonly")) {
- this.$input.val(str);
+ this.$input.val(str.split("\n")[0]);
} else {
+ str = _.escape(str).split("\n").join("<br />");
this.$element.find('a')
.unbind('click')
- .text(str)
+ .html(str)
.click(function () {
self.do_action({
type: 'ir.actions.act_window',
@@ -2752,7 +2767,9 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
var self = this;
if (value_ instanceof Array) {
this.display_value = {};
- this.display_value["" + value_[0]] = value_[1];
+ if (! this.get_definition_options().always_reload) {
+ this.display_value["" + value_[0]] = value_[1];
+ }
value_ = value_[0];
}
value_ = value_ || false;
@@ -2886,25 +2903,36 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
view.embedded_view = self.field.views[mode];
}
if(view.view_type === "list") {
- view.options.selectable = self.multi_selection;
- view.options.sortable = false;
+ _.extend(view.options, {
+ selectable: self.multi_selection,
+ sortable: false,
+ import_enabled: false,
+ });
if (self.get("effective_readonly")) {
- view.options.addable = null;
- view.options.deletable = null;
- view.options.reorderable = false;
+ _.extend(view.options, {
+ addable: null,
+ deletable: null,
+ reorderable: false,
+ });
}
} else if (view.view_type === "form") {
if (self.get("effective_readonly")) {
view.view_type = 'form';
}
- view.options.not_interactible_on_create = true;
+ _.extend(view.options, {
+ not_interactible_on_create: true,
+ });
} else if (view.view_type === "kanban") {
- view.options.confirm_on_delete = false;
+ _.extend(view.options, {
+ confirm_on_delete: false,
+ });
if (self.get("effective_readonly")) {
- view.options.action_buttons = false;
- view.options.quick_creatable = false;
- view.options.creatable = false;
- view.options.read_only_mode = true;
+ _.extend(view.options, {
+ action_buttons: false,
+ quick_creatable: false,
+ creatable: false,
+ read_only_mode: true,
+ });
}
}
views.push(view);
@@ -3117,7 +3145,7 @@ instance.web.form.One2ManyViewManager = instance.web.ViewManager.extend({
var id = self.o2m.dataset.index !== null ? self.o2m.dataset.ids[self.o2m.dataset.index] : null;
var pop = new instance.web.form.FormOpenPopup(self.o2m.view);
pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(), {
- title: _t("Open: ") + self.name,
+ title: _t("Open: ") + self.o2m.string,
create_function: function(data) {
return self.o2m.dataset.create(data).then(function(r) {
self.o2m.dataset.set_ids(self.o2m.dataset.ids.concat([r.result]));
@@ -3174,7 +3202,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({
// Otherwise validate internal form
return _(form.fields).chain()
.invoke(function () {
- this._check_css_flag();
+ this._check_css_flags();
return this.is_valid();
})
.all(_.identity)
@@ -3202,7 +3230,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({
pop.select_element(
self.o2m.field.relation,
{
- title: _t("Create: ") + self.name,
+ title: _t("Create: ") + self.o2m.string,
initial_view: "form",
alternative_form_view: self.o2m.field.views ? self.o2m.field.views["form"] : undefined,
create_function: function(data, callback, error_callback) {
@@ -3230,7 +3258,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({
var self = this;
var pop = new instance.web.form.FormOpenPopup(self.o2m.view);
pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(), {
- title: _t("Open: ") + self.name,
+ title: _t("Open: ") + self.o2m.string,
write_function: function(id, data) {
return self.o2m.dataset.write(id, data, {}, function(r) {
self.o2m.reload_current_view();
@@ -3514,6 +3542,7 @@ instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({
'selectable': self.multi_selection,
'sortable': false,
'reorderable': false,
+ 'import_enabled': false,
});
var embedded = (this.field.views || {}).tree;
if (embedded) {
@@ -3558,7 +3587,7 @@ instance.web.form.Many2ManyListView = instance.web.ListView.extend(/** @lends in
pop.select_element(
this.model,
{
- title: _t("Add: ") + this.name
+ title: _t("Add: ") + this.m2m_field.string
},
new instance.web.CompoundDomain(this.m2m_field.build_domain(), ["!", ["id", "in", this.m2m_field.dataset.ids]]),
this.m2m_field.build_context()
@@ -3578,7 +3607,7 @@ instance.web.form.Many2ManyListView = instance.web.ListView.extend(/** @lends in
var self = this;
var pop = new instance.web.form.FormOpenPopup(this);
pop.show_element(this.dataset.model, id, this.m2m_field.build_context(), {
- title: _t("Open: ") + this.name,
+ title: _t("Open: ") + this.m2m_field.string,
readonly: this.getParent().get("effective_readonly")
});
pop.on_write_completed.add_last(function() {
@@ -3676,7 +3705,7 @@ instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend(
pop.select_element(
this.field.relation,
{
- title: _t("Add: ") + this.name
+ title: _t("Add: ") + this.string
},
new instance.web.CompoundDomain(this.build_domain(), ["!", ["id", "in", this.dataset.ids]]),
this.build_context()
@@ -3694,7 +3723,7 @@ instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend(
var id = self.dataset.ids[self.dataset.index];
var pop = new instance.web.form.FormOpenPopup(self.view);
pop.show_element(self.field.relation, id, self.build_context(), {
- title: _t("Open: ") + self.name,
+ title: _t("Open: ") + self.string,
write_function: function(id, data, options) {
return self.dataset.write(id, data, {}).then(function() {
self.reload_content();
@@ -3994,6 +4023,7 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
_.extend({'deletable': false,
'selectable': !self.options.disable_multiple_selection,
'read_only': true,
+ 'import_enabled': false,
}, self.options.list_view_options || {}));
self.view_list.popup = self;
self.view_list.appendTo($(".oe_popup_list", self.$element)).pipe(function() {
@@ -4354,10 +4384,13 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({
});
instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
- tagName: "span",
+ template: "FieldStatus",
start: function() {
this._super();
this.selected_value = null;
+ if (this.$element.parent().is('header')) {
+ this.$element.after('<div class="oe_clear"/>');
+ }
// preview in start only for selection fields, because of the dynamic behavior of many2one fields.
if (this.field.type in ['selection']) {
this.render_list();
@@ -4469,6 +4502,9 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
elem.css("color", color);
}
},
+ focus: function() {
+ return false;
+ },
});
/**
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index 015829a0579..7bf9d4ad6bf 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -24,6 +24,8 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
// if true, the view can't be editable, ignoring the view's and the context's
// instructions
'read_only': false,
+ // if true, the 'Import', 'Export', etc... buttons will be shown
+ 'import_enabled': true,
},
/**
* Core class for list-type displays.
@@ -343,6 +345,8 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
self._limit = (isNaN(val) ? null : val);
self.page = 0;
self.reload_content();
+ }).blur(function() {
+ $(this).trigger('change');
})
.val(self._limit || 'NaN');
});
@@ -375,11 +379,12 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
}
var total = dataset.size();
- this.$pager.toggleClass('oe_list_pager_single_page', (total <= this.limit()));
+ var limit = this.limit() || total;
+ this.$pager.toggleClass('oe_list_pager_single_page', (total <= limit));
var spager = '-';
if (total) {
- var range_start = this.page * this.limit() + 1;
- var range_stop = range_start - 1 + this.limit();
+ var range_start = this.page * limit + 1;
+ var range_stop = range_start - 1 + limit;
if (range_stop > total) {
range_stop = total;
}
@@ -1331,6 +1336,11 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we
row_data[group.grouped_on] = group;
var group_column = _(self.columns).detect(function (column) {
return column.id === group.grouped_on; });
+ if (! group_column) {
+ throw new Error(_.str.sprintf(
+ _t("Grouping on field '%s' is not possible because that field does not appear in the list view."),
+ group.grouped_on));
+ }
try {
$group_column.html(instance.web.format_cell(
row_data, group_column, {
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index 8d0493a9753..98df8a0af0d 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -136,7 +136,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
};
}
if (action.target === 'new') {
- if (this.dialog == null) {
+ if (this.dialog === null) {
this.dialog = new instance.web.Dialog(this, { width: '80%' });
if(on_close)
this.dialog.on_close.add(on_close);
@@ -144,8 +144,9 @@ instance.web.ActionManager = instance.web.Widget.extend({
this.dialog_viewmanager.destroy();
}
this.dialog.dialog_title = action.name;
- this.dialog_viewmanager = new instance.web.ViewManagerAction(this, action);
+ this.dialog_viewmanager = new instance.web.ViewManagerAction(this.dialog, action);
this.dialog_viewmanager.appendTo(this.dialog.$element);
+ this.dialog_viewmanager.$element.addClass("oe_view_manager_" + action.target);
this.dialog.open();
} else {
this.dialog_stop();
@@ -158,7 +159,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
this.inner_action = action;
this.inner_viewmanager = new instance.web.ViewManagerAction(this, action);
this.inner_viewmanager.appendTo(this.$element);
- this.inner_viewmanager.$element.addClass("oe_view_manager_global");
+ this.inner_viewmanager.$element.addClass("oe_view_manager_" + action.target);
}
},
ir_actions_act_window_close: function (action, on_closed) {