summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js
diff options
context:
space:
mode:
authorHiral Patel (OpenERP) <hip@tinyerp.com>2012-11-26 17:30:04 +0530
committerHiral Patel (OpenERP) <hip@tinyerp.com>2012-11-26 17:30:04 +0530
commit59ccb3cc3d499f79df268d9c6006ca4beba2d3f5 (patch)
treef197f93792b971ddd8e0b60b0124cd22807b5179 /addons/web/static/src/js
parent786b11f31dd45b6af61b7a74dc7894ab7914faba (diff)
parent7f9b18dc1d173586dbdcd611bc1f752162ad2a8b (diff)
[MERGE] Merge with lp:openerp-web
bzr revid: hip@tinyerp.com-20121126120004-svopvxi5btx8nawc
Diffstat (limited to 'addons/web/static/src/js')
-rw-r--r--addons/web/static/src/js/chrome.js197
-rw-r--r--addons/web/static/src/js/coresetup.js2
-rw-r--r--addons/web/static/src/js/data_export.js1
-rw-r--r--addons/web/static/src/js/search.js14
-rw-r--r--addons/web/static/src/js/view_form.js32
-rw-r--r--addons/web/static/src/js/view_list.js2
-rw-r--r--addons/web/static/src/js/view_list_editable.js8
-rw-r--r--addons/web/static/src/js/views.js22
8 files changed, 174 insertions, 104 deletions
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index b95550c74a0..e355f08bb7c 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -52,8 +52,29 @@ instance.web.dialog = function(element) {
return result;
};
+/**
+ A useful class to handle dialogs.
+
+ Attributes:
+ - $buttons: A jQuery element targeting a dom part where buttons can be added. It always exists
+ during the lifecycle of the dialog.
+*/
instance.web.Dialog = instance.web.Widget.extend({
dialog_title: "",
+ /**
+ Constructor.
+
+ @param {Widget} parent
+ @param {dictionary} options A dictionary that will be forwarded to jQueryUI Dialog. Additionaly, that
+ dictionary can contain the following keys:
+ - buttons: Deprecated. The buttons key is not propagated to jQueryUI Dialog. It must be a dictionary (key = button
+ label, value = click handler) or a list of dictionaries (each element in the dictionary is send to the
+ corresponding method of a jQuery element targeting the <button> tag). It is deprecated because all dialogs
+ in OpenERP must be personalized in some way (button in red, link instead of button, ...) and this
+ feature does not allow that kind of personalization.
+ - destroy_on_close: Default true. If true and the dialog is closed, it is automatically destroyed.
+ @param {jQuery object} content Some content to replace this.$el .
+ */
init: function (parent, options, content) {
var self = this;
this._super(parent);
@@ -66,50 +87,49 @@ instance.web.Dialog = instance.web.Widget.extend({
max_width: '95%',
height: 'auto',
min_height: 0,
- max_height: this.get_height('100%') - 200,
+ max_height: $(window.top).height() - 200,
autoOpen: false,
position: [false, 40],
- buttons: {},
+ buttons: null,
beforeClose: function () {
self.trigger("closing");
},
- resizeStop: this.on_resized
+ resizeStop: function() {
+ self.trigger("resized");
+ },
};
- for (var f in this) {
- if (f.substr(0, 10) == 'on_button_') {
- this.dialog_options.buttons[f.substr(10)] = this[f];
- }
- }
if (options) {
_.extend(this.dialog_options, options);
}
this.on("closing", this, this._closing);
+ this.$buttons = $('<div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"><span class="oe_dialog_custom_buttons"/></div>');
},
- get_options: function(options) {
- var self = this,
- o = _.extend({}, this.dialog_options, options || {});
- _.each(['width', 'height'], function(unit) {
- o[unit] = self['get_' + unit](o[unit]);
- o['min_' + unit] = self['get_' + unit](o['min_' + unit] || 0);
- o['max_' + unit] = self['get_' + unit](o['max_' + unit] || 0);
- if (o[unit] !== 'auto' && o['min_' + unit] && o[unit] < o['min_' + unit]) o[unit] = o['min_' + unit];
- if (o[unit] !== 'auto' && o['max_' + unit] && o[unit] > o['max_' + unit]) o[unit] = o['max_' + unit];
+ _get_options: function() {
+ var self = this;
+ var o = _.extend({}, this.dialog_options);
+ var sizes = {
+ width: $(window.top).width(),
+ height: $(window.top).height(),
+ };
+ _.each(sizes, function(available_size, unit) {
+ o[unit] = self._get_size(o[unit], available_size);
+ o['min_' + unit] = self._get_size(o['min_' + unit] || 0, available_size);
+ o['max_' + unit] = self._get_size(o['max_' + unit] || 0, available_size);
+ if (o[unit] !== 'auto' && o['min_' + unit] && o[unit] < o['min_' + unit]) {
+ o[unit] = o['min_' + unit];
+ }
+ if (o[unit] !== 'auto' && o['max_' + unit] && o[unit] > o['max_' + unit]) {
+ o[unit] = o['max_' + unit];
+ }
});
- if (!o.title && this.dialog_title) {
- o.title = this.dialog_title;
- }
+ o.title = o.title || this.dialog_title;
return o;
},
- get_width: function(val) {
- return this.get_size(val.toString(), $(window.top).width());
- },
- get_height: function(val) {
- return this.get_size(val.toString(), $(window.top).height());
- },
- get_size: function(val, available_size) {
+ _get_size: function(val, available_size) {
+ val = val.toString();
if (val === 'auto') {
return val;
- } else if (val.slice(-1) == "%") {
+ } else if (val.slice(-1) === "%") {
return Math.round(available_size / 100 * parseInt(val.slice(0, -1), 10));
} else {
return parseInt(val, 10);
@@ -122,41 +142,58 @@ instance.web.Dialog = instance.web.Widget.extend({
this._super();
}
},
- open: function(options) {
- if (! this.dialog_inited)
+ /**
+ Opens the popup. Inits the dialog if it is not already inited.
+
+ @return this
+ */
+ open: function() {
+ if (!this.dialog_inited) {
this.init_dialog();
- var o = this.get_options(options);
- this.add_buttons(o.buttons);
- delete(o.buttons);
- this.$buttons.appendTo($("body"));
- instance.web.dialog(this.$el, o).dialog('open');
- this.$el.dialog("widget").find(".ui-dialog-buttonpane").remove();
- this.$buttons.appendTo(this.$el.dialog("widget"));
- if (o.height === 'auto' && o.max_height) {
- this.$el.css({ 'max-height': o.max_height, 'overflow-y': 'auto' });
}
+ this.$el.dialog('open');
+ this.$el.dialog("widget").append(this.$buttons);
return this;
},
- add_buttons: function(buttons) {
+ _add_buttons: function(buttons) {
var self = this;
- _.each(buttons, function(fn, but) {
- var $but = $(QWeb.render('WidgetButton', { widget : { string: but, node: { attrs: {} }}}));
- self.$buttons.append($but);
+ var $customButons = this.$buttons.find('.oe_dialog_custom_buttons').empty();
+ _.each(buttons, function(fn, text) {
+ // buttons can be object or array
+ if (!_.isFunction(fn)) {
+ text = fn.text;
+ fn = fn.click;
+ }
+ var $but = $(QWeb.render('WidgetButton', { widget : { string: text, node: { attrs: {} }}}));
+ $customButons.append($but);
$but.on('click', function(ev) {
fn.call(self.$el, ev);
});
});
},
- init_dialog: function(options) {
+ /**
+ Initializes the popup.
+
+ @return The result returned by start().
+ */
+ init_dialog: function() {
+ var options = this._get_options();
+ if (options.buttons) {
+ this._add_buttons(options.buttons);
+ delete(options.buttons);
+ }
this.renderElement();
- var o = this.get_options(options);
- instance.web.dialog(this.$el, o);
- this.$buttons = $('<div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" />');
- this.$el.dialog("widget").append(this.$buttons);
+ instance.web.dialog(this.$el, options);
+ if (options.height === 'auto' && options.max_height) {
+ this.$el.css({ 'max-height': options.max_height, 'overflow-y': 'auto' });
+ }
this.dialog_inited = true;
var res = this.start();
return res;
},
+ /**
+ Closes the popup, if destroy_on_close was passed to the constructor, it is also destroyed.
+ */
close: function() {
if (this.dialog_inited && this.$el.is(":data(dialog)")) {
this.$el.dialog('close');
@@ -171,9 +208,11 @@ instance.web.Dialog = instance.web.Widget.extend({
this.__tmp_dialog_closing = undefined;
}
},
- on_resized: function() {
- },
+ /**
+ Destroys the popup, also closes it.
+ */
destroy: function () {
+ this.$buttons.remove();
_.each(this.getChildren(), function(el) {
el.destroy();
});
@@ -182,7 +221,7 @@ instance.web.Dialog = instance.web.Widget.extend({
this.close();
this.__tmp_dialog_destroying = undefined;
}
- if (this.dialog_inited && !this.isDestroyed()) {
+ if (this.dialog_inited && !this.isDestroyed() && this.$el.is(":data(dialog)")) {
this.$el.dialog('destroy');
}
this._super();
@@ -565,13 +604,19 @@ instance.web.Login = instance.web.Widget.extend({
self.$el.find('.oe_login_manage_db').click(function() {
self.do_action("database_manager");
});
- var d;
- if (self.params.db) {
- if (self.params.login && self.params.password) {
- d = self.do_login(self.params.db, self.params.login, self.params.password);
- }
+ var d = $.when();
+ if ($.deparam.querystring().db) {
+ self.params.db = $.deparam.querystring().db;
+ }
+ // used by dbmanager.do_create via internal client action
+ if (self.params.db && self.params.login && self.params.password) {
+ d = self.do_login(self.params.db, self.params.login, self.params.password);
} else {
- d = self.rpc("/web/database/get_list", {}).done(self.on_db_loaded).fail(self.on_db_failed);
+ if (self.params.db) {
+ self.on_db_loaded([self.params.db])
+ } else {
+ d = self.rpc("/web/database/get_list", {}).done(self.on_db_loaded).fail(self.on_db_failed);
+ }
}
return d;
},
@@ -720,20 +765,24 @@ instance.web.ChangePassword = instance.web.Widget.extend({
template: "ChangePassword",
start: function() {
var self = this;
- self.$el.validate({
- submitHandler: function (form) {
- self.rpc("/web/session/change_password",{
- 'fields': $(form).serializeArray()
- }).done(function(result) {
- if (result.error) {
- self.display_error(result);
- return;
- } else {
- instance.webclient.on_logout();
- }
- });
- }
- });
+ this.getParent().dialog_title = "Change Password";
+ var $button = self.$el.find('.oe_form_button');
+ $button.appendTo(this.getParent().$buttons);
+ $button.eq(2).click(function(){
+ self.getParent().close();
+ })
+ $button.eq(0).click(function(){
+ self.rpc("/web/session/change_password",{
+ 'fields': $("form[name=change_password_form]").serializeArray()
+ }).done(function(result) {
+ if (result.error) {
+ self.display_error(result);
+ return;
+ } else {
+ instance.webclient.on_logout();
+ }
+ });
+ })
},
display_error: function (error) {
return instance.web.dialog($('<div>'), {
@@ -981,7 +1030,7 @@ instance.web.Client = instance.web.Widget.extend({
start: function() {
var self = this;
return instance.session.session_bind(this.origin).then(function() {
- var $e = $(QWeb.render(self._template, {}));
+ var $e = $(QWeb.render(self._template, {widget: self}));
self.replaceElement($e);
$e.openerpClass();
self.bind_events();
@@ -1049,9 +1098,7 @@ instance.web.WebClient = instance.web.Client.extend({
start: function() {
var self = this;
return $.when(this._super()).then(function() {
- self.$el.on('click', '.oe_logo', function() {
- self.action_manager.do_action('home');
- });
+ self.$(".oe_logo").attr("href", $.param.fragment("" + window.location, "", 2).slice(0, -1));
if (jQuery.param !== undefined && jQuery.deparam(jQuery.param.querystring()).kitten !== undefined) {
$("body").addClass("kitten-mode-activated");
if ($.blockUI) {
diff --git a/addons/web/static/src/js/coresetup.js b/addons/web/static/src/js/coresetup.js
index 7ddefa301f2..8b12f39c5e4 100644
--- a/addons/web/static/src/js/coresetup.js
+++ b/addons/web/static/src/js/coresetup.js
@@ -543,12 +543,12 @@ instance.web._lt = function (s) {
return {toString: function () { return instance.web._t(s); }}
};
instance.web.qweb = new QWeb2.Engine();
-instance.web.qweb.default_dict['__debug__'] = instance.session.debug; // Which one ?
instance.web.qweb.debug = instance.session.debug;
instance.web.qweb.default_dict = {
'_' : _,
'_t' : instance.web._t,
'JSON': JSON,
+ '__debug__': instance.session.debug,
};
instance.web.qweb.preprocess_node = function() {
// Note that 'this' is the Qweb Node
diff --git a/addons/web/static/src/js/data_export.js b/addons/web/static/src/js/data_export.js
index 477d89c99b3..e38d21d1cd2 100644
--- a/addons/web/static/src/js/data_export.js
+++ b/addons/web/static/src/js/data_export.js
@@ -22,7 +22,6 @@ instance.web.DataExport = instance.web.Dialog.extend({
start: function() {
var self = this;
this._super.apply(this, arguments);
- this.open();
self.$el.removeClass('ui-dialog-content ui-widget-content');
self.$el.find('#add_field').click(function() {
if ($('#field-tree-structure tr.ui-selected')) {
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index 0f25b2484c3..88d45793173 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -1893,6 +1893,9 @@ instance.web.search.ExtendedSearchProposition.DateTime = instance.web.search.Ext
get_value: function() {
return this.datewidget.get_value();
},
+ toString: function () {
+ return instance.web.format_value(this.get_value(), { type:"datetime" });
+ },
start: function() {
var ready = this._super();
this.datewidget = new (this.widget())(this);
@@ -1901,7 +1904,10 @@ instance.web.search.ExtendedSearchProposition.DateTime = instance.web.search.Ext
}
});
instance.web.search.ExtendedSearchProposition.Date = instance.web.search.ExtendedSearchProposition.DateTime.extend({
- widget: function () { return instance.web.DateWidget; }
+ widget: function () { return instance.web.DateWidget; },
+ toString: function () {
+ return instance.web.format_value(this.get_value(), { type:"date" });
+ }
});
instance.web.search.ExtendedSearchProposition.Integer = instance.web.search.ExtendedSearchProposition.Field.extend({
template: 'SearchView.extended_search.proposition.integer',
@@ -1918,7 +1924,8 @@ instance.web.search.ExtendedSearchProposition.Integer = instance.web.search.Exte
},
get_value: function() {
try {
- return instance.web.parse_value(this.$el.val(), {'widget': 'integer'});
+ var val =this.$el.val();
+ return instance.web.parse_value(val == "" ? 0 : val, {'widget': 'integer'});
} catch (e) {
return "";
}
@@ -1942,7 +1949,8 @@ instance.web.search.ExtendedSearchProposition.Float = instance.web.search.Extend
},
get_value: function() {
try {
- return instance.web.parse_value(this.$el.val(), {'widget': 'float'});
+ var val =this.$el.val();
+ return instance.web.parse_value(val == "" ? 0.0 : val, {'widget': 'float'});
} catch (e) {
return "";
}
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index dad622fb7f9..b0ad23d6854 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -195,7 +195,6 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
this.sidebar.add_items('other', _.compact([
self.is_action_enabled('delete') && { label: _t('Delete'), callback: self.on_button_delete },
self.is_action_enabled('create') && { label: _t('Duplicate'), callback: self.on_button_duplicate },
- { label: _t('Set Default'), callback: function (item) { self.open_defaults_dialog(); } }
]));
}
@@ -1009,8 +1008,8 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
}
return true;
},
- sidebar_context: function () {
- return this.save().then(_.bind(function() {return this.get_fields_values();}, this));
+ sidebar_eval_context: function () {
+ return $.when(this.build_eval_context());
},
open_defaults_dialog: function () {
var self = this;
@@ -1215,7 +1214,7 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
var doc = $.parseXML('<div class="oe_form">' + xml + '</div>');
$('button', doc).each(function() {
- $(this).attr('data-button-type', $(this).attr('type'));
+ $(this).attr('data-button-type', $(this).attr('type')).attr('type', 'button');
});
xml = instance.web.xml_to_str(doc);
return $(xml);
@@ -4026,6 +4025,9 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in
}
this._super(value_);
},
+ is_false: function() {
+ return _(this.get("value")).isEmpty();
+ },
get_value: function() {
var tmp = [commands.replace_with(this.get("value"))];
return tmp;
@@ -4236,16 +4238,14 @@ instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend(
var self = this;
self.load_view();
- this.is_loaded.done(function() {
- self.on("change:effective_readonly", self, function() {
- self.is_loaded = self.is_loaded.then(function() {
- self.kanban_view.destroy();
- return $.when(self.load_view()).done(function() {
- self.render_value();
- });
+ self.on("change:effective_readonly", self, function() {
+ self.is_loaded = self.is_loaded.then(function() {
+ self.kanban_view.destroy();
+ return $.when(self.load_view()).done(function() {
+ self.render_value();
});
});
- })
+ });
},
set_value: function(value_) {
value_ = value_ || [];
@@ -4628,6 +4628,8 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
'selectable': !self.options.disable_multiple_selection,
'import_enabled': false,
'$buttons': self.$buttonpane,
+ 'disable_editable_mode': true,
+ '$pager': self.$('.oe_popup_list_pager'),
}, self.options.list_view_options || {}));
self.view_list.on('edit:before', self, function (e) {
e.cancel = true;
@@ -4787,6 +4789,7 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance.
this._super(field_manager, node);
this.binary_value = false;
this.useFileAPI = !!window.FileReader;
+ this.max_upload_size = 25 * 1024 * 1024; // 25Mo
if (!this.useFileAPI) {
this.fileupload_id = _.uniqueId('oe_fileupload');
$(window).on(this.fileupload_id, function() {
@@ -4812,6 +4815,11 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance.
if ((this.useFileAPI && file_node.files.length) || (!this.useFileAPI && $(file_node).val() !== '')) {
if (this.useFileAPI) {
var file = file_node.files[0];
+ if (file.size > this.max_upload_size) {
+ var msg = _t("The selected file exceed the maximum file size of %s.");
+ instance.webclient.notification.warn(_t("File upload"), _.str.sprintf(msg, instance.web.human_size(this.max_upload_size)));
+ return false;
+ }
var filereader = new FileReader();
filereader.readAsDataURL(file);
filereader.onloadend = function(upload) {
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index df74674a343..55e3c17b494 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -21,6 +21,8 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
// whether the view rows can be reordered (via vertical drag & drop)
'reorderable': true,
'action_buttons': true,
+ //whether the editable property of the view has to be disabled
+ 'disable_editable_mode': false,
},
view_type: 'tree',
/**
diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js
index 1abe3caab39..db7e22e5f32 100644
--- a/addons/web/static/src/js/view_list_editable.js
+++ b/addons/web/static/src/js/view_list_editable.js
@@ -78,18 +78,20 @@ openerp.web.list_editable = function (instance) {
_.extend(this.dataset, dataset);
},
do_delete: function (ids) {
+ var nonfalse = _.compact(ids);
var _super = this._super.bind(this);
var next = this.editor.is_editing()
? this.cancel_edition(true)
: $.when();
return next.then(function () {
- return _super(ids);
+ return _super(nonfalse);
});
},
editable: function () {
- return this.fields_view.arch.attrs.editable
+ return !this.options.disable_editable_mode
+ && (this.fields_view.arch.attrs.editable
|| this._context_editable
- || this.options.editable;
+ || this.options.editable);
},
/**
* Replace do_search to handle editability process
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index 641821152b2..81662ac6487 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -26,6 +26,7 @@ instance.web.ActionManager = instance.web.Widget.extend({
if (this.dialog) {
this.dialog.destroy();
}
+ this.dialog = null;
},
/**
* Add a new item to the breadcrumb
@@ -318,7 +319,6 @@ instance.web.ActionManager = instance.web.Widget.extend({
dialogClass: executor.klass,
});
this.dialog.on("closing", null, options.on_close);
- this.dialog.init_dialog();
this.dialog.dialog_title = executor.action.name;
if (widget instanceof instance.web.ViewManager) {
_.extend(widget.flags, {
@@ -809,6 +809,9 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({
case 'toggle_layout_outline':
current_view.rendering_engine.toggle_layout_debugging();
break;
+ case 'set_defaults':
+ current_view.open_defaults_dialog();
+ break;
case 'translate':
this.do_action({
name: "Technical Translation",
@@ -1060,23 +1063,24 @@ instance.web.Sidebar = instance.web.Widget.extend({
},
on_item_action_clicked: function(item) {
var self = this;
- self.getParent().sidebar_context().done(function (context) {
+ self.getParent().sidebar_eval_context().done(function (sidebar_eval_context) {
var ids = self.getParent().get_selected_ids();
if (ids.length == 0) {
instance.web.dialog($("<div />").text(_t("You must choose at least one record.")), { title: _t("Warning"), modal: true });
return false;
}
- var additional_context = _.extend({
+ var active_ids_context = {
active_id: ids[0],
active_ids: ids,
active_model: self.getParent().dataset.model
- }, context);
+ };
self.rpc("/web/action/load", {
action_id: item.action.id,
- context: additional_context
+ context: active_ids_context,
+ eval_context: new instance.web.CompoundContext(sidebar_eval_context, active_ids_context),
}).done(function(result) {
- result.context = _.extend(result.context || {},
- additional_context);
+ console.log(result.context);
+ result.context = new instance.web.CompoundContext(result.context || {}, active_ids_context);
result.flags = result.flags || {};
result.flags.new_window = true;
self.do_action(result, {
@@ -1329,8 +1333,8 @@ instance.web.View = instance.web.Widget.extend({
on_sidebar_export: function() {
new instance.web.DataExport(this, this.dataset).open();
},
- sidebar_context: function () {
- return $.when();
+ sidebar_eval_context: function () {
+ return $.when({});
},
/**
* Asks the view to reload itself, if the reloading is asynchronous should