summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js
diff options
context:
space:
mode:
authorJiten (OpenERP) <jra@tinyerp.com>2011-10-03 10:46:33 +0530
committerJiten (OpenERP) <jra@tinyerp.com>2011-10-03 10:46:33 +0530
commit10380b13431a981bd942a04c49c6afb69c19dc18 (patch)
tree9c308f77f46f990c610dfbf0e63535e601210673 /addons/web/static/src/js
parent3fba4c077a2343434f5f4a655d75dabb1a2ac7eb (diff)
parent3a12aa8d7c6a22b6bf8431209bcd1dfec7b9a791 (diff)
[MERGE] Merge from openerp-web.
bzr revid: jra@tinyerp.com-20111003051633-9z4qdvet7rbz9z7p
Diffstat (limited to 'addons/web/static/src/js')
-rw-r--r--addons/web/static/src/js/chrome.js39
-rw-r--r--addons/web/static/src/js/data.js20
-rw-r--r--addons/web/static/src/js/view_form.js316
-rw-r--r--addons/web/static/src/js/view_list.js46
-rw-r--r--addons/web/static/src/js/views.js33
5 files changed, 325 insertions, 129 deletions
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index c6b065205d7..1955298ba27 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -1,7 +1,6 @@
/*---------------------------------------------------------
* OpenERP Web chrome
*---------------------------------------------------------*/
-
openerp.web.chrome = function(openerp) {
var QWeb = openerp.web.qweb;
@@ -129,6 +128,7 @@ openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog#
// Destroy widget
this.close();
this.$dialog.dialog('destroy');
+ this._super();
}
});
@@ -253,7 +253,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
.removeClass("database_block")
.end()
.empty();
-
+ this._super();
},
/**
* Converts a .serializeArray() result into a dict. Does not bother folding
@@ -299,9 +299,9 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
var admin = result[1][0];
setTimeout(function () {
- self.stop();
self.widget_parent.do_login(
info.db, admin.login, admin.password);
+ self.stop();
$.unblockUI();
});
});
@@ -463,6 +463,9 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
remember_creditentials: true,
+
+ template: "Login",
+ identifier_prefix: 'oe-app-login-',
/**
* @constructs openerp.web.Login
* @extends openerp.web.Widget
@@ -471,8 +474,8 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
* @param element_id
*/
- init: function(parent, element_id) {
- this._super(parent, element_id);
+ init: function(parent) {
+ this._super(parent);
this.has_local_storage = typeof(localStorage) != 'undefined';
this.selected_db = null;
this.selected_login = null;
@@ -487,17 +490,6 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
},
start: function() {
var self = this;
- this.rpc("/web/database/get_list", {}, function(result) {
- self.db_list = result.db_list;
- self.display();
- }, function() {
- self.display();
- });
- },
- display: function() {
- var self = this;
-
- this.$element.html(QWeb.render("Login", this));
this.database = new openerp.web.Database(
this, "oe_database", "oe_db_options");
@@ -506,6 +498,17 @@ openerp.web.Login = openerp.web.Widget.extend(/** @lends openerp.web.Login# */{
});
this.$element.find("form").submit(this.on_submit);
+
+ this.rpc("/web/database/get_list", {}, function(result) {
+ var tpl = openerp.web.qweb.render('Login_dblist', {db_list: result.db_list, selected_db: self.selected_db});
+ self.$element.find("input[name=db]").replaceWith(tpl)
+ },
+ function(error, event) {
+ if (error.data.fault_code === 'AccessDenied') {
+ event.preventDefault();
+ }
+ });
+
},
on_login_invalid: function() {
this.$element.closest(".openerp").addClass("login-mode");
@@ -933,7 +936,7 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
openerp.web.Widget.prototype.notification = new openerp.web.Notification(this, "oe_notification");
this.header = new openerp.web.Header(this);
- this.login = new openerp.web.Login(this, "oe_login");
+ this.login = new openerp.web.Login(this);
this.header.on_logout.add(this.login.on_logout);
this.header.on_action.add(this.on_menu_action);
@@ -953,7 +956,7 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
start: function() {
this.header.appendTo($("#oe_header"));
this.session.start();
- this.login.start();
+ this.login.appendTo($('#oe_login'));
this.menu.start();
},
on_logged: function() {
diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js
index 00281628e75..fcf6a65dcf5 100644
--- a/addons/web/static/src/js/data.js
+++ b/addons/web/static/src/js/data.js
@@ -233,6 +233,7 @@ openerp.web.StaticDataGroup = openerp.web.GrouplessDataGroup.extend( /** @lends
});
openerp.web.DataSet = openerp.web.Widget.extend( /** @lends openerp.web.DataSet# */{
+ identifier_prefix: "dataset",
/**
* DateaManagement interface between views and the collection of selected
* OpenERP records (represents the view's state?)
@@ -242,16 +243,12 @@ openerp.web.DataSet = openerp.web.Widget.extend( /** @lends openerp.web.DataSet
*
* @param {String} model the OpenERP model this dataset will manage
*/
- init: function(source_controller, model, context) {
- // we don't want the dataset to be a child of anything!
- this._super(null);
- this.session = source_controller ? source_controller.session : undefined;
+ init: function(parent, model, context) {
+ this._super(parent);
this.model = model;
this.context = context || {};
this.index = null;
},
- start: function() {
- },
previous: function () {
this.index -= 1;
if (this.index < 0) {
@@ -549,13 +546,11 @@ openerp.web.DataSetSearch = openerp.web.DataSet.extend(/** @lends openerp.web.D
sort: this.sort(),
offset: offset,
limit: options.limit || false
- }, function (result) {
+ }).pipe(function (result) {
self.ids = result.ids;
self.offset = offset;
- if (callback) {
- callback(result.records);
- }
- });
+ return result.records;
+ }).then(callback);
},
get_domain: function (other_domain) {
if (other_domain) {
@@ -603,7 +598,6 @@ openerp.web.DataSetSearch = openerp.web.DataSet.extend(/** @lends openerp.web.D
});
openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
virtual_id_prefix: "one2many_v_id_",
- virtual_id_regex: /one2many_v_id_.*/,
debug_mode: true,
init: function() {
this._super.apply(this, arguments);
@@ -724,6 +718,8 @@ openerp.web.BufferedDataSet = openerp.web.DataSetStatic.extend({
return completion.promise();
}
});
+openerp.web.BufferedDataSet.virtual_id_regex = /^one2many_v_id_.*$/;
+
openerp.web.ReadOnlyDataSetSearch = openerp.web.DataSetSearch.extend({
default_get: function(fields, callback) {
return this._super(fields, callback).then(this.on_default_get);
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index c7ffb896186..11ebad8d093 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -41,7 +41,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.has_been_loaded = $.Deferred();
this.$form_header = null;
this.translatable_fields = [];
- _.defaults(this.options, {"always_show_new_button": true});
+ _.defaults(this.options, {"always_show_new_button": true,
+ "not_interactible_on_create": false});
},
start: function() {
this._super();
@@ -72,17 +73,25 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
_.each(this.widgets, function(w) {
w.stop();
});
+ this._super();
+ },
+ reposition: function ($e) {
+ this.$element = $e;
+ this.on_loaded();
},
on_loaded: function(data) {
var self = this;
- this.fields_view = data;
- var frame = new (this.registry.get_object('frame'))(this, this.fields_view.arch);
+ if (data) {
+ this.fields_view = data;
+ var frame = new (this.registry.get_object('frame'))(this, this.fields_view.arch);
- this.$element.html(QWeb.render(this.form_template, { 'frame': frame, 'view': this }));
+ this.rendered = QWeb.render(this.form_template, { 'frame': frame, 'view': this });
+ }
+ this.$element.html(this.rendered);
_.each(this.widgets, function(w) {
w.start();
});
- this.$form_header = this.$element.find('#' + this.element_id + '_header');
+ this.$form_header = this.$element.find('.oe_form_header:first');
this.$form_header.find('div.oe_form_pager button[data-pager-action]').click(function() {
var action = $(this).data('pager-action');
self.on_pager_action(action);
@@ -93,6 +102,17 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.$form_header.find('button.oe_form_button_cancel').click(this.do_cancel);
this.$form_header.find('button.oe_form_button_new').click(this.on_button_new);
this.$form_header.find('button.oe_form_button_duplicate').click(this.on_button_duplicate);
+ this.$form_header.find('button.oe_form_button_toggle').click(function () {
+ self.translatable_fields = [];
+ self.widgets = {};
+ self.fields = {};
+ self.$form_header.find('button').unbind('click');
+ self.registry = self.registry === openerp.web.form.widgets
+ ? openerp.web.form.readonly
+ : openerp.web.form.widgets;
+ self.on_loaded(self.fields_view);
+ self.reload();
+ });
if (this.options.sidebar && this.options.sidebar_id) {
this.sidebar = new openerp.web.Sidebar(this, this.options.sidebar_id);
@@ -196,7 +216,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
},
do_update_pager: function(hide_index) {
- var $pager = this.$element.find('#' + this.element_id + '_header div.oe_form_pager');
+ var $pager = this.$form_header.find('div.oe_form_pager');
var index = hide_index ? '-' : this.dataset.index + 1;
$pager.find('span.oe_pager_index').html(index);
$pager.find('span.oe_pager_count').html(this.dataset.ids.length);
@@ -477,6 +497,17 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
if (self.dataset.parent_view)
return self.dataset.parent_view.recursive_save();
});
+ },
+ is_interactible_record: function() {
+ var id = this.datarecord.id;
+ if (!id) {
+ if (this.options.not_interactible_on_create)
+ return false;
+ } else if (typeof(id) === "string") {
+ if(openerp.web.BufferedDataSet.virtual_id_regex.test(id))
+ return false;
+ }
+ return true;
}
});
openerp.web.FormDialog = openerp.web.Dialog.extend({
@@ -624,6 +655,7 @@ openerp.web.form.compute_domain = function(expr, fields) {
openerp.web.form.Widget = openerp.web.Widget.extend(/** @lends openerp.web.form.Widget# */{
template: 'Widget',
+ identifier_prefix: 'formview-widget-',
/**
* @constructs openerp.web.form.Widget
* @extends openerp.web.Widget
@@ -637,11 +669,13 @@ openerp.web.form.Widget = openerp.web.Widget.extend(/** @lends openerp.web.form.
this.modifiers = JSON.parse(this.node.attrs.modifiers || '{}');
this.type = this.type || node.tag;
this.element_name = this.element_name || this.type;
- this.element_id = [this.view.element_id, this.element_name, this.view.widgets_counter++].join("_");
+ this.element_class = [
+ 'formview', this.view.view_id, this.element_name,
+ this.view.widgets_counter++].join("_");
- this._super(view, this.element_id);
+ this._super(view);
- this.view.widgets[this.element_id] = this;
+ this.view.widgets[this.element_class] = this;
this.children = node.children;
this.colspan = parseInt(node.attrs.colspan || 1, 10);
this.decrease_max_width = 0;
@@ -654,12 +688,7 @@ openerp.web.form.Widget = openerp.web.Widget.extend(/** @lends openerp.web.form.
this.width = this.node.attrs.width;
},
start: function() {
- this.$element = $('#' + this.element_id);
- },
- stop: function() {
- if (this.$element) {
- this.$element.remove();
- }
+ this.$element = this.view.$element.find('.' + this.element_class);
},
process_modifiers: function() {
var compute_domain = openerp.web.form.compute_domain;
@@ -763,13 +792,24 @@ openerp.web.form.WidgetNotebook = openerp.web.form.Widget.extend({
for (var i = 0; i < node.children.length; i++) {
var n = node.children[i];
if (n.tag == "page") {
- var page = new openerp.web.form.WidgetNotebookPage(this.view, n, this, this.pages.length);
+ var page = new openerp.web.form.WidgetNotebookPage(
+ this.view, n, this, this.pages.length);
this.pages.push(page);
}
}
},
start: function() {
+ var self = this;
this._super.apply(this, arguments);
+ this.$element.find('> ul > li').each(function (index, tab_li) {
+ var page = self.pages[index],
+ id = _.uniqueId(self.element_name + '-');
+ page.element_id = id;
+ $(tab_li).find('a').attr('href', '#' + id);
+ });
+ this.$element.find('> div').each(function (index, page) {
+ page.id = self.pages[index].element_id;
+ });
this.$element.tabs();
this.view.on_button_new.add_last(this.do_select_first_visible_tab);
},
@@ -791,11 +831,11 @@ openerp.web.form.WidgetNotebookPage = openerp.web.form.WidgetFrame.extend({
this.index = index;
this.element_name = 'page_' + index;
this._super(view, node);
- this.element_tab_id = this.element_id + '_tab';
},
start: function() {
this._super.apply(this, arguments);
- this.$element_tab = $('#' + this.element_tab_id);
+ this.$element_tab = this.notebook.$element.find(
+ '> ul > li:eq(' + this.index + ')');
},
update_dom: function() {
if (this.invisible && this.index === this.notebook.$element.tabs('option', 'selected')) {
@@ -807,9 +847,9 @@ openerp.web.form.WidgetNotebookPage = openerp.web.form.WidgetFrame.extend({
});
openerp.web.form.WidgetSeparator = openerp.web.form.Widget.extend({
+ template: 'WidgetSeparator',
init: function(view, node) {
this._super(view, node);
- this.template = "WidgetSeparator";
this.orientation = node.attrs.orientation || 'horizontal';
if (this.orientation === 'vertical') {
this.width = '1';
@@ -819,9 +859,10 @@ openerp.web.form.WidgetSeparator = openerp.web.form.Widget.extend({
});
openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
+ template: 'WidgetButton',
init: function(view, node) {
this._super(view, node);
- this.template = "WidgetButton";
+ this.force_disabled = false;
if (this.string) {
// We don't have button key bindings in the webclient
this.string = this.string.replace(/_/g, '');
@@ -833,46 +874,74 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({
},
start: function() {
this._super.apply(this, arguments);
- this.$element.click(this.on_click);
+ this.$element.find("button").click(this.on_click);
},
on_click: function() {
var self = this;
+ this.force_disabled = true;
+ this.check_disable();
+ this.execute_action().always(function() {
+ self.force_disabled = false;
+ self.check_disable();
+ });
+ },
+ execute_action: function() {
+ var self = this;
var exec_action = function() {
if (self.node.attrs.confirm) {
+ var def = $.Deferred();
var dialog = $('<div>' + self.node.attrs.confirm + '</div>').dialog({
title: 'Confirm',
modal: true,
buttons: {
Ok: function() {
- self.on_confirmed();
+ self.on_confirmed().then(function() {
+ def.resolve();
+ });
$(self).dialog("close");
},
Cancel: function() {
+ def.resolve();
$(self).dialog("close");
}
}
});
+ return def.promise();
} else {
- self.on_confirmed();
+ return self.on_confirmed();
}
};
if ((!this.node.attrs.special && this.view.dirty_for_user) || !this.view.datarecord.id) {
- this.view.recursive_save().then(exec_action);
+ return this.view.recursive_save().pipe(exec_action);
} else {
- exec_action();
+ return exec_action();
}
},
on_confirmed: function() {
var self = this;
- this.view.do_execute_action(
+ return this.view.do_execute_action(
this.node.attrs, this.view.dataset, this.view.datarecord.id, function () {
self.view.reload();
});
+ },
+ update_dom: function() {
+ this._super();
+ this.check_disable();
+ },
+ check_disable: function() {
+ if (this.force_disabled || !this.view.is_interactible_record()) {
+ this.$element.find("button").attr("disabled", "disabled");
+ this.$element.find("button").css("color", "grey");
+ } else {
+ this.$element.find("button").removeAttr("disabled");
+ this.$element.find("button").css("color", "");
+ }
}
});
openerp.web.form.WidgetLabel = openerp.web.form.Widget.extend({
+ template: 'WidgetLabel',
init: function(view, node) {
this.element_name = 'label_' + node.attrs.name;
@@ -883,7 +952,6 @@ openerp.web.form.WidgetLabel = openerp.web.form.Widget.extend({
this.template = "WidgetParagraph";
this.colspan = parseInt(this.node.attrs.colspan || 1, 10);
} else {
- this.template = "WidgetLabel";
this.colspan = 1;
this.width = '1%';
this.decrease_max_width = 1;
@@ -902,7 +970,7 @@ openerp.web.form.WidgetLabel = openerp.web.form.Widget.extend({
var self = this;
this.$element.find("label").dblclick(function() {
var widget = self['for'] || self;
- console.log(widget.element_id , widget);
+ console.log(widget.element_class , widget);
window.w = widget;
});
}
@@ -1002,12 +1070,16 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
focus: function() {
},
_build_view_fields_values: function() {
- var a_dataset = this.view.dataset || {};
+ var a_dataset = this.view.dataset;
var fields_values = this.view.get_fields_values();
var parent_values = a_dataset.parent_view ? a_dataset.parent_view.get_fields_values() : {};
fields_values.parent = parent_values;
return fields_values;
},
+ _build_eval_context: function() {
+ var a_dataset = this.view.dataset;
+ return new openerp.web.CompoundContext(a_dataset.get_context(), this._build_view_fields_values());
+ },
/**
* Builds a new context usable for operations related to fields by merging
* the fields'context with the action's context.
@@ -1020,7 +1092,7 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
var v_context = new openerp.web.CompoundContext();
_.each(v_contexts, function(x) {v_context.add(x);});
if (_.detect(v_contexts, function(x) {return !!x.__ref;})) {
- var fields_values = this._build_view_fields_values();
+ var fields_values = this._build_eval_context();
v_context.set_eval_context(fields_values);
}
// if there is a context on the node, overrides the model's context
@@ -1031,7 +1103,7 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
var f_domain = this.field.domain || null;
var v_domain = this.node.attrs.domain || [];
if (!(v_domain instanceof Array) || true) { //TODO niv: remove || true
- var fields_values = this._build_view_fields_values();
+ var fields_values = this._build_eval_context();
v_domain = new openerp.web.CompoundDomain(v_domain).set_eval_context(fields_values);
}
// if there is a domain on the node, overrides the model's domain
@@ -1040,10 +1112,7 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
});
openerp.web.form.FieldChar = openerp.web.form.Field.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldChar";
- },
+ template: 'FieldChar',
start: function() {
this._super.apply(this, arguments);
this.$element.find('input').change(this.on_ui_change);
@@ -1052,6 +1121,7 @@ openerp.web.form.FieldChar = openerp.web.form.Field.extend({
this._super.apply(this, arguments);
var show_value = openerp.web.format_value(value, this, '');
this.$element.find('input').val(show_value);
+ return show_value;
},
update_dom: function() {
this._super.apply(this, arguments);
@@ -1076,10 +1146,7 @@ openerp.web.form.FieldChar = openerp.web.form.Field.extend({
});
openerp.web.form.FieldEmail = openerp.web.form.FieldChar.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldEmail";
- },
+ template: 'FieldEmail',
start: function() {
this._super.apply(this, arguments);
this.$element.find('button').click(this.on_button_clicked);
@@ -1090,18 +1157,11 @@ openerp.web.form.FieldEmail = openerp.web.form.FieldChar.extend({
} else {
location.href = 'mailto:' + this.value;
}
- },
- set_value: function(value) {
- this._super.apply(this, arguments);
- this.$element.find('a').attr('href', 'mailto:' + this.$element.find('input').val());
}
});
openerp.web.form.FieldUrl = openerp.web.form.FieldChar.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldUrl";
- },
+ template: 'FieldUrl',
start: function() {
this._super.apply(this, arguments);
this.$element.find('button').click(this.on_button_clicked);
@@ -1252,10 +1312,7 @@ openerp.web.form.FieldDate = openerp.web.form.FieldDatetime.extend({
});
openerp.web.form.FieldText = openerp.web.form.Field.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldText";
- },
+ template: 'FieldText',
start: function() {
this._super.apply(this, arguments);
this.$element.find('textarea').change(this.on_ui_change);
@@ -1288,10 +1345,7 @@ openerp.web.form.FieldText = openerp.web.form.Field.extend({
});
openerp.web.form.FieldBoolean = openerp.web.form.Field.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldBoolean";
- },
+ template: 'FieldBoolean',
start: function() {
var self = this;
this._super.apply(this, arguments);
@@ -1322,10 +1376,7 @@ openerp.web.form.FieldBoolean = openerp.web.form.Field.extend({
});
openerp.web.form.FieldProgressBar = openerp.web.form.Field.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldProgressBar";
- },
+ template: 'FieldProgressBar',
start: function() {
this._super.apply(this, arguments);
this.$element.find('div').progressbar({
@@ -1348,10 +1399,10 @@ openerp.web.form.FieldTextXml = openerp.web.form.Field.extend({
});
openerp.web.form.FieldSelection = openerp.web.form.Field.extend({
+ template: 'FieldSelection',
init: function(view, node) {
var self = this;
this._super(view, node);
- this.template = "FieldSelection";
this.values = this.field.selection;
_.each(this.values, function(v, i) {
if (v[0] === false && v[1] === '') {
@@ -1458,9 +1509,9 @@ openerp.web.form.dialog = function(content, options) {
};
openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
+ template: 'FieldMany2One',
init: function(view, node) {
this._super(view, node);
- this.template = "FieldMany2One";
this.limit = 7;
this.value = null;
this.cm_id = _.uniqueId('m2o_cm_');
@@ -1785,10 +1836,10 @@ var commands = {
}
};
openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
+ template: 'FieldOne2Many',
multi_selection: false,
init: function(view, node) {
this._super(view, node);
- this.template = "FieldOne2Many";
this.is_started = $.Deferred();
this.form_last_update = $.Deferred();
this.disable_utility_classes = true;
@@ -1819,6 +1870,8 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
}
if(view.view_type === "list") {
view.options.selectable = self.multi_selection;
+ } else if (view.view_type === "form") {
+ view.options.not_interactible_on_create = true;
}
views.push(view);
});
@@ -1878,6 +1931,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
switch (command[0]) {
case commands.CREATE:
obj['id'] = _.uniqueId(self.dataset.virtual_id_prefix);
+ obj.defaults = {};
self.dataset.to_create.push(obj);
self.dataset.cache.push(_.clone(obj));
ids.push(obj.id);
@@ -1907,6 +1961,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
_.each(value, function(command) {
var obj = {values: command};
obj['id'] = _.uniqueId(self.dataset.virtual_id_prefix);
+ obj.defaults = {};
self.dataset.to_create.push(obj);
self.dataset.cache.push(_.clone(obj));
ids.push(obj.id);
@@ -1965,9 +2020,8 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
},
validate: function() {
this.invalid = false;
- var self = this;
- var view = self.viewmanager.views[self.viewmanager.active_view].controller;
- if (self.viewmanager.active_view === "form") {
+ var view = this.viewmanager.views[this.viewmanager.active_view].controller;
+ if (this.viewmanager.active_view === "form") {
for (var f in view.fields) {
f = view.fields[f];
if (!f.is_valid()) {
@@ -2014,7 +2068,8 @@ openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
self.o2m.dataset.on_change();
});
},
- parent_view: self.o2m.view
+ parent_view: self.o2m.view,
+ form_view_options: {'not_interactible_on_create':true}
}, self.o2m.build_domain(), self.o2m.build_context());
pop.on_select_elements.add_last(function() {
self.o2m.reload_current_view();
@@ -2030,7 +2085,8 @@ openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
parent_view: self.o2m.view,
read_function: function() {
return self.o2m.dataset.read_ids.apply(self.o2m.dataset, arguments);
- }
+ },
+ form_view_options: {'not_interactible_on_create':true}
});
pop.on_write.add(function(id, data) {
self.o2m.dataset.write(id, data, {}, function(r) {
@@ -2041,10 +2097,10 @@ openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
});
openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({
+ template: 'FieldMany2Many',
multi_selection: false,
init: function(view, node) {
this._super(view, node);
- this.template = "FieldMany2Many";
this.list_id = _.uniqueId("many2many");
this.is_started = $.Deferred();
},
@@ -2145,6 +2201,8 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
* - alternative_form_view
* - create_function (defaults to a naive saving behavior)
* - parent_view
+ * - form_view_options
+ * - list_view_options
*/
select_element: function(model, options, domain, context) {
var self = this;
@@ -2209,7 +2267,7 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
});
self.view_list = new openerp.web.form.SelectCreateListView(self,
self.dataset, false,
- {'deletable': false});
+ _.extend({'deletable': false}, self.options.list_view_options || {}));
self.view_list.popup = self;
self.view_list.appendTo($("#" + self.element_id + "_view_list")).pipe(function() {
self.view_list.do_show();
@@ -2245,7 +2303,7 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
this.view_list.$element.hide();
}
this.dataset.index = null;
- this.view_form = new openerp.web.FormView(this, this.dataset, false);
+ this.view_form = new openerp.web.FormView(this, this.dataset, false, self.options.form_view_options);
if (this.options.alternative_form_view) {
this.view_form.set_embedded_view(this.options.alternative_form_view);
}
@@ -2320,6 +2378,7 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
* - auto_write (default true)
* - read_function
* - parent_view
+ * - form_view_options
*/
show_element: function(model, row_id, context, options) {
this.model = model;
@@ -2355,7 +2414,7 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
on_write_completed: function() {},
setup_form_view: function() {
var self = this;
- this.view_form = new openerp.web.FormView(this, this.dataset, false);
+ this.view_form = new openerp.web.FormView(this, this.dataset, false, self.options.form_view_options);
if (this.options.alternative_form_view) {
this.view_form.set_embedded_view(this.options.alternative_form_view);
}
@@ -2388,9 +2447,9 @@ openerp.web.form.FormOpenDataset = openerp.web.ReadOnlyDataSetSearch.extend({
});
openerp.web.form.FieldReference = openerp.web.form.Field.extend({
+ template: 'FieldReference',
init: function(view, node) {
this._super(view, node);
- this.template = "FieldReference";
this.fields_view = {
fields: {
selection: {
@@ -2525,10 +2584,7 @@ openerp.web.form.FieldBinary = openerp.web.form.Field.extend({
});
openerp.web.form.FieldBinaryFile = openerp.web.form.FieldBinary.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldBinaryFile";
- },
+ template: 'FieldBinaryFile',
set_value: function(value) {
this._super.apply(this, arguments);
var show_value = (value != null && value !== false) ? value : '';
@@ -2556,10 +2612,7 @@ openerp.web.form.FieldBinaryFile = openerp.web.form.FieldBinary.extend({
});
openerp.web.form.FieldBinaryImage = openerp.web.form.FieldBinary.extend({
- init: function(view, node) {
- this._super(view, node);
- this.template = "FieldBinaryImage";
- },
+ template: 'FieldBinaryImage',
start: function() {
this._super.apply(this, arguments);
this.$image = this.$element.find('img.oe-binary-image');
@@ -2634,6 +2687,93 @@ openerp.web.form.FieldStatus = openerp.web.form.Field.extend({
}
});
+openerp.web.form.WidgetNotebookReadonly = openerp.web.form.WidgetNotebook.extend({
+ template: 'WidgetNotebook.readonly'
+});
+openerp.web.form.FieldReadonly = openerp.web.form.Field.extend({
+
+});
+openerp.web.form.FieldCharReadonly = openerp.web.form.FieldReadonly.extend({
+ template: 'FieldChar.readonly',
+ set_value: function (value) {
+ this._super.apply(this, arguments);
+ var show_value = openerp.web.format_value(value, this, '');
+ this.$element.find('div').text(show_value);
+ return show_value;
+ }
+});
+openerp.web.form.FieldURIReadonly = openerp.web.form.FieldCharReadonly.extend({
+ template: 'FieldURI.readonly',
+ scheme: null,
+ set_value: function (value) {
+ var displayed = this._super.apply(this, arguments);
+ this.$element.find('a')
+ .attr('href', this.scheme + ':' + displayed)
+ .text(displayed);
+ }
+});
+openerp.web.form.FieldEmailReadonly = openerp.web.form.FieldURIReadonly.extend({
+ scheme: 'mailto'
+});
+openerp.web.form.FieldUrlReadonly = openerp.web.form.FieldURIReadonly.extend({
+ set_value: function (value) {
+ var s = /(\w+):(\.+)/.match(value);
+ if (!(s[0] === 'http' || s[0] === 'https')) { return; }
+ this.scheme = s[0];
+ this._super(s[1]);
+ }
+});
+openerp.web.form.FieldBooleanReadonly = openerp.web.form.FieldCharReadonly.extend({
+ set_value: function (value) {
+ this._super(value ? '\u2714' : '\u2718');
+ }
+});
+openerp.web.form.FieldSelectionReadonly = openerp.web.form.FieldReadonly.extend({
+ template: 'FieldChar.readonly',
+ init: function(view, node) {
+ // lifted straight from r/w version
+ var self = this;
+ this._super(view, node);
+ this.values = this.field.selection;
+ _.each(this.values, function(v, i) {
+ if (v[0] === false && v[1] === '') {
+ self.values.splice(i, 1);
+ }
+ });
+ this.values.unshift([false, '']);
+ },
+ set_value: function (value) {
+ value = value === null ? false : value;
+ value = value instanceof Array ? value[0] : value;
+ var option = _(this.values)
+ .detect(function (record) { return record[0] === value; });
+ this._super(value);
+ this.$element.find('div').text(option ? option[1] : this.values[0][1]);
+ }
+});
+openerp.web.form.FieldMany2OneReadonly = openerp.web.form.FieldCharReadonly.extend({
+ set_value: function (value) {
+ value = value || null;
+ this.invalid = false;
+ var self = this;
+ this.tmp_value = value;
+ self.update_dom();
+ self.on_value_changed();
+ var real_set_value = function(rval) {
+ self.$element.find('div').text(rval ? rval[1] : '');
+ };
+ if(typeof(value) === "number") {
+ var dataset = new openerp.web.DataSetStatic(
+ this, this.field.relation, self.build_context());
+ dataset.name_get([value], function(data) {
+ real_set_value(data[0]);
+ }).fail(function() {self.tmp_value = undefined;});
+ } else {
+ setTimeout(function() {real_set_value(value);}, 0);
+ }
+ }
+});
+
/**
* Registry of form widgets, called by :js:`openerp.web.FormView`
*/
@@ -2666,6 +2806,22 @@ openerp.web.form.widgets = new openerp.web.Registry({
'binary': 'openerp.web.form.FieldBinaryFile',
'statusbar': 'openerp.web.form.FieldStatus'
});
+openerp.web.form.readonly = openerp.web.form.widgets.clone({
+ 'notebook': 'openerp.web.form.WidgetNotebookReadonly',
+ 'char': 'openerp.web.form.FieldCharReadonly',
+ 'email': 'openerp.web.form.FieldEmailReadonly',
+ 'url': 'openerp.web.form.FieldUrlReadonly',
+ 'text': 'openerp.web.form.FieldCharReadonly',
+ 'text_wiki' : 'openerp.web.form.FieldCharReadonly',
+ 'date': 'openerp.web.form.FieldCharReadonly',
+ 'datetime': 'openerp.web.form.FieldCharReadonly',
+ 'selection' : 'openerp.web.form.FieldSelectionReadonly',
+ 'many2one': 'openerp.web.form.FieldMany2OneReadonly',
+ 'boolean': 'openerp.web.form.FieldBooleanReadonly',
+ 'float': 'openerp.web.form.FieldCharReadonly',
+ 'integer': 'openerp.web.form.FieldCharReadonly',
+ 'float_time': 'openerp.web.form.FieldCharReadonly'
+});
};
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index eeda44c4c99..8a9deaab228 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -49,6 +49,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
this.model = dataset.model;
this.view_id = view_id;
this.previous_colspan = null;
+ this.colors = null;
this.columns = [];
@@ -75,6 +76,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
}
self.compute_aggregates();
});
+
},
/**
* Retrieves the view's number of records per page (|| section)
@@ -132,6 +134,31 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
return this.reload_view(null, null, true);
},
/**
+ * Returns the color for the provided record in the current view (from the
+ * ``@colors`` attribute)
+ *
+ * @param {Record} record record for the current row
+ * @returns {String} CSS color declaration
+ */
+ color_for: function (record) {
+ if (!this.colors) { return ''; }
+ var context = _.extend({}, record.attributes, {
+ uid: this.session.uid,
+ current_date: new Date().toString('yyyy-MM-dd')
+ // TODO: time, datetime, relativedelta
+ });
+ for(var i=0, len=this.colors.length; i<len; ++i) {
+ var pair = this.colors[i],
+ color = pair[0],
+ expression = pair[1];
+ if (py.evaluate(expression, context)) {
+ return 'color: ' + color + ';';
+ }
+ // TODO: handle evaluation errors
+ }
+ return '';
+ },
+ /**
* Called after loading the list view's description, sets up such things
* as the view table's columns, renders the table itself and hooks up the
* various table-level and row-level DOM events (action buttons, deletion
@@ -159,6 +186,17 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
this.fields_view = data;
this.name = "" + this.fields_view.arch.attrs.string;
+ if (this.fields_view.arch.attrs.colors) {
+ this.colors = _(this.fields_view.arch.attrs.colors.split(';')).chain()
+ .compact()
+ .map(function(color_pair) {
+ var pair = color_pair.split(':'),
+ color = pair[0],
+ expr = pair[1];
+ return [color, py.parse(py.tokenize(expr)), expr];
+ }).value();
+ }
+
this.setup_columns(this.fields_view.fields, grouped);
this.$element.html(QWeb.render("ListView", this));
@@ -1355,10 +1393,10 @@ var Record = openerp.web.Class.extend(/** @lends Record# */{
* @returns {Object} record displayable in a form view
*/
toForm: function () {
- var form_data = {};
- _(this.attributes).each(function (value, key) {
- form_data[key] = {value: value};
- });
+ var form_data = {}, attrs = this.attributes;
+ for(var k in attrs) {
+ form_data[k] = {value: attrs[k]};
+ }
return {data: form_data};
}
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index d31a3b05674..4a9e57ebd1d 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -86,7 +86,7 @@ db.web.ActionManager = db.web.Widget.extend({
console.log("Action manager can't handle action of type " + action.type, action);
return;
}
- this[type](action, on_close);
+ return this[type](action, on_close);
},
ir_actions_act_window: function (action, on_close) {
if (action.target === 'new') {
@@ -163,7 +163,7 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
*/
init: function(parent, dataset, views) {
this._super(parent);
- this.model = dataset.model;
+ this.model = dataset ? dataset.model : undefined;
this.dataset = dataset;
this.searchview = null;
this.active_view = null;
@@ -184,7 +184,6 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
start: function() {
this._super();
var self = this;
- this.dataset.start();
this.$element.find('.oe_vm_switch button').click(function() {
self.on_mode_switch($(this).data('view-type'));
});
@@ -332,6 +331,7 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
// dataset initialization will take the session from ``this``, so if we
// do not have it yet (and we don't, because we've not called our own
// ``_super()``) rpc requests will blow up.
+ this._super(parent, null, action.views);
this.session = parent.session;
this.action = action;
var dataset = new db.web.DataSetSearch(this, action.res_model, action.context, action.domain);
@@ -339,7 +339,7 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
dataset.ids.push(action.res_id);
dataset.index = 0;
}
- this._super(parent, dataset, action.views);
+ this.dataset = dataset;
this.flags = this.action.flags || {};
if (action.res_model == 'board.board' && action.views.length == 1 && action.views) {
// Not elegant but allows to avoid form chrome (pager, save/new
@@ -470,7 +470,7 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
* Intercept do_action resolution from children views
*/
on_action_executed: function () {
- new db.web.DataSet(this, 'res.log')
+ return new db.web.DataSet(this, 'res.log')
.call('get', [], this.do_display_log);
},
/**
@@ -770,28 +770,31 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
var self = this;
var result_handler = function () {
if (on_closed) { on_closed.apply(null, arguments); }
- self.widget_parent.on_action_executed.apply(null, arguments);
+ return self.widget_parent.on_action_executed.apply(null, arguments);
};
var handler = function (r) {
var action = r.result;
if (action && action.constructor == Object) {
- action.context = action.context || {};
- _.extend(action.context, {
- active_id: record_id || false,
- active_ids: [record_id || false],
- active_model: dataset.model
+ return self.rpc('/web/session/eval_domain_and_context', {
+ contexts: [dataset.get_context(), action.context || {}, {
+ active_id: record_id || false,
+ active_ids: [record_id || false],
+ active_model: dataset.model
+ }],
+ domains: []
+ }).pipe(function (results) {
+ action.context = results.context
+ return self.do_action(action, result_handler);
});
- action.context = new db.web.CompoundContext(dataset.get_context(), action.context);
- self.do_action(action, result_handler);
} else {
- result_handler();
+ return result_handler();
}
};
var context = new db.web.CompoundContext(dataset.get_context(), action_data.context || {});
if (action_data.special) {
- handler({result: {"type":"ir.actions.act_window_close"}});
+ return handler({result: {"type":"ir.actions.act_window_close"}});
} else if (action_data.type=="object") {
return dataset.call_button(action_data.name, [[record_id], context], handler);
} else if (action_data.type=="action") {