summaryrefslogtreecommitdiff
path: root/addons/web/static
diff options
context:
space:
mode:
authorVishmita <vja@tinyerp.com>2012-10-11 15:58:37 +0530
committerVishmita <vja@tinyerp.com>2012-10-11 15:58:37 +0530
commitffe8dd604a833ae8c3f6b8d1fd6ccdfa02b256bb (patch)
tree44d7961b09e4678c0ba8f3c4bc1ece4469213b6c /addons/web/static
parent3e15613cf7783df5175f52d0ba4945ba54890f98 (diff)
parent70afbd796e441cce26171af03c26a08f88c3ab52 (diff)
[MERGE]Merge Trunk
bzr revid: vja@tinyerp.com-20121011102837-k0y1kvf901rp3l8u
Diffstat (limited to 'addons/web/static')
-rw-r--r--addons/web/static/src/css/base.css73
-rw-r--r--addons/web/static/src/css/base.sass47
-rw-r--r--addons/web/static/src/js/chrome.js30
-rw-r--r--addons/web/static/src/js/corelib.js13
-rw-r--r--addons/web/static/src/js/data.js8
-rw-r--r--addons/web/static/src/js/view_form.js185
-rw-r--r--addons/web/static/src/js/view_list_editable.js7
-rw-r--r--addons/web/static/src/js/views.js49
-rw-r--r--addons/web/static/src/xml/base.xml21
9 files changed, 256 insertions, 177 deletions
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index 3d54aef0fa2..c8f1567bee9 100644
--- a/addons/web/static/src/css/base.css
+++ b/addons/web/static/src/css/base.css
@@ -25,7 +25,6 @@
display: none !important;
}
}
-
.openerp.openerp_webclient_container {
height: 100%;
position: relative;
@@ -46,7 +45,7 @@
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
/* http://www.quirksmode.org/dom/inputfile.html
* http://stackoverflow.com/questions/2855589/replace-input-type-file-by-an-image
- */ */
+ */
}
.openerp :-moz-placeholder {
color: #afafb6 !important;
@@ -69,10 +68,13 @@
background-color: #f0f0f0;
}
.openerp thead th {
- border-right: 1px dotted #afafb6;
+ border-left: 1px solid #dfdfdf;
}
-.openerp thead th:last-child {
- border-right: none;
+.openerp thead th:first-child {
+ border-left: none;
+}
+.openerp thead th.null {
+ border-left: none;
}
.openerp th, .openerp td {
padding: 0;
@@ -522,28 +524,6 @@
.openerp .oe_grey {
color: #aaaaaa;
}
-.openerp header {
- position: relative;
- border-bottom: 1px solid #cacaca;
- padding-left: 2px;
- background-color: #fcfcfc;
- background-image: -webkit-gradient(linear, left top, left bottom, from(#fcfcfc), to(#dedede));
- background-image: -webkit-linear-gradient(top, #fcfcfc, #dedede);
- background-image: -moz-linear-gradient(top, #fcfcfc, #dedede);
- background-image: -ms-linear-gradient(top, #fcfcfc, #dedede);
- background-image: -o-linear-gradient(top, #fcfcfc, #dedede);
- background-image: linear-gradient(to bottom, #fcfcfc, #dedede);
-}
-.openerp header > span {
- margin-left: 4px;
-}
-.openerp header ul {
- display: inline-block;
- float: right;
-}
-.openerp header .oe_button {
- margin: 3px 2px 1px;
-}
.openerp .oe_tag {
border: 1px solid #afafb6;
font-size: 11px;
@@ -1204,7 +1184,7 @@
color: white;
padding: 2px 4px;
margin: 1px 6px 0 0;
- border: 1px solid lightGray;
+ border: 1px solid lightgrey;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
@@ -1229,7 +1209,7 @@
transform: scale(1.1);
}
.openerp .oe_secondary_submenu .oe_active {
- border-top: 1px solid lightGray;
+ border-top: 1px solid lightgrey;
border-bottom: 1px solid #dedede;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
-moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2), inset 0 -1px 3px rgba(40, 40, 40, 0.2);
@@ -2044,6 +2024,31 @@
.openerp .oe_application .oe_form_sheet .oe_notebook_page {
padding: 0 16px;
}
+.openerp .oe_form header {
+ position: relative;
+ border-bottom: 1px solid #cacaca;
+ padding-left: 2px;
+ background-color: #fcfcfc;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#fcfcfc), to(#dedede));
+ background-image: -webkit-linear-gradient(top, #fcfcfc, #dedede);
+ background-image: -moz-linear-gradient(top, #fcfcfc, #dedede);
+ background-image: -ms-linear-gradient(top, #fcfcfc, #dedede);
+ background-image: -o-linear-gradient(top, #fcfcfc, #dedede);
+ background-image: linear-gradient(to bottom, #fcfcfc, #dedede);
+}
+.openerp .oe_form header > span {
+ margin-left: 4px;
+}
+.openerp .oe_form header ul {
+ display: inline-block;
+ float: right;
+}
+.openerp .oe_form header .oe_button {
+ margin: 3px 2px 1px;
+}
+.openerp .oe_form header .oe_button:first-child {
+ margin-left: 6px;
+}
.openerp .oe_form header .oe_tags {
margin: 5px 0 0 5px;
width: 400px;
@@ -2125,7 +2130,7 @@
}
.openerp .oe_form .oe_form_label_help[for] span, .openerp .oe_form .oe_form_label[for] span {
font-size: 80%;
- color: darkGreen;
+ color: darkgreen;
vertical-align: top;
position: relative;
top: -4px;
@@ -2294,16 +2299,16 @@
margin-bottom: 32px;
text-align: justify;
}
-.openerp .oe_form_editable .oe_form .oe_form_field_integer {
+.openerp .oe_form_editable .oe_form .oe_form_field_integer input {
width: 6em !important;
}
-.openerp .oe_form_editable .oe_form .oe_form_field_float {
+.openerp .oe_form_editable .oe_form .oe_form_field_float input {
width: 7em !important;
}
-.openerp .oe_form_editable .oe_form .oe_form_field_date {
+.openerp .oe_form_editable .oe_form .oe_form_field_date input {
width: 7.5em !important;
}
-.openerp .oe_form_editable .oe_form .oe_form_field_datetime {
+.openerp .oe_form_editable .oe_form .oe_form_field_datetime input {
width: 11.5em !important;
}
.openerp .oe_hidden_input_file {
diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass
index 0567d31b1eb..823ced4e24f 100644
--- a/addons/web/static/src/css/base.sass
+++ b/addons/web/static/src/css/base.sass
@@ -180,9 +180,11 @@ $sheet-max-width: 860px
font-weight: bold
background-color: #f0f0f0
th
- border-right: 1px dotted $tag-border
- &:last-child
- border-right: none
+ border-left: 1px solid #dfdfdf
+ &:first-child
+ border-left: none
+ &.null
+ border-left: none
th, td
padding: 0
text-align: left
@@ -457,21 +459,6 @@ $sheet-max-width: 860px
// }}}
- // Generic blocks {{{
- header
- position: relative
- border-bottom: 1px solid #cacaca
- padding-left: 2px
- @include vertical-gradient(#fcfcfc, #dedede)
- > span
- margin-left: 4px
- ul
- display: inline-block
- float: right
- .oe_button
- margin: 3px 2px 1px
- // }}}
-
// Tags (for many2many tags, among others) {{{
.oe_tag
border: 1px solid $tag-border
@@ -1618,6 +1605,22 @@ $sheet-max-width: 860px
.oe_notebook_page
padding: 0 16px
// }}}
+ // FormView.header {{{
+ .oe_form header
+ position: relative
+ border-bottom: 1px solid #cacaca
+ padding-left: 2px
+ @include vertical-gradient(#fcfcfc, #dedede)
+ > span
+ margin-left: 4px
+ ul
+ display: inline-block
+ float: right
+ .oe_button,
+ margin: 3px 2px 1px
+ &:first-child
+ margin-left: 6px
+ // }}}
// FormView.custom tags and classes {{{
.oe_form header .oe_tags
margin: 5px 0 0 5px
@@ -1822,13 +1825,13 @@ $sheet-max-width: 860px
.oe_form_editable
.oe_form
- .oe_form_field_integer
+ .oe_form_field_integer input
width: 6em !important
- .oe_form_field_float
+ .oe_form_field_float input
width: 7em !important
- .oe_form_field_date
+ .oe_form_field_date input
width: 7.5em !important
- .oe_form_field_datetime
+ .oe_form_field_datetime input
width: 11.5em !important
// }}}
// FormView.fields_binary {{{
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index 80693d26e46..b605f4ad4e1 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -181,7 +181,7 @@ instance.web.Dialog = instance.web.Widget.extend({
});
instance.web.CrashManager = instance.web.CallbackEnabled.extend({
- on_rpc_error: function(error) {
+ rpc_error: function(error) {
if (error.data.fault_code) {
var split = ("" + error.data.fault_code).split('\n')[0].split(' -- ');
if (split.length > 1) {
@@ -190,12 +190,12 @@ instance.web.CrashManager = instance.web.CallbackEnabled.extend({
}
}
if (error.code === 200 && error.type) {
- this.on_managed_error(error);
+ this.show_warning(error);
} else {
- this.on_traceback(error);
+ this.show_error(error);
}
},
- on_managed_error: function(error) {
+ show_warning: function(error) {
instance.web.dialog($('<div>' + QWeb.render('CrashManager.warning', {error: error}) + '</div>'), {
title: "OpenERP " + _.str.capitalize(error.type),
buttons: [
@@ -203,7 +203,7 @@ instance.web.CrashManager = instance.web.CallbackEnabled.extend({
]
});
},
- on_traceback: function(error) {
+ show_error: function(error) {
var self = this;
var buttons = {};
buttons[_t("Ok")] = function() {
@@ -219,8 +219,8 @@ instance.web.CrashManager = instance.web.CallbackEnabled.extend({
}).open();
dialog.$el.html(QWeb.render('CrashManager.error', {session: instance.session, error: error}));
},
- on_javascript_exception: function(exception) {
- this.on_traceback({
+ show_message: function(exception) {
+ this.show_error({
type: _t("Client Error"),
message: exception,
data: {debug: ""}
@@ -236,7 +236,7 @@ instance.web.Loading = instance.web.Widget.extend({
this.blocked_ui = false;
this.session.on("request", this, this.request_call);
this.session.on("response", this, this.response_call);
- this.session.on("error", this, this.response_call);
+ this.session.on("response_failed", this, this.response_call);
},
destroy: function() {
this.on_rpc_event(-this.count);
@@ -957,7 +957,7 @@ instance.web.Client = instance.web.Widget.extend({
show_common: function() {
var self = this;
this.crashmanager = new instance.web.CrashManager();
- instance.session.on_rpc_error.add(this.crashmanager.on_rpc_error);
+ instance.session.on('error', this.crashmanager, this.crashmanager.rpc_error);
self.notification = new instance.web.Notification(this);
self.notification.appendTo(self.$el);
self.loading = new instance.web.Loading(self);
@@ -1007,7 +1007,7 @@ instance.web.WebClient = instance.web.Client.extend({
var self = this;
this._super();
window.onerror = function (message, file, line) {
- self.crashmanager.on_traceback({
+ self.crashmanager.show_error({
type: _t("Client Error"),
message: message,
data: {debug: file + ':' + line}
@@ -1016,15 +1016,13 @@ instance.web.WebClient = instance.web.Client.extend({
},
show_login: function() {
this.toggle_bars(false);
-
+
+ var state = $.bbq.getState(true);
var action = {
'type': 'ir.actions.client',
- 'tag': 'login'
+ 'tag': 'login',
+ 'params': state
};
- var state = $.bbq.getState(true);
- if (state.action === "login") {
- action.params = state;
- }
this.action_manager.do_action(action);
this.action_manager.inner_widget.on('login_successful', this, function() {
diff --git a/addons/web/static/src/js/corelib.js b/addons/web/static/src/js/corelib.js
index ff193605033..b5fbacc7927 100644
--- a/addons/web/static/src/js/corelib.js
+++ b/addons/web/static/src/js/corelib.js
@@ -121,6 +121,10 @@ openerp.web.corelib = function(instance) {
// The dummy class constructor
function Class() {
+ if(this.constructor !== instance.web.Class){
+ throw new Error("You can only instanciate objects with the 'new' operator");
+ return null;
+ }
// All construction is actually done in the init method
if (!initializing && this.init) {
var ret = this.init.apply(this, arguments);
@@ -976,7 +980,8 @@ instance.web.JsonRPC = instance.web.CallbackEnabled.extend({
triggers: {
'request': 'Request sent',
'response': 'Response received',
- 'error': 'HTTP Error response or timeout received',
+ 'response_failed': 'HTTP Error response or timeout received',
+ 'error': 'The received response is an JSON-RPC error',
},
/**
* @constructs instance.web.JsonRPC
@@ -1332,7 +1337,7 @@ instance.web.JsonRPC = instance.web.CallbackEnabled.extend({
}
},
function(jqXHR, textStatus, errorThrown) {
- self.trigger('error');
+ self.trigger('response_failed', jqXHR);
var error = {
code: -32098,
message: "XmlHttpRequestError " + errorThrown,
@@ -1344,7 +1349,7 @@ instance.web.JsonRPC = instance.web.CallbackEnabled.extend({
deferred.fail(function() {
deferred.fail(function(error, event) {
if (!event.isDefaultPrevented()) {
- self.on_rpc_error(error, event);
+ self.trigger('error', error, event);
}
});
});
@@ -1430,8 +1435,6 @@ instance.web.JsonRPC = instance.web.CallbackEnabled.extend({
return deferred;
}
},
- on_rpc_error: function(error) {
- },
get_url: function (file) {
return this.prefix + file;
},
diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js
index 220d42737da..ce85e0ac43f 100644
--- a/addons/web/static/src/js/data.js
+++ b/addons/web/static/src/js/data.js
@@ -575,6 +575,7 @@ instance.web.DataSet = instance.web.CallbackEnabled.extend({
* @param {Number|String} ids identifier of the record to delete
*/
unlink: function(ids) {
+ this.trigger('unlink', ids);
return this._model.call('unlink', [ids], {context: this._model.context()});
},
/**
@@ -690,6 +691,7 @@ instance.web.DataSet = instance.web.CallbackEnabled.extend({
instance.web.DataSetStatic = instance.web.DataSet.extend({
init: function(parent, model, context, ids) {
+ var self = this;
this._super(parent, model, context);
// all local records
this.ids = ids || [];
@@ -711,12 +713,10 @@ instance.web.DataSetStatic = instance.web.DataSet.extend({
}
},
unlink: function(ids) {
- this.on_unlink(ids);
+ this.set_ids(_.without.apply(null, [this.ids].concat(ids)));
+ this.trigger('unlink', ids);
return $.Deferred().resolve({result: true});
},
- on_unlink: function(ids) {
- this.set_ids(_.without.apply(null, [this.ids].concat(ids)));
- }
});
instance.web.DataSetSearch = instance.web.DataSet.extend({
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index a17d43a0b5b..afb5e258c0b 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -126,6 +126,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
self.on("change:actual_mode", self, self.init_pager);
self.init_pager();
});
+ self.on("load_record", self, self.load_record);
instance.web.bus.on('clear_uncommitted_changes', this, function(e) {
if (!this.can_be_discarded()) {
e.preventDefault();
@@ -172,10 +173,10 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
} else {
this.$el.find('.oe_form_buttons').replaceWith(this.$buttons);
}
- this.$buttons.on('click','.oe_form_button_create',this.on_button_create);
- this.$buttons.on('click','.oe_form_button_edit',this.on_button_edit);
- this.$buttons.on('click','.oe_form_button_save',this.on_button_save);
- this.$buttons.on('click','.oe_form_button_cancel',this.on_button_cancel);
+ this.$buttons.on('click', '.oe_form_button_create', this.on_button_create);
+ this.$buttons.on('click', '.oe_form_button_edit', this.on_button_edit);
+ this.$buttons.on('click', '.oe_form_button_save', this.on_button_save);
+ this.$buttons.on('click', '.oe_form_button_cancel', this.on_button_cancel);
this.$sidebar = this.options.$sidebar || this.$el.find('.oe_form_sidebar');
if (!this.sidebar && this.options.$sidebar) {
@@ -331,7 +332,9 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
fields.push('display_name');
return self.dataset.read_index(fields, {
context: { 'bin_size': true, 'future_display_name' : true }
- }).pipe(self.on_record_loaded);
+ }).pipe(function(r) {
+ self.trigger('load_record', r);
+ });
});
}
return shown.pipe(function() {
@@ -354,7 +357,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
}
this._super();
},
- on_record_loaded: function(record) {
+ load_record: function(record) {
var self = this, set_values = [];
if (!record) {
this.set({ 'title' : undefined });
@@ -413,12 +416,14 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
* @return {$.Deferred}
*/
load_defaults: function () {
+ var self = this;
var keys = _.keys(this.fields_view.fields);
if (keys.length) {
- return this.dataset.default_get(keys)
- .pipe(this.on_record_loaded);
+ return this.dataset.default_get(keys).pipe(function(r) {
+ self.trigger('load_record', r);
+ });
}
- return this.on_record_loaded({});
+ return self.trigger('load_record', {});
},
on_form_changed: function() {
this.trigger("view_content_has_changed");
@@ -610,7 +615,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
return self.on_processed_onchange(response, processed);
} catch(e) {
console.error(e);
- instance.webclient.crashmanager.on_javascript_exception(e);
+ instance.webclient.crashmanager.show_message(e);
return $.Deferred().reject();
}
});
@@ -645,7 +650,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
return $.Deferred().resolve();
} catch(e) {
console.error(e);
- instance.webclient.crashmanager.on_javascript_exception(e);
+ instance.webclient.crashmanager.show_message(e);
return $.Deferred().reject();
}
},
@@ -752,9 +757,10 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
this.trigger('history_back');
} else {
this.to_view_mode();
- this.on_record_loaded(this.datarecord);
+ this.trigger('load_record', this.datarecord);
}
}
+ this.trigger('on_button_cancel');
return false;
},
on_button_new: function() {
@@ -778,7 +784,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
var def = $.Deferred();
$.when(this.has_been_loaded).then(function() {
self.dataset.call('copy', [self.datarecord.id, {}, self.dataset.context]).then(function(new_id) {
- return self.on_created({ result : new_id });
+ return self.record_created({ result : new_id });
}).then(function() {
return self.to_edit_mode();
}).then(function() {
@@ -855,7 +861,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
if (!self.datarecord.id) {
// Creation save
save_deferral = self.dataset.create(values).pipe(function(r) {
- return self.on_created(r, prepend_on_create);
+ return self.record_created(r, prepend_on_create);
}, null);
} else if (_.isEmpty(values) && ! self.force_dirty) {
// Not dirty, noop save
@@ -864,7 +870,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
self.force_dirty = false;
// Write save
save_deferral = self.dataset.write(self.datarecord.id, values, {}).pipe(function(r) {
- return self.on_saved(r);
+ return self.record_saved(r);
}, null);
}
return save_deferral;
@@ -891,12 +897,15 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
*
* @param {Object} r result of the write function.
*/
- on_saved: function(r) {
+ record_saved: function(r) {
+ var self = this;
if (!r) {
// should not happen in the server, but may happen for internal purpose
+ this.trigger('record_saved', r);
return $.Deferred().reject();
} else {
return $.when(this.reload()).pipe(function () {
+ self.trigger('record_saved', r);
return r;
});
}
@@ -914,9 +923,11 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
* @param {Boolean} [prepend_on_create=false] adds the newly created record
* at the beginning of the dataset instead of the end
*/
- on_created: function(r, prepend_on_create) {
+ record_created: function(r, prepend_on_create) {
+ var self = this;
if (!r) {
// should not happen in the server, but may happen for internal purpose
+ this.trigger('record_created', r);
return $.Deferred().reject();
} else {
this.datarecord.id = r;
@@ -930,9 +941,10 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
this.do_update_pager();
if (this.sidebar) {
this.sidebar.do_attachement_update(this.dataset, this.datarecord.id);
- }
+ }
//openerp.log("The record has been created with id #" + this.datarecord.id);
return $.when(this.reload()).pipe(function () {
+ self.trigger('record_created', r);
return _.extend(r, {created: true});
});
}
@@ -952,9 +964,15 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
} else {
var fields = _.keys(self.fields_view.fields);
fields.push('display_name');
- return self.dataset.read_index(fields, {
- context : { 'bin_size' : true, 'future_display_name' : true }
- }).pipe(self.on_record_loaded);
+ return self.dataset.read_index(fields,
+ {
+ context: {
+ 'bin_size': true,
+ 'future_display_name': true
+ }
+ }).pipe(function(r) {
+ self.trigger('load_record', r);
+ });
}
});
},
@@ -1618,13 +1636,14 @@ instance.web.form.FormDialog = instance.web.Dialog.extend({
return this;
},
start: function() {
+ var self = this;
this._super();
this.form = new instance.web.FormView(this, this.dataset, this.view_id, {
pager: false
});
this.form.appendTo(this.$el);
- this.form.on_created.add_last(this.on_form_dialog_saved);
- this.form.on_saved.add_last(this.on_form_dialog_saved);
+ this.form.on('record_created', self, this.on_form_dialog_saved);
+ this.form.on('record_saved', this, this.on_form_dialog_saved);
return this;
},
select_id: function(id) {
@@ -2068,7 +2087,11 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w
this.field = this.field_manager.get_field_desc(this.name);
this.widget = this.node.attrs.widget;
this.string = this.node.attrs.string || this.field.string || this.name;
- this.options = JSON.parse(this.node.attrs.options || '{}');
+ try {
+ this.options = JSON.parse(this.node.attrs.options || '{}');
+ } catch (e) {
+ throw new Error(_.str.sprintf(_t("Widget options for field '%s' are not valid JSON."), this.name));
+ }
this.set({'value': false});
this.on("change:value", this, function() {
@@ -2165,11 +2188,12 @@ instance.web.form.ReinitializeWidgetMixin = {
this.initialize_field();
},
initialize_field: function() {
- this.on("change:effective_readonly", this, function() {
- this.destroy_content();
- this.renderElement();
- this.initialize_content();
- });
+ this.on("change:effective_readonly", this, this.reinitialize);
+ this.initialize_content();
+ },
+ reinitialize: function() {
+ this.destroy_content();
+ this.renderElement();
this.initialize_content();
},
/**
@@ -2190,9 +2214,10 @@ instance.web.form.ReinitializeWidgetMixin = {
instance.web.form.ReinitializeFieldMixin = _.extend({}, instance.web.form.ReinitializeWidgetMixin, {
initialize_field: function() {
instance.web.form.ReinitializeWidgetMixin.initialize_field.call(this);
- this.on("change:effective_readonly", this, function() {
- this.render_value();
- });
+ this.render_value();
+ },
+ reinitialize: function() {
+ instance.web.form.ReinitializeWidgetMixin.reinitialize.call(this);
this.render_value();
},
/**
@@ -2212,7 +2237,7 @@ instance.web.form.FieldChar = instance.web.form.AbstractField.extend(instance.we
var self = this;
var $input = this.$el.find('input');
$input.change(function() {
- self.set({'value': instance.web.parse_value($input.val(), self)});
+ self.set({'value': self.parse_value($input.val())});
});
this.setupFocus($input);
},
@@ -2221,20 +2246,20 @@ instance.web.form.FieldChar = instance.web.form.AbstractField.extend(instance.we
this.render_value();
},
render_value: function() {
- var show_value = instance.web.format_value(this.get('value'), this, '');
+ var show_value = this.format_value(this.get('value'), '');
if (!this.get("effective_readonly")) {
this.$el.find('input').val(show_value);
} else {
if (this.password) {
show_value = new Array(show_value.length + 1).join('*');
}
- this.$el.text(show_value);
+ this.$(".oe_form_char_content").text(show_value);
}
},
is_syntax_valid: function() {
if (!this.get("effective_readonly")) {
try {
- var value_ = instance.web.parse_value(this.$el.find('input').val(), this, '');
+ var value_ = this.parse_value(this.$el.find('input').val(), '');
return true;
} catch(e) {
return false;
@@ -2242,6 +2267,12 @@ instance.web.form.FieldChar = instance.web.form.AbstractField.extend(instance.we
}
return true;
},
+ parse_value: function(val, def) {
+ return instance.web.parse_value(val, this, def);
+ },
+ format_value: function(val, def) {
+ return instance.web.format_value(val, this, def);
+ },
is_false: function() {
return this.get('value') === '' || this._super();
},
@@ -2959,7 +2990,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc
title: _t("Open: ") + self.string
}
);
- pop.on('on_write_complete', self, function(){
+ pop.on('write_completed', self, function(){
self.display_value = {};
self.render_value();
self.focus();
@@ -3285,11 +3316,7 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
var views = [];
_.each(modes, function(mode) {
if (! _.include(["list", "tree", "graph", "kanban"], mode)) {
- try {
- throw new Error(_.str.sprintf("View type '%s' is not supported in One2Many.", mode));
- } catch(e) {
- instance.webclient.crashmanager.on_javascript_exception(e)
- }
+ throw new Error(_.str.sprintf("View type '%s' is not supported in One2Many.", mode));
}
var view = {
view_id: false,
@@ -3357,9 +3384,9 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
if (self.get("effective_readonly")) {
$(".oe_form_buttons", controller.$el).children().remove();
}
- controller.on_record_loaded.add_last(function() {
- once.resolve();
- });
+ controller.on("load_record", self, function(){
+ once.resolve();
+ });
controller.on_pager_action.add_first(function() {
self.save_any_view();
});
@@ -3368,10 +3395,13 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({
}
def.resolve();
});
- this.viewmanager.on_mode_switch.add_first(function(n_mode, b, c, d, e) {
+ this.viewmanager.on("switch_mode", self, function(n_mode, b, c, d, e) {
$.when(self.save_any_view()).then(function() {
- if(n_mode === "list")
- $.async_when().then(function() {self.reload_current_view();});
+ if (n_mode === "list") {
+ $.async_when().then(function() {
+ self.reload_current_view();
+ });
+ }
});
});
this.is_setted.then(function() {
@@ -3539,7 +3569,7 @@ instance.web.form.One2ManyViewManager = instance.web.ViewManager.extend({
});
this.__ignore_blur = false;
},
- switch_view: function(mode, unused) {
+ switch_mode: function(mode, unused) {
if (mode !== 'form') {
return this._super(mode, unused);
}
@@ -3793,7 +3823,7 @@ instance.web.form.One2ManyList = instance.web.ListView.List.extend({
colspan: columns,
'class': 'oe_form_field_one2many_list_row_add'
}).append(
- $('<a>', {href: '#'}).text(_t("Add a row"))
+ $('<a>', {href: '#'}).text(_t("Add an item"))
.mousedown(function () {
// FIXME: needs to be an official API somehow
if (self.view.editor.is_editing()) {
@@ -3996,7 +4026,7 @@ instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({
this.dataset = new instance.web.form.Many2ManyDataSet(this, this.field.relation);
this.dataset.m2m = this;
- this.dataset.on_unlink.add_last(function(ids) {
+ this.dataset.on('unlink', self, function(ids) {
self.dataset_changed();
});
@@ -4108,7 +4138,7 @@ instance.web.form.Many2ManyListView = instance.web.ListView.extend(/** @lends in
title: _t("Open: ") + this.m2m_field.string,
readonly: this.getParent().get("effective_readonly")
});
- pop.on('on_write_complete', self, self.reload_content);
+ pop.on('write_completed', self, self.reload_content);
}
});
@@ -4129,7 +4159,7 @@ instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend(
this.dataset = new instance.web.form.Many2ManyDataSet(this, this.field.relation);
this.dataset.m2m = this;
- this.dataset.on_unlink.add_last(function(ids) {
+ this.dataset.on('unlink', self, function(ids) {
self.dataset_changed();
});
@@ -4177,7 +4207,7 @@ instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend(
self.initial_is_loaded.resolve();
loaded.resolve();
});
- this.kanban_view.do_switch_view.add_last(_.bind(this.open_popup, this));
+ this.kanban_view.on('switch_mode', this, this.open_popup);
$.async_when().then(function () {
self.kanban_view.appendTo(self.$el);
});
@@ -4356,7 +4386,7 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.extend({
this.dataset.write_function = function(id, data, options, sup) {
var fct = self.options.write_function || sup;
return fct.call(this, id, data, options).then(function() {
- self.trigger('on_write_complete');
+ self.trigger('write_completed');
});
};
this.dataset.parent_view = this.options.parent_view;
@@ -4790,9 +4820,9 @@ instance.web.form.FieldBinaryFile = instance.web.form.FieldBinary.extend({
this._super();
if (this.get("effective_readonly")) {
var self = this;
- this.$el.find('a').click(function() {
+ this.$el.find('a').click(function(ev) {
if (self.get('value')) {
- self.on_save_as();
+ self.on_save_as(ev);
}
return false;
});
@@ -4989,6 +5019,44 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({
},
});
+instance.web.form.FieldMonetary = instance.web.form.FieldFloat.extend({
+ template: "FieldMonetary",
+ init: function() {
+ this._super.apply(this, arguments);
+ this.set({"currency": false});
+ if (this.options.currency_field) {
+ this.field_manager.on("field_changed:" + this.options.currency_field, this, function() {
+ this.set({"currency": this.field_manager.get_field_value(this.options.currency_field)});
+ });
+ }
+ this.on("change:currency", this, this.get_currency_info);
+ this.get_currency_info();
+ this.ci_dm = new instance.web.DropMisordered();
+ },
+ start: function() {
+ var tmp = this._super();
+ this.on("change:currency_info", this, this.reinitialize);
+ return tmp;
+ },
+ get_currency_info: function() {
+ var self = this;
+ if (this.get("currency") === false) {
+ this.set({"currency_info": null});
+ return;
+ }
+ return this.ci_dm.add(new instance.web.Model("res.currency").query(["symbol", "position"])
+ .filter([["id", "=", self.get("currency")]]).first()).pipe(function(res) {
+ self.set({"currency_info": res});
+ });
+ },
+ parse_value: function(val, def) {
+ return instance.web.parse_value(val, {type: "float"}, def);
+ },
+ format_value: function(val, def) {
+ return instance.web.format_value(val, {type: "float"}, def);
+ },
+});
+
/**
* Registry of form fields, called by :js:`instance.web.FormView`.
*
@@ -5019,7 +5087,8 @@ instance.web.form.widgets = new instance.web.Registry({
'progressbar': 'instance.web.form.FieldProgressBar',
'image': 'instance.web.form.FieldBinaryImage',
'binary': 'instance.web.form.FieldBinaryFile',
- 'statusbar': 'instance.web.form.FieldStatus'
+ 'statusbar': 'instance.web.form.FieldStatus',
+ 'monetary': 'instance.web.form.FieldMonetary',
});
/**
diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js
index 892221a347b..fe0f525fe3f 100644
--- a/addons/web/static/src/js/view_list_editable.js
+++ b/addons/web/static/src/js/view_list_editable.js
@@ -626,7 +626,7 @@ openerp.web.list_editable = function (instance) {
},
start: function () {
var self = this;
- var _super = this._super();
+ var _super = this._super();
this.form.embedded_view = this._validate_view(
this.delegate.edition_view(this));
var form_ready = this.form.appendTo(this.$el).then(
@@ -708,10 +708,9 @@ openerp.web.list_editable = function (instance) {
var self = this;
var form = self.form;
var loaded = record
- ? form.on_record_loaded(_.extend({}, record))
+ ? form.trigger('load_record', _.extend({}, record))
: form.load_defaults();
-
- return loaded.pipe(function () {
+ return $.when(loaded).pipe(function () {
return form.do_show({reload: false});
}).pipe(function () {
self.record = form.datarecord;
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index b98d6d4802b..f985e5f6dc8 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -417,7 +417,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
this._super();
var self = this;
this.$el.find('.oe_view_manager_switch a').click(function() {
- self.on_mode_switch($(this).data('view-type'));
+ self.switch_mode($(this).data('view-type'));
}).tipsy();
var views_ids = {};
_.each(this.views_src, function(view) {
@@ -439,24 +439,17 @@ instance.web.ViewManager = instance.web.Widget.extend({
}
// If no default view defined, switch to the first one in sequence
var default_view = this.flags.default_view || this.views_src[0].view_type;
- return this.on_mode_switch(default_view);
+ return this.switch_mode(default_view);
},
- /**
- * Asks the view manager to switch visualization mode.
- *
- * @param {String} view_type type of view to display
- * @param {Boolean} [no_store=false] don't store the view being switched to on the switch stack
- * @returns {jQuery.Deferred} new view loading promise
- */
- on_mode_switch: function(view_type, no_store, view_options) {
+ switch_mode: function(view_type, no_store, view_options) {
var self = this;
var view = this.views[view_type];
var view_promise;
var form = this.views['form'];
if (!view || (form && form.controller && !form.controller.can_be_discarded())) {
+ self.trigger('switch_mode', view_type, no_store, view_options);
return $.Deferred().reject();
}
-
if (!no_store) {
this.views_history.push(view_type);
}
@@ -474,13 +467,12 @@ instance.web.ViewManager = instance.web.Widget.extend({
this.searchview[(view.controller.searchable === false || this.searchview.hidden) ? 'hide' : 'show']();
}
- this.$el
- .find('.oe_view_manager_switch a').parent().removeClass('active');
+ this.$el.find('.oe_view_manager_switch a').parent().removeClass('active');
this.$el
.find('.oe_view_manager_switch a').filter('[data-view-type="' + view_type + '"]')
.parent().addClass('active');
- return $.when(view_promise).then(function () {
+ r = $.when(view_promise).then(function () {
_.each(_.keys(self.views), function(view_name) {
var controller = self.views[view_name].controller;
if (controller) {
@@ -501,7 +493,9 @@ instance.web.ViewManager = instance.web.Widget.extend({
}
}
});
+ self.trigger('switch_mode', view_type, no_store, view_options);
});
+ return r;
},
do_create_view: function(view_type) {
// Lazy loading of views
@@ -530,7 +524,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
if (view.embedded_view) {
controller.set_embedded_view(view.embedded_view);
}
- controller.do_switch_view.add_last(_.bind(this.switch_view, this));
+ controller.on('switch_mode', self, this.switch_mode);
controller.do_prev_view.add_last(this.on_prev_view);
var container = this.$el.find(".oe_view_manager_view_" + view_type);
@@ -552,7 +546,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
add_breadcrumb: function(on_reverse_breadcrumb) {
var self = this;
var views = [this.active_view || this.views_src[0].view_type];
- this.on_mode_switch.add(function(mode) {
+ this.on('switch_mode', self, function(mode) {
var last = views.slice(-1)[0];
if (mode !== last) {
if (mode !== 'form') {
@@ -568,7 +562,7 @@ instance.web.ViewManager = instance.web.Widget.extend({
var view_to_select = views[index];
self.$el.show();
if (self.active_view !== view_to_select) {
- self.on_mode_switch(view_to_select);
+ self.switch_mode(view_to_select);
}
},
get_title: function() {
@@ -599,17 +593,9 @@ instance.web.ViewManager = instance.web.Widget.extend({
});
},
/**
- * Method used internally when a view asks to switch view. This method is meant
- * to be extended by child classes to change the default behavior, which simply
- * consist to switch to the asked view.
- */
- switch_view: function(view_type, no_store, options) {
- return this.on_mode_switch(view_type, no_store, options);
- },
- /**
* Returns to the view preceding the caller view in this manager's
* navigation history (the navigation history is appended to via
- * on_mode_switch)
+ * switch_mode)
*
* @param {Object} [options]
* @param {Boolean} [options.created=false] resource was created
@@ -623,12 +609,12 @@ instance.web.ViewManager = instance.web.Widget.extend({
if (options.created && current_view === 'form' && previous_view === 'list') {
// APR special case: "If creation mode from list (and only from a list),
// after saving, go to page view (don't come back in list)"
- return this.on_mode_switch('form');
+ return this.switch_mode('form');
} else if (options.created && !previous_view && this.action && this.action.flags.default_view === 'form') {
// APR special case: "If creation from dashboard, we have no previous view
- return this.on_mode_switch('form');
+ return this.switch_mode('form');
}
- return this.on_mode_switch(previous_view, true);
+ return this.switch_mode(previous_view, true);
},
/**
* Sets up the current viewmanager's search view.
@@ -897,7 +883,7 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({
}, action || {});
this.do_action(action);
},
- on_mode_switch: function (view_type, no_store, options) {
+ switch_mode: function (view_type, no_store, options) {
var self = this;
return $.when(this._super.apply(this, arguments)).then(function () {
@@ -932,7 +918,7 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({
if (state.view_type && state.view_type !== this.active_view) {
defs.push(
this.views[this.active_view].deferred.pipe(function() {
- return self.on_mode_switch(state.view_type, true);
+ return self.switch_mode(state.view_type, true);
})
);
}
@@ -1271,6 +1257,7 @@ instance.web.View = instance.web.Widget.extend({
* @param {String} view view type to switch to
*/
do_switch_view: function(view) {
+ this.trigger('switch_mode',view);
},
/**
* Cancels the switch to the current view, switches to the previous one
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index bf55db8d7c2..a09897862f6 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -548,7 +548,7 @@
<a class="oe_sidebar_action_a" t-att-title="item.title" t-att-data-section="section.name" t-att-data-index="item_index" t-att-href="item.url" target="_blank">
<t t-raw="item.label"/>
</a>
- <a t-if="section.name == 'files'" class="oe_sidebar_delete_item" t-att-data-id="item.id" title="Delete this attachment">x</a>
+ <a t-if="section.name == 'files' and !item.callback" class="oe_sidebar_delete_item" t-att-data-id="item.id" title="Delete this attachment">x</a>
</li>
<li t-if="section.name == 'files'" class="oe_sidebar_add_attachment">
<t t-call="HiddenInputFile">
@@ -916,7 +916,7 @@
</t>
<t t-name="FieldChar">
<span t-att-class="'oe_form_field '+widget.widget_class" t-att-style="widget.node.attrs.style">
- <t t-if="!widget.get('effective_readonly')">
+ <t t-if="!widget.get('effective_readonly')">
<input t-att-type="widget.password ? 'password' : 'text'"
t-att-id="widget.id_for_label"
t-att-tabindex="widget.node.attrs.tabindex"
@@ -925,6 +925,9 @@
t-att-maxlength="widget.field.size"
/><img class="oe_field_translate oe_input_icon" t-if="widget.field.translate" t-att-src='_s + "/web/static/src/img/icons/terp-translate.png"' width="16" height="16" border="0"/>
</t>
+ <t t-if="widget.get('effective_readonly')">
+ <span class="oe_form_char_content"></span>
+ </t>
</span>
</t>
<t t-name="FieldEmail">
@@ -1534,7 +1537,7 @@
<td colspan="3">
<label for="import_compat">Export Type:</label>
<select id="import_compat" name="import_compat">
- <option value="yes">Import Compatible Export</option>
+ <option value="yes">Import-Compatible Export</option>
<option value="">Export all Data</option>
</select>
@@ -1717,4 +1720,16 @@
<button class="oe_form_m2o_sc_button oe_button">Add All Info...</button>
<button class="oe_form_m2o_cancel_button oe_button">Cancel</button>
</t>
+<t t-name="FieldMonetary" t-extend="FieldChar">
+ <t t-jquery="t:first" t-operation="before">
+ <t t-if="widget.get('currency_info') and widget.get('currency_info').position === 'before'">
+ <t t-esc="widget.get('currency_info').symbol"/>
+ </t>
+ </t>
+ <t t-jquery="t:last" t-operation="after">
+ <t t-if="widget.get('currency_info') and widget.get('currency_info').position === 'after'">
+ <t t-esc="widget.get('currency_info').symbol"/>
+ </t>
+ </t>
+</t>
</templates>