summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js
diff options
context:
space:
mode:
authorRichard Mathot (OpenERP) <rim@openerp.com>2014-04-11 15:10:28 +0200
committerRichard Mathot (OpenERP) <rim@openerp.com>2014-04-11 15:10:28 +0200
commitfb912d82beae89ef75433d43bfce6966eeee0c0b (patch)
tree63e55a61d95df2aaa71a4354019f3d7e2ecb35b6 /addons/web/static/src/js
parent004fa1f1acdcc68a5d138f68da674630e22cd1df (diff)
parent60f74ff3f4c7bb1e5208b0f4be3ef2577a5645f4 (diff)
[MERGE] Sync with trunk
bzr revid: rim@openerp.com-20140411131028-fqudb40nz71qhwc6
Diffstat (limited to 'addons/web/static/src/js')
-rw-r--r--addons/web/static/src/js/chrome.js25
-rw-r--r--addons/web/static/src/js/core.js7
-rw-r--r--addons/web/static/src/js/data.js72
-rw-r--r--addons/web/static/src/js/data_export.js11
-rw-r--r--addons/web/static/src/js/search.js10
-rw-r--r--addons/web/static/src/js/view_form.js115
-rw-r--r--addons/web/static/src/js/view_list.js18
-rw-r--r--addons/web/static/src/js/view_list_editable.js11
-rw-r--r--addons/web/static/src/js/views.js12
9 files changed, 220 insertions, 61 deletions
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index 9b87d416206..de56927799e 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -105,9 +105,6 @@ instance.web.Dialog = instance.web.Widget.extend({
autoOpen: false,
position: [false, 40],
buttons: null,
- beforeClose: function () {
- self.trigger("closing");
- },
resizeStop: function() {
self.trigger("resized");
},
@@ -208,8 +205,9 @@ instance.web.Dialog = instance.web.Widget.extend({
/**
Closes the popup, if destroy_on_close was passed to the constructor, it is also destroyed.
*/
- close: function() {
+ close: function(reason) {
if (this.dialog_inited && this.$el.is(":data(dialog)")) {
+ this.trigger("closing", reason);
this.$el.dialog('close');
}
},
@@ -225,14 +223,14 @@ instance.web.Dialog = instance.web.Widget.extend({
/**
Destroys the popup, also closes it.
*/
- destroy: function () {
+ destroy: function (reason) {
this.$buttons.remove();
_.each(this.getChildren(), function(el) {
el.destroy();
});
if (! this.__tmp_dialog_closing) {
this.__tmp_dialog_destroying = true;
- this.close();
+ this.close(reason);
this.__tmp_dialog_destroying = undefined;
}
if (this.dialog_inited && !this.isDestroyed() && this.$el.is(":data(dialog)")) {
@@ -256,7 +254,7 @@ instance.web.CrashManager = instance.web.Class.extend({
new (handler)(this, error).display();
return;
}
- if (error.data.name === "openerp.http.SessionExpiredException") {
+ if (error.data.name === "openerp.http.SessionExpiredException" || error.data.name === "werkzeug.exceptions.Forbidden") {
this.show_warning({type: "Session Expired", data: { message: _t("Your OpenERP session expired. Please refresh the current web page.") }});
return;
}
@@ -1264,9 +1262,9 @@ instance.web.WebClient = instance.web.Client.extend({
};
self.action_manager.do_action(result);
var form = self.action_manager.dialog_widget.views.form.controller;
- form.on("on_button_cancel", self.action_manager.dialog, self.action_manager.dialog.close);
+ form.on("on_button_cancel", self.action_manager, self.action_manager.dialog_stop);
form.on('record_saved', self, function() {
- self.action_manager.dialog.close();
+ self.action_manager.dialog_stop();
self.update_logo();
});
});
@@ -1337,12 +1335,13 @@ instance.web.WebClient = instance.web.Client.extend({
if (_.isEmpty(state) || state.action == "login") {
self.menu.has_been_loaded.done(function() {
new instance.web.Model("res.users").call("read", [self.session.uid, ["action_id"]]).done(function(data) {
- var first_menu_id = self.menu.$el.find("a:first").data("menu");
- if(first_menu_id)
- self.menu.menu_click(first_menu_id);
-
if(data.action_id) {
self.action_manager.do_action(data.action_id[0]);
+ self.menu.open_action(data.action_id[0]);
+ } else {
+ var first_menu_id = self.menu.$el.find("a:first").data("menu");
+ if(first_menu_id)
+ self.menu.menu_click(first_menu_id);
}
});
});
diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js
index b92ca1d3ba5..90c84ba9cda 100644
--- a/addons/web/static/src/js/core.js
+++ b/addons/web/static/src/js/core.js
@@ -271,7 +271,12 @@ instance.web.Session.include( /** @lends instance.web.Session# */{
for(var i=0; i<cookies.length; ++i) {
var cookie = cookies[i].replace(/^\s*/, '');
if(cookie.indexOf(nameEQ) === 0) {
- return JSON.parse(decodeURIComponent(cookie.substring(nameEQ.length)));
+ try {
+ return JSON.parse(decodeURIComponent(cookie.substring(nameEQ.length)));
+ } catch(err) {
+ // wrong cookie, delete it
+ this.set_cookie(name, '', -1);
+ }
}
}
return null;
diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js
index cc595c30688..6819634655d 100644
--- a/addons/web/static/src/js/data.js
+++ b/addons/web/static/src/js/data.js
@@ -27,6 +27,7 @@ instance.web.Query = instance.web.Class.extend({
this._fields = fields;
this._filter = [];
this._context = {};
+ this._lazy = true;
this._limit = false;
this._offset = 0;
this._order_by = [];
@@ -36,6 +37,7 @@ instance.web.Query = instance.web.Class.extend({
var q = new instance.web.Query(this._model, this._fields);
q._context = this._context;
q._filter = this._filter;
+ q._lazy = this._lazy;
q._limit = this._limit;
q._offset = this._offset;
q._order_by = this._order_by;
@@ -51,6 +53,7 @@ instance.web.Query = instance.web.Class.extend({
q._context = new instance.web.CompoundContext(
q._context, to_set.context);
break;
+ case 'lazy':
case 'limit':
case 'offset':
case 'order_by':
@@ -140,6 +143,7 @@ instance.web.Query = instance.web.Class.extend({
domain: this._model.domain(this._filter),
context: ctx,
offset: this._offset,
+ lazy: this._lazy,
limit: this._limit,
orderby: instance.web.serialize_sort(this._order_by) || false
}).then(function (results) {
@@ -148,8 +152,9 @@ instance.web.Query = instance.web.Class.extend({
result.__context = result.__context || {};
result.__context.group_by = result.__context.group_by || [];
_.defaults(result.__context, ctx);
+ var grouping_fields = self._lazy ? [grouping[0]] : grouping;
return new instance.web.QueryGroup(
- self._model.name, grouping[0], result);
+ self._model.name, grouping_fields, result);
});
});
},
@@ -176,6 +181,18 @@ instance.web.Query = instance.web.Class.extend({
return this.clone({filter: domain});
},
/**
+ * Creates a new query with the provided parameter lazy replacing the current
+ * query's own.
+ *
+ * @param {Boolean} lazy indicates if the read_group should return only the
+ * first level of groupby records, or should return the records grouped by
+ * all levels at once (so, it makes only 1 db request).
+ * @returns {openerp.web.Query}
+ */
+ lazy: function (lazy) {
+ return this.clone({lazy: lazy});
+ },
+ /**
* Creates a new query with the provided limit replacing the current
* query's own limit
*
@@ -213,7 +230,7 @@ instance.web.Query = instance.web.Class.extend({
});
instance.web.QueryGroup = instance.web.Class.extend({
- init: function (model, grouping_field, read_group_group) {
+ init: function (model, grouping_fields, read_group_group) {
// In cases where group_by_no_leaf and no group_by, the result of
// read_group has aggregate fields but no __context or __domain.
// Create default (empty) values for those so that things don't break
@@ -221,11 +238,12 @@ instance.web.QueryGroup = instance.web.Class.extend({
{__context: {group_by: []}, __domain: []},
read_group_group);
+ var count_key = (grouping_fields[0] && grouping_fields[0].split(':')[0]) + '_count';
var aggregates = {};
_(fixed_group).each(function (value, key) {
if (key.indexOf('__') === 0
- || key === grouping_field
- || key === grouping_field + '_count') {
+ || _.contains(grouping_fields, key)
+ || (key === count_key)) {
return;
}
aggregates[key] = value || 0;
@@ -234,16 +252,21 @@ instance.web.QueryGroup = instance.web.Class.extend({
this.model = new instance.web.Model(
model, fixed_group.__context, fixed_group.__domain);
- var raw_field = grouping_field && grouping_field.split(':')[0];
- var group_size = fixed_group[raw_field + '_count'] || fixed_group.__count || 0;
+ var group_size = fixed_group[count_key] || fixed_group.__count || 0;
var leaf_group = fixed_group.__context.group_by.length === 0;
+ var value = (grouping_fields.length === 1)
+ ? fixed_group[grouping_fields[0]]
+ : _.map(grouping_fields, function (field) { return fixed_group[field]; });
+ var grouped_on = (grouping_fields.length === 1)
+ ? grouping_fields[0]
+ : grouping_fields;
this.attributes = {
folded: !!(fixed_group.__fold),
- grouped_on: grouping_field,
+ grouped_on: grouped_on,
// if terminal group (or no group) and group_by_no_leaf => use group.__count
length: group_size,
- value: fixed_group[raw_field],
+ value: value,
// A group is open-able if it's not a leaf in group_by_no_leaf mode
has_children: !(leaf_group && fixed_group.__context['group_by_no_leaf']),
@@ -448,7 +471,8 @@ instance.web.DataSet = instance.web.Class.extend(instance.web.PropertiesMixin,
* Read records.
*
* @param {Array} ids identifiers of the records to read
- * @param {Array} fields fields to read and return, by default all fields are returned
+ * @param {Array} [fields] fields to read and return, by default all fields are returned
+ * @param {Object} [options]
* @returns {$.Deferred}
*/
read_ids: function (ids, fields, options) {
@@ -456,10 +480,28 @@ instance.web.DataSet = instance.web.Class.extend(instance.web.PropertiesMixin,
return $.Deferred().resolve([]);
options = options || {};
- // TODO: reorder results to match ids list
- return this._model.call('read',
- [ids, fields || false],
- {context: this.get_context(options.context)});
+ var method = 'read';
+ var ids_arg = ids;
+ var context = this.get_context(options.context);
+ if (options.check_access_rule === true){
+ method = 'search_read';
+ ids_arg = [['id', 'in', ids]];
+ context = new instance.web.CompoundContext(context, {active_test: false});
+ }
+ return this._model.call(method,
+ [ids_arg, fields || false],
+ {context: context})
+ .then(function (records) {
+ if (records.length <= 1) { return records; }
+ var indexes = {};
+ for (var i = 0; i < ids.length; i++) {
+ indexes[ids[i]] = i;
+ }
+ records.sort(function (a, b) {
+ return indexes[a.id] - indexes[b.id];
+ });
+ return records;
+ });
},
/**
* Read a slice of the records represented by this DataSet, based on its
@@ -904,6 +946,10 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({
sign = -1;
field = field.slice(1);
}
+ //m2o should be searched based on value[1] not based whole value(i.e. [id, value])
+ if(_.isArray(a[field]) && a[field].length == 2 && _.isString(a[field][1])){
+ return sign * compare(a[field][1], b[field][1]);
+ }
return sign * compare(a[field], b[field]);
}, 0);
});
diff --git a/addons/web/static/src/js/data_export.js b/addons/web/static/src/js/data_export.js
index 2725e18ea6e..252a5a378cc 100644
--- a/addons/web/static/src/js/data_export.js
+++ b/addons/web/static/src/js/data_export.js
@@ -119,6 +119,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
if (select_exp.val()) {
self.exports.unlink([parseInt(select_exp.val(), 10)]);
select_exp.remove();
+ self.$el.find("#fields_list option").remove();
if (self.$el.find('#saved_export_list option').length <= 1) {
self.$el.find('#ExistsExportList').hide();
}
@@ -166,18 +167,16 @@ instance.web.DataExport = instance.web.Dialog.extend({
export_fields: _(fields).map(function (field) {
return [0, 0, {name: field}];
})
- }, function (export_list_id) {
- if (!export_list_id.result) {
+ }).then(function (export_list_id) {
+ if (!export_list_id) {
return;
}
- self.$el.find("#saved_export_list").append(
- new Option(value, export_list_id.result));
- if (self.$el.find("#saved_export_list").is(":hidden")) {
+ if (!self.$el.find("#saved_export_list").length || self.$el.find("#saved_export_list").is(":hidden")) {
self.show_exports_list();
}
+ self.$el.find("#saved_export_list").append( new Option(value, export_list_id) );
});
this.on_show_save_list();
- this.$el.find("#fields_list option").remove();
},
on_click: function(id, record) {
var self = this;
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index b667d135bdd..04bb1a61d99 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -355,7 +355,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
}
},
'autocompleteopen': function () {
- this.$el.autocomplete('widget').css('z-index', 1004);
+ this.$el.autocomplete('widget').css('z-index', 9999);
},
},
/**
@@ -677,6 +677,11 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
* @returns instance.web.search.Field
*/
make_field: function (item, field, parent) {
+ // M2O combined with selection widget is pointless and broken in search views,
+ // but has been used in the past for unsupported hacks -> ignore it
+ if (field.type === "many2one" && item.attrs.widget === "selection"){
+ item.attrs.widget = undefined;
+ }
var obj = instance.web.search.fields.get_any( [item.attrs.widget, field.type]);
if(obj) {
return new (obj) (item, field, parent || this);
@@ -1555,9 +1560,6 @@ instance.web.search.ManyToOneField = instance.web.search.CharField.extend({
this.model = new instance.web.Model(this.attrs.relation);
},
complete: function (needle) {
- if (this.attrs.operator || this.attrs.filter_domain) {
- return this._super(needle);
- }
var self = this;
// FIXME: "concurrent" searches (multiple requests, mis-ordered responses)
var context = instance.web.pyeval.eval(
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index f1fc377fa94..37c60a36f04 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -967,9 +967,12 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
context: {
'bin_size': true,
'future_display_name': true
- }
+ },
+ check_access_rule: true
}).then(function(r) {
self.trigger('load_record', r);
+ }).fail(function (){
+ self.do_action('history_back');
});
}
});
@@ -1277,6 +1280,9 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
var defs = [];
_.each(this.to_replace, function(el) {
defs.push(el[0].replace(el[1]));
+ if (el[1].children().length) {
+ el[0].$el.append(el[1].children());
+ }
});
this.to_replace = [];
return $.when.apply($, defs);
@@ -1304,7 +1310,7 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
var tagname = $tag[0].nodeName.toLowerCase();
if (this.tags_registry.contains(tagname)) {
this.tags_to_init.push($tag);
- return $tag;
+ return (tagname === 'button') ? this.process_button($tag) : $tag;
}
var fn = self['process_' + tagname];
if (fn) {
@@ -1321,6 +1327,13 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
return $tag;
}
},
+ process_button: function ($button) {
+ var self = this;
+ $button.children().each(function() {
+ self.process($(this));
+ });
+ return $button;
+ },
process_widget: function($widget) {
this.widgets_to_init.push($widget);
return $widget;
@@ -1906,6 +1919,8 @@ instance.web.form.WidgetButton = instance.web.form.FormWidget.extend({
template: 'WidgetButton',
init: function(field_manager, node) {
node.attrs.type = node.attrs['data-button-type'];
+ this.is_stat_button = /\boe_stat_button\b/.test(node.attrs['class']);
+ this.icon = node.attrs.icon && "<span class=\"fa " + node.attrs.icon + " fa-fw\"></span>";
this._super(field_manager, node);
this.force_disabled = false;
this.string = (this.node.attrs.string || '').replace(/_/g, '');
@@ -1976,11 +1991,12 @@ instance.web.form.WidgetButton = instance.web.form.FormWidget.extend({
var self = this;
var context = this.build_context();
-
return this.view.do_execute_action(
_.extend({}, this.node.attrs, {context: context}),
- this.view.dataset, this.view.datarecord.id, function () {
- self.view.recursive_reload();
+ this.view.dataset, this.view.datarecord.id, function (reason) {
+ if (!_.isObject(reason)) {
+ self.view.recursive_reload();
+ }
});
},
check_disable: function() {
@@ -2253,7 +2269,7 @@ instance.web.form.ReinitializeFieldMixin = _.extend({}, instance.web.form.Reini
/**
Some hack to make placeholders work in ie9.
*/
-if ($.browser.msie && $.browser.version === "9.0") {
+if (!('placeholder' in document.createElement('input'))) {
document.addEventListener("DOMNodeInserted",function(event){
var nodename = event.target.nodeName.toLowerCase();
if ( nodename === "input" || nodename == "textarea" ) {
@@ -2805,6 +2821,50 @@ instance.web.form.FieldProgressBar = instance.web.form.AbstractField.extend({
}
});
+/**
+ The PercentPie field expect a float from 0 to 100.
+*/
+instance.web.form.FieldPercentPie = instance.web.form.AbstractField.extend({
+ template: 'FieldPercentPie',
+
+ render_value: function() {
+ var value = this.get('value'),
+ formatted_value = Math.round(value || 0) + '%',
+ svg = this.$('svg')[0];
+
+ svg.innerHTML = "";
+ nv.addGraph(function() {
+ var size=43;
+ var chart = nv.models.pieChart()
+ .width(size)
+ .height(size)
+ .margin({top: 0, right: 0, bottom: 0, left: 0})
+ .donut(true)
+ .showLegend(false)
+ .showLabels(false)
+ .tooltips(false)
+ .color(['#7C7BAD','#DDD'])
+ .donutRatio(0.62);
+
+ d3.select(svg)
+ .datum([{'x': 'value', 'y': value}, {'x': 'complement', 'y': 100 - value}])
+ .transition()
+ .call(chart)
+ .attr({width:size, height:size});
+
+ d3.select(svg)
+ .append("text")
+ .attr({x: size/2, y: size/2 + 3, 'text-anchor': 'middle'})
+ .style({"font-size": "10px", "font-weight": "bold"})
+ .text(formatted_value);
+
+ return chart;
+ });
+
+ }
+});
+
+
instance.web.form.FieldSelection = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, {
template: 'FieldSelection',
@@ -2835,9 +2895,7 @@ instance.web.form.FieldSelection = instance.web.form.AbstractField.extend(instan
var def;
if (this.field.type === "many2one") {
var model = new openerp.Model(openerp.session, this.field.relation);
- def = model.call("search", [this.get("domain")], {"context": this.build_context()}).then(function(record_ids) {
- return model.call("name_get", [record_ids] , {"context": self.build_context()});
- });
+ def = model.call("name_search", ['', this.get("domain")], {"context": this.build_context()});
} else {
var values = _.reject(this.field.selection, function (v) { return v[0] === false && v[1] === ''; });
def = $.when(values);
@@ -3127,7 +3185,8 @@ instance.web.form.CompletionFieldMixin = {
if (self.options.quick_create === undefined || self.options.quick_create) {
new instance.web.DataSet(this, this.field.relation, self.build_context())
.name_create(name).done(function(data) {
- self.add_id(data[0]);
+ if (!self.get('effective_readonly'))
+ self.add_id(data[0]);
}).fail(function(error, event) {
event.preventDefault();
slow_create();
@@ -4304,7 +4363,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
if (data.id) {
self.add_id(data.id);
} else {
- ignore_blur = true;
+ self.ignore_blur = true;
data.action();
}
this.trigger('setSuggestions', {result : []});
@@ -4344,7 +4403,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
if (this.get("effective_readonly"))
return;
var self = this;
- var ignore_blur = false;
+ self.ignore_blur = false;
self.$text = this.$("textarea");
self.$text.textext(self.initialize_texttext()).bind('getSuggestions', function(e, data) {
var _this = this;
@@ -4364,11 +4423,11 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
self.$text
.focusin(function () {
self.trigger('focused');
- ignore_blur = false;
+ self.ignore_blur = false;
})
.focusout(function() {
self.$text.trigger("setInputData", "");
- if (!ignore_blur) {
+ if (!self.ignore_blur) {
self.trigger('blurred');
}
}).keydown(function(e) {
@@ -4446,6 +4505,10 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
width: width,
minHeight: height
});
+ },
+ _search_create_popup: function() {
+ self.ignore_blur = true;
+ return instance.web.form.CompletionFieldMixin._search_create_popup.apply(this, arguments);
},
});
@@ -5007,7 +5070,7 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
this.searchview.on('search_data', self, function(domains, contexts, groupbys) {
if (self.initial_ids) {
self.do_search(domains.concat([[["id", "in", self.initial_ids]], self.domain]),
- contexts, groupbys);
+ contexts.concat(self.context), groupbys);
self.initial_ids = undefined;
} else {
self.do_search(domains.concat([self.domain]), contexts.concat(self.context), groupbys);
@@ -5853,6 +5916,26 @@ instance.web.form.X2ManyCounter = instance.web.form.AbstractField.extend(instanc
});
/**
+ This widget is intended to be used on stat button numeric fields. It will display
+ the value many2many and one2many. It is a read-only field that will
+ display a simple string "<value of field> <label of the field>"
+*/
+instance.web.form.StatInfo = instance.web.form.AbstractField.extend({
+ init: function() {
+ this._super.apply(this, arguments);
+ this.set("value", 0);
+ },
+ render_value: function() {
+ var options = {
+ value: this.get("value") || 0,
+ text: this.string,
+ };
+ this.$el.html(QWeb.render("StatInfo", options));
+ },
+
+});
+
+/**
* Registry of form fields, called by :js:`instance.web.FormView`.
*
* All referenced classes must implement FieldInterface. Those represent the classes whose instances
@@ -5879,6 +5962,7 @@ instance.web.form.widgets = new instance.web.Registry({
'reference' : 'instance.web.form.FieldReference',
'boolean' : 'instance.web.form.FieldBoolean',
'float' : 'instance.web.form.FieldFloat',
+ 'percentpie': 'instance.web.form.FieldPercentPie',
'integer': 'instance.web.form.FieldFloat',
'float_time': 'instance.web.form.FieldFloat',
'progressbar': 'instance.web.form.FieldProgressBar',
@@ -5889,6 +5973,7 @@ instance.web.form.widgets = new instance.web.Registry({
'monetary': 'instance.web.form.FieldMonetary',
'many2many_checkboxes': 'instance.web.form.FieldMany2ManyCheckBoxes',
'x2many_counter': 'instance.web.form.X2ManyCounter',
+ 'statinfo': 'instance.web.form.StatInfo',
});
/**
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index e01ab29f914..cdb9ff8302f 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -408,6 +408,9 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
if (total) {
var range_start = this.page * limit + 1;
var range_stop = range_start - 1 + limit;
+ if (this.records.length) {
+ range_stop = range_start - 1 + this.records.length;
+ }
if (range_stop > total) {
range_stop = total;
}
@@ -534,7 +537,8 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
[record.get('id')],
_.pluck(_(this.columns).filter(function (r) {
return r.tag === 'field';
- }), 'name')
+ }), 'name'),
+ {check_access_rule: true}
).done(function (records) {
var values = records[0];
if (!values) {
@@ -602,7 +606,17 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
_(ids).each(function (id) {
self.records.remove(self.records.get(id));
});
- self.configure_pager(self.dataset);
+ if (self.records.length === 0 && self.dataset.size() > 0) {
+ //Trigger previous manually to navigate to previous page,
+ //If all records are deleted on current page.
+ self.$pager.find('ul li:first a').trigger('click');
+ } else if (self.dataset.size() == self.limit()) {
+ //Reload listview to update current page with next page records
+ //because pager going to be hidden if dataset.size == limit
+ self.reload();
+ } else {
+ self.configure_pager(self.dataset);
+ }
self.compute_aggregates();
});
},
diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js
index fc9af47dfe6..e2c63eb191a 100644
--- a/addons/web/static/src/js/view_list_editable.js
+++ b/addons/web/static/src/js/view_list_editable.js
@@ -126,10 +126,19 @@
* as an editable row at the top or bottom of the list)
*/
do_add_record: function () {
+ var self = this;
if (this.editable()) {
this.$el.find('table:first').show();
this.$el.find('.oe_view_nocontent').remove();
- this.start_edition();
+ this.start_edition().then(function(){
+ var fields = self.editor.form.fields;
+ self.editor.form.fields_order.some(function(field){
+ if (fields[field].$el.is(':visible')){
+ fields[field].$el.find("input").select();
+ return true;
+ }
+ });
+ });
} else {
this._super();
}
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index c9229c3c70a..2f401445f7e 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -25,9 +25,9 @@ instance.web.ActionManager = instance.web.Widget.extend({
this._super.apply(this, arguments);
this.$el.on('click', 'a.oe_breadcrumb_item', this.on_breadcrumb_clicked);
},
- dialog_stop: function () {
+ dialog_stop: function (reason) {
if (this.dialog) {
- this.dialog.destroy();
+ this.dialog.destroy(reason);
}
this.dialog = null;
},
@@ -408,7 +408,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
if (this.dialog_widget && !this.dialog_widget.isDestroyed()) {
this.dialog_widget.destroy();
}
- this.dialog_stop();
+ this.dialog_stop(executor.action);
this.dialog = new instance.web.Dialog(this, {
dialogClass: executor.klass,
});
@@ -426,7 +426,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
this.dialog.open();
return initialized;
} else {
- this.dialog_stop();
+ this.dialog_stop(executor.action);
this.inner_action = executor.action;
this.inner_widget = widget;
executor.post_process(widget);
@@ -639,7 +639,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
this.$el
.find('.oe_view_manager_switch a').filter('[data-view-type="' + view_type + '"]')
.parent().addClass('active');
-
+ this.$el.attr("data-view-type", view_type);
return $.when(view_promise).done(function () {
_.each(_.keys(self.views), function(view_name) {
var controller = self.views[view_name].controller;
@@ -1402,7 +1402,7 @@ instance.web.View = instance.web.Widget.extend({
// Wrong group_by values will simply fail and forbid rendering of the destination view
var ncontext = new instance.web.CompoundContext(
_.object(_.reject(_.pairs(dataset.get_context().eval()), function(pair) {
- return pair[0].match('^(?:(?:default_|search_default_).+|group_by|group_by_no_leaf|active_id|active_ids)$') !== null;
+ return pair[0].match('^(?:(?:default_|search_default_).+|.+_view_ref|group_by|group_by_no_leaf|active_id|active_ids)$') !== null;
}))
);
ncontext.add(action_data.context || {});