diff options
| author | Hiral Patel (OpenERP) <hip@tinyerp.com> | 2012-11-26 17:30:04 +0530 |
|---|---|---|
| committer | Hiral Patel (OpenERP) <hip@tinyerp.com> | 2012-11-26 17:30:04 +0530 |
| commit | 59ccb3cc3d499f79df268d9c6006ca4beba2d3f5 (patch) | |
| tree | f197f93792b971ddd8e0b60b0124cd22807b5179 /addons/web/static/src/js | |
| parent | 786b11f31dd45b6af61b7a74dc7894ab7914faba (diff) | |
| parent | 7f9b18dc1d173586dbdcd611bc1f752162ad2a8b (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.js | 197 | ||||
| -rw-r--r-- | addons/web/static/src/js/coresetup.js | 2 | ||||
| -rw-r--r-- | addons/web/static/src/js/data_export.js | 1 | ||||
| -rw-r--r-- | addons/web/static/src/js/search.js | 14 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_form.js | 32 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_list.js | 2 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_list_editable.js | 8 | ||||
| -rw-r--r-- | addons/web/static/src/js/views.js | 22 |
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 |
