diff options
| author | Xavier Morel <xmo@openerp.com> | 2012-07-11 13:29:59 +0200 |
|---|---|---|
| committer | Xavier Morel <xmo@openerp.com> | 2012-07-11 13:29:59 +0200 |
| commit | e431cda2d34f3ff066722232c52bd3987e973b7b (patch) | |
| tree | 5dfe24e9dfd9f351aea9fcb67d7b92670950b2f3 /addons/web/static/src/js | |
| parent | 3efc9c033a7f9b2a1d032951785ff5a94ecdbe6c (diff) | |
| parent | f419cb8e024ea6a8713091714f940f2ffddf150e (diff) | |
[MERGE} from trunk
bzr revid: xmo@openerp.com-20120711112959-tcb9epdfc9frt6ux
Diffstat (limited to 'addons/web/static/src/js')
| -rw-r--r-- | addons/web/static/src/js/chrome.js | 98 | ||||
| -rw-r--r-- | addons/web/static/src/js/corelib.js | 6 | ||||
| -rw-r--r-- | addons/web/static/src/js/coresetup.js | 47 | ||||
| -rw-r--r-- | addons/web/static/src/js/data_import.js | 14 | ||||
| -rw-r--r-- | addons/web/static/src/js/formats.js | 2 | ||||
| -rw-r--r-- | addons/web/static/src/js/search.js | 149 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_editor.js | 27 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_form.js | 171 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_list.js | 71 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_tree.js | 9 | ||||
| -rw-r--r-- | addons/web/static/src/js/views.js | 11 |
11 files changed, 384 insertions, 221 deletions
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index a398ceb67d9..b87ebe56856 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -136,14 +136,18 @@ instance.web.Dialog = instance.web.Widget.extend({ }, on_close: function() { if (this.dialog_options.destroy_on_close) { - this.$element.dialog('destroy'); + this.destroy(); } }, on_resized: function() { }, destroy: function () { - this.close(); - this.$element.dialog('destroy'); + _.each(this.getChildren(), function(el) { + el.destroy(); + }); + if (! this.isDestroyed()) { + this.$element.dialog('destroy'); + } this._super(); } }); @@ -401,7 +405,14 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ success: function () { self.do_notify(_t("Backed"), _t("Database backed up successfully")); }, - error: instance.webclient.crashmanager.on_rpc_error, + error: function(error){ + if(error){ + self.display_error({ + title: 'Backup Database', + error: 'AccessDenied' + }); + } + }, complete: function() { self.unblockUI(); } @@ -538,6 +549,7 @@ instance.web.Login = instance.web.Widget.extend({ do_login: function (db, login, password) { var self = this; this.$element.removeClass('oe_login_invalid'); + self.$(".oe_login_pane").fadeOut("slow"); return this.session.session_authenticate(db, login, password).pipe(function() { if (self.has_local_storage) { if(self.remember_credentials) { @@ -552,9 +564,9 @@ instance.web.Login = instance.web.Widget.extend({ localStorage.setItem('last_password_login_success', ''); } } - self.$(".oe_login_pane").fadeOut("slow"); self.trigger("login"); },function () { + self.$(".oe_login_pane").fadeIn("fast"); self.$element.addClass("oe_login_invalid"); }); } @@ -571,6 +583,7 @@ instance.web.Menu = instance.web.Widget.extend({ start: function() { this._super.apply(this, arguments); this.$secondary_menus = this.getParent().$element.find('.oe_secondary_menus_container'); + this.$secondary_menus.on('click', 'a[data-menu]', this.on_menu_click); return this.do_reload(); }, do_reload: function() { @@ -583,7 +596,6 @@ instance.web.Menu = instance.web.Widget.extend({ this.limit_entries(); this.$secondary_menus.html(QWeb.render("Menu.secondary", { widget : this })); this.$element.on('click', 'a[data-menu]', this.on_menu_click); - this.$secondary_menus.on('click', 'a[data-menu]', this.on_menu_click); // Hide second level submenus this.$secondary_menus.find('.oe_menu_toggler').siblings('.oe_secondary_submenu').hide(); if (self.current_menu) { @@ -665,32 +677,37 @@ instance.web.Menu = instance.web.Widget.extend({ * Process a click on a menu item * * @param {Number} id the menu_id + * @param {Boolean} [needaction=false] whether the triggered action should execute in a `needs action` context */ - menu_click: function(id) { - if (id) { - // find back the menuitem in dom to get the action - var $item = this.$element.find('a[data-menu=' + id + ']'); - if (!$item.length) { - $item = this.$secondary_menus.find('a[data-menu=' + id + ']'); - } - var action_id = $item.data('action-id'); - // If first level menu doesnt have action trigger first leaf - if (!action_id) { - if(this.$element.has($item).length) { - $sub_menu = this.$secondary_menus.find('.oe_secondary_menu[data-menu-parent=' + id + ']'); - $items = $sub_menu.find('a[data-action-id]').filter('[data-action-id!=""]'); - if($items.length) { - action_id = $items.data('action-id'); - id = $items.data('menu'); - } + menu_click: function(id, needaction) { + if (!id) { return; } + + // find back the menuitem in dom to get the action + var $item = this.$element.find('a[data-menu=' + id + ']'); + if (!$item.length) { + $item = this.$secondary_menus.find('a[data-menu=' + id + ']'); + } + var action_id = $item.data('action-id'); + // If first level menu doesnt have action trigger first leaf + if (!action_id) { + if(this.$element.has($item).length) { + var $sub_menu = this.$secondary_menus.find('.oe_secondary_menu[data-menu-parent=' + id + ']'); + var $items = $sub_menu.find('a[data-action-id]').filter('[data-action-id!=""]'); + if($items.length) { + action_id = $items.data('action-id'); + id = $items.data('menu'); } } - this.open_menu(id); - this.current_menu = id; - this.session.active_id = id; - if (action_id) { - this.trigger('menu_click', action_id, id, $item); - } + } + this.open_menu(id); + this.current_menu = id; + this.session.active_id = id; + if (action_id) { + this.trigger('menu_click', { + action_id: action_id, + needaction: needaction, + id: id + }, $item); } }, /** @@ -700,7 +717,8 @@ instance.web.Menu = instance.web.Widget.extend({ */ on_menu_click: function(ev) { ev.preventDefault(); - this.menu_click($(ev.currentTarget).data('menu')); + var needaction = $(ev.target).is('div.oe_menu_counter'); + this.menu_click($(ev.currentTarget).data('menu'), needaction); }, }); @@ -855,12 +873,12 @@ instance.web.WebClient = instance.web.Widget.extend({ }, start: function() { var self = this; - this.$element.addClass("openerp openerp-web-client-container"); + this.$element.addClass("openerp openerp_webclient_container"); if (jQuery.param !== undefined && jQuery.deparam(jQuery.param.querystring()).kitten !== undefined) { $("body").addClass("kitten-mode-activated"); - self.$element.delegate('img.oe-record-edit-link-img', 'hover', function(e) { - self.$element.toggleClass('clark-gable'); - }); + if ($.blockUI) { + $.blockUI.defaults.message = '<img src="http://www.amigrave.com/kitten.gif">'; + } } this.session.session_bind().then(function() { self.destroy_content(); @@ -1010,8 +1028,16 @@ instance.web.WebClient = instance.web.Widget.extend({ this._current_state = _.clone(state); $.bbq.pushState(url); }, - on_menu_action: function(action) { - this.action_manager.do_action(action); + on_menu_action: function(options) { + var self = this; + this.rpc("/web/action/load", { action_id: options.action_id }) + .then(function (result) { + var action = result.result; + if (options.needaction) { + action.context.search_default_needaction_pending = true; + } + self.action_manager.do_action(action); + }); }, do_action: function(action) { var self = this; diff --git a/addons/web/static/src/js/corelib.js b/addons/web/static/src/js/corelib.js index 5af51fa519a..1ed4c4788e3 100644 --- a/addons/web/static/src/js/corelib.js +++ b/addons/web/static/src/js/corelib.js @@ -1307,19 +1307,19 @@ instance.web.JsonRPC = instance.web.CallbackEnabled.extend({ } else { // Indirect jsonp request var ifid = _.uniqueId('oe_rpc_iframe'); - var display = options.openerp.debug ? 'block' : 'none'; + var display = self.debug ? 'block' : 'none'; var $iframe = $(_.str.sprintf("<iframe src='javascript:false;' name='%s' id='%s' style='display:%s'></iframe>", ifid, ifid, display)); var $form = $('<form>') .attr('method', 'POST') .attr('target', ifid) .attr('enctype', "multipart/form-data") - .attr('action', ajax.url + '?' + $.param(data)) + .attr('action', ajax.url + '?jsonp=1&' + $.param(data)) .append($('<input type="hidden" name="r" />').attr('value', payload_str)) .hide() .appendTo($('body')); var cleanUp = function() { if ($iframe) { - $iframe.unbind("load").attr("src", "javascript:false;").remove(); + $iframe.unbind("load").remove(); } $form.remove(); }; diff --git a/addons/web/static/src/js/coresetup.js b/addons/web/static/src/js/coresetup.js index 99e134e7bd4..a00ca4002e5 100644 --- a/addons/web/static/src/js/coresetup.js +++ b/addons/web/static/src/js/coresetup.js @@ -334,11 +334,14 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess .appendTo(document.body) .load(function () { try { - if (options.error) { - options.error(JSON.parse( - this.contentDocument.body.childNodes[1].textContent - )); - } + if (options.error) { + if (!this.contentDocument.body.childNodes[1]) { + options.error(this.contentDocument.body.childNodes); + } + else { + options.error(JSON.parse(this.contentDocument.body.childNodes[1].textContent)); + } + } } finally { complete(); } @@ -595,7 +598,7 @@ instance.web.qweb.preprocess_node = function() { break; case 1: // Element - var attr, attrs = ['label', 'title', 'alt']; + var attr, attrs = ['label', 'title', 'alt', 'placeholder']; while (attr = attrs.pop()) { if (this.attributes[attr]) { this.attributes[attr] = instance.web._t(this.attributes[attr]); @@ -605,15 +608,31 @@ instance.web.qweb.preprocess_node = function() { }; /** Setup jQuery timeago */ -var timeago_setup = function () { - var s = $.timeago.settings.strings; - _.each(s, function(v,k) { - if(_.isString(v)) { - s[k] = instance.web._t(v); - } - }); +var _t = instance.web._t; +/* + * Strings in timeago are "composed" with prefixes, words and suffixes. This + * makes their detection by our translating system impossible. Use all literal + * strings we're using with a translation mark here so the extractor can do its + * job. + */ +{ + _t('less than a minute ago'); + _t('about a minute ago'); + _t('%d minutes ago'); + _t('about an hour ago'); + _t('%d hours ago'); + _t('a day ago'); + _t('%d days ago'); + _t('about a month ago'); + _t('%d months ago'); + _t('about a year ago'); + _t('%d years ago'); } -instance.connection.on('module_loaded', this, timeago_setup); + +instance.connection.on('module_loaded', this, function () { + // provide timeago.js with our own translator method + $.timeago.settings.translator = instance.web._t; +}); /** * Registry for all the client actions key: tag value: widget diff --git a/addons/web/static/src/js/data_import.js b/addons/web/static/src/js/data_import.js index bc98d8a1c10..6059f292df9 100644 --- a/addons/web/static/src/js/data_import.js +++ b/addons/web/static/src/js/data_import.js @@ -68,7 +68,7 @@ instance.web.DataImport = instance.web.Dialog.extend({ this.open({ buttons: [ {text: _t("Close"), click: function() { self.destroy(); }}, - {text: _t("Import File"), click: function() { self.do_import(); }, 'class': 'oe-dialog-import-button'} + {text: _t("Import File"), click: function() { self.do_import(); }, 'class': 'oe_import_dialog_button'} ], close: function(event, ui) { self.destroy(); @@ -78,7 +78,7 @@ instance.web.DataImport = instance.web.Dialog.extend({ this.$element.find('#csvfile').change(this.on_autodetect_data); this.$element.find('fieldset').change(this.on_autodetect_data); this.$element.delegate('fieldset legend', 'click', function() { - $(this).parent().toggleClass('oe-closed'); + $(this).parent().toggleClass('oe_closed'); }); this.ready.push(new instance.web.DataSet(this, this.model).call( 'fields_get', [], function (fields) { @@ -157,7 +157,7 @@ instance.web.DataImport = instance.web.Dialog.extend({ }, toggle_import_button: function (newstate) { instance.web.dialog(this.$element, 'widget') - .find('.oe-dialog-import-button') + .find('.oe_import_dialog_button') .button('option', 'disabled', !newstate); }, do_import: function() { @@ -202,7 +202,7 @@ instance.web.DataImport = instance.web.Dialog.extend({ if (results['error']) { result_node.append(QWeb.render('ImportView.error', { 'error': results['error']})); - this.$element.find('fieldset').removeClass('oe-closed'); + this.$element.find('fieldset').removeClass('oe_closed'); return; } if (results['success']) { @@ -224,11 +224,11 @@ instance.web.DataImport = instance.web.Dialog.extend({ : with_headers ? results.records.slice(1) : results.records })); - this.$element.find('fieldset').addClass('oe-closed'); + this.$element.find('fieldset').addClass('oe_closed'); } - this.$element.find('form').removeClass('oe-import-no-result'); + this.$element.find('form').removeClass('oe_import_no_result'); - this.$element.delegate('.oe-m2o-drop-down-button', 'click', function () { + this.$element.delegate('.oe_m2o_drop_down_button', 'click', function () { $(this).prev('input').focus(); }); diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js index e0ee3359091..6ceb7090e44 100644 --- a/addons/web/static/src/js/formats.js +++ b/addons/web/static/src/js/formats.js @@ -309,7 +309,7 @@ instance.web.format_cell = function (row_data, column, options) { '</button>', { title: column.string || '', additional_attributes: isNaN(row_data["id"].value) && instance.web.BufferedDataSet.virtual_id_regex.test(row_data["id"].value) ? - 'disabled="disabled" class="oe-listview-button-disabled"' : '', + 'disabled="disabled" class="oe_list_button_disabled"' : '', prefix: instance.connection.prefix, icon: column.icon, alt: column.string || '' diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index 85521a14651..c8b6f797dba 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -352,6 +352,11 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea e.stopImmediatePropagation(); self.$element.toggleClass('oe_searchview_open_drawer'); }); + instance.web.bus.on('click', this, function(ev) { + if ($(ev.target).parents('.oe_searchview').length === 0) { + self.$element.removeClass('oe_searchview_open_drawer'); + } + }); // Focus last input if the view itself is clicked (empty section of // facets element) this.$element.on('click', function (e) { @@ -640,6 +645,8 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea var drawer_started = $.when.apply( null, _(this.select_for_drawer()).invoke( 'appendTo', this.$element.find('.oe_searchview_drawer'))); + + new instance.web.search.AddToDashboard(this).appendTo($('.oe_searchview_drawer', this.$element)); // load defaults var defaults_fetched = $.when.apply(null, _(this.inputs).invoke( @@ -692,53 +699,6 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea select.val(''); } }, - on_add_to_dashboard: function() { - this.$element.find(".oe_search-view-filters-management")[0].selectedIndex = 0; - var self = this, - menu = instance.webclient.menu, - $dialog = $(QWeb.render("SearchView.add_to_dashboard", { - dashboards : menu.data.data.children, - selected_menu_id : menu.$element.find('a.active').data('menu') - })); - $dialog.find('input').val(this.fields_view.name); - instance.web.dialog($dialog, { - modal: true, - title: _t("Add to Dashboard"), - buttons: [ - {text: _t("Cancel"), click: function() { - $(this).dialog("close"); - }}, - {text: _t("OK"), click: function() { - $(this).dialog("close"); - var menu_id = $(this).find("select").val(), - title = $(this).find("input").val(), - data = self.build_search_data(), - context = new instance.web.CompoundContext(), - domain = new instance.web.CompoundDomain(); - _.each(data.contexts, function(x) { - context.add(x); - }); - _.each(data.domains, function(x) { - domain.add(x); - }); - self.rpc('/web/searchview/add_to_dashboard', { - menu_id: menu_id, - action_id: self.getParent().action.id, - context_to_save: context, - domain: domain, - view_mode: self.getParent().active_view, - name: title - }, function(r) { - if (r === false) { - self.do_warn("Could not add filter to dashboard"); - } else { - self.do_notify("Filter added to dashboard", ''); - } - }); - }} - ] - }); - }, /** * Extract search data from the view's facets. * @@ -1234,7 +1194,7 @@ instance.web.search.Field = instance.web.search.Input.extend( /** @lends instanc var self = this; // A field needs a context to send when active var context = this.attrs.context; - if (!context || !facet.values.length) { + if (_.isEmpty(context) || !facet.values.length) { return; } var contexts = facet.values.map(function (facetValue) { @@ -1530,6 +1490,15 @@ instance.web.search.ManyToOneField = instance.web.search.CharField.extend({ return [[name, '=', facetValue.get('value')]]; } return this._super(name, operator, facetValue); + }, + get_context: function (facet) { + var values = facet.values; + if (_.isEmpty(this.attrs.context) && values.length === 1) { + var c = {}; + c['default_' + this.attrs.name] = values.at(0).get('value'); + return c; + } + return this._super(facet); } }); @@ -1540,6 +1509,14 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({ var self = this; this.model = new instance.web.Model('ir.filters'); this.filters = {}; + this.view.query + .on('remove', function (facet) { + if (!facet.get('is_custom_filter')) { + return; + } + self.clear_selection(); + }) + .on('reset', this.proxy('clear_selection')); this.$element.on('submit', 'form', this.proxy('save_current')); this.$element.on('click', 'h4', function () { self.$element.toggleClass('oe_opened'); @@ -1549,6 +1526,9 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({ model: this.view.model }).pipe(this.proxy('set_filters')); }, + clear_selection: function () { + this.$element.find('li.oe_selected').removeClass('oe_selected'); + }, append_filter: function (filter) { var self = this; var key = _.str.sprintf('(%s)%s', filter.user_id, filter.name); @@ -1583,8 +1563,10 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({ get_groupby: function () { return [filter.context]; }, get_domain: function () { return filter.domain; } }, + is_custom_filter: true, values: [{label: filter.name, value: null}] }]); + $filter.addClass('oe_selected'); }); }, set_filters: function (filters) { @@ -1671,6 +1653,77 @@ instance.web.search.Filters = instance.web.search.Input.extend({ })); } }); +instance.web.search.AddToDashboard = instance.web.Widget.extend({ + template: 'SearchView.addtodashboard', + _in_drawer: true, + start: function () { + var self = this; + this.data_loaded = $.Deferred(); + this.dashboard_data =[]; + this.$element + .on('click', 'h4', this.proxy('show_option')) + .on('submit', 'form', function (e) { + e.preventDefault(); + self.add_dashboard(); + }); + return $.when(this.load_data(),this.data_loaded).pipe(this.proxy("render_data")); + }, + load_data:function(){ + var self = this,dashboard_menu = instance.webclient.menu.data.data.children; + var ir_model_data = new instance.web.Model('ir.model.data',{},[['name','=','menu_reporting_dashboard']]).query(['res_id']); + var map_data = function(result){ + _.detect(dashboard_menu, function(dash){ + var id = _.pluck(dash.children, "id"),indexof = _.indexOf(id, result.res_id); + if(indexof !== -1){ + self.dashboard_data = dash.children[indexof].children + self.data_loaded.resolve(); + return; + } + }); + }; + return ir_model_data._execute().done(function(result){map_data(result[0])}); + }, + + render_data: function(){ + var self = this; + var selection = instance.web.qweb.render("SearchView.addtodashboard.selection",{selections:this.dashboard_data}); + this.$element.find("input").before(selection) + }, + add_dashboard:function(){ + var self = this; + var getParent = this.getParent(); + var view_parent = this.getParent().getParent(); + if (! view_parent.action || ! this.$element.find("select").val()) + return this.do_warn("Can't find dashboard action"); + data = getParent.build_search_data(), + context = new instance.web.CompoundContext(getParent.dataset.get_context() || []), + domain = new instance.web.CompoundDomain(getParent.dataset.get_domain() || []); + _.each(data.contexts, function(x) {context.add(x);}); + _.each(data.domains, function(x) {domain.add(x);}); + this.rpc('/web/searchview/add_to_dashboard', { + menu_id: this.$element.find("select").val(), + action_id: view_parent.action.id, + context_to_save: context, + domain: domain, + view_mode: view_parent.active_view, + name: this.$element.find("input").val() + }, function(r) { + if (r === false) { + self.do_warn("Could not add filter to dashboard"); + } else { + self.$element.toggleClass('oe_opened'); + self.do_notify("Filter added to dashboard", ''); + } + }); + }, + show_option:function(){ + this.$element.toggleClass('oe_opened'); + if (! this.$element.hasClass('oe_opened')) + return; + this.$element.find("input").val(this.getParent().fields_view.name || "" ); + } +}); + instance.web.search.Advanced = instance.web.search.Input.extend({ template: 'SearchView.advanced', _in_drawer: true, diff --git a/addons/web/static/src/js/view_editor.js b/addons/web/static/src/js/view_editor.js index 9fdd4f0bca1..8733a191b21 100644 --- a/addons/web/static/src/js/view_editor.js +++ b/addons/web/static/src/js/view_editor.js @@ -515,21 +515,18 @@ instance.web.ViewEditor = instance.web.OldWidget.extend({ } }, do_node_add: function(side){ - var self = this; + var self = this,property_to_check = []; var tr = self.get_object_by_id(this.one_object.clicked_tr_id, this.one_object['main_object'], [])[0].att_list[0]; var parent_tr = ($(side).prevAll("tr[level=" + String(this.one_object.clicked_tr_level - 1) + "]"))[0]; var field_dataset = new instance.web.DataSetSearch(this, this.model, null, null); - parent_tr = $(parent_tr).find('a').text(); + parent_tr = self.get_object_by_id(parseInt($(parent_tr).attr('id').replace(/[^0-9]+/g, '')), this.one_object['main_object'], [])[0].att_list[0]; + _.each([tr, parent_tr],function(element) { + var value = _.has(_CHILDREN, element) ? element : _.str.include(html_tag, element)?"html_tag":false; + property_to_check.push(value); + }); field_dataset.call( 'fields_get', [], function(result) { var fields = _.keys(result); fields.push(" "),fields.sort(); - var property_to_check = []; - _.each([tr, parent_tr],function(element) { - property_to_check.push( - _.detect(_.keys(_CHILDREN),function(res){ - return _.str.include(element, res); - })); - }); self.on_add_node(property_to_check, fields); }); }, @@ -990,7 +987,7 @@ instance.web.ViewEditor = instance.web.OldWidget.extend({ render_new_field :function( result ) { var self = this; var action = { - context: {'default_model_id': result.id, 'manual': true, 'module' : result.modules}, + context: {'default_model_id': result.id, 'manual': true, 'module' : result.model}, res_model: "ir.model.fields", views: [[false, 'form']], type: 'ir.actions.act_window', @@ -1168,8 +1165,16 @@ var _CHILDREN = { 'label': [], 'button' : [], 'newline': [], - 'separator': [] + 'separator': [], + 'sheet' :['group','field','notebook','label','separator','div','page'], + 'kanban' : ['field'], + 'html_tag':['notebook', 'group', 'field', 'label', 'button','board', 'newline', 'separator'] +//e.g.:xyz 'td' : ['field'] }; +// Generic html_tag list and can be added html tag in future. It's support above _CHILDREN dict's *html_tag* by default. +// For specific child node one has to define tag above and specify children tag in list. Like above xyz example. +var html_tag = ['div','h1','h2','h3','h4','h5','h6','td','tr']; + var _ICONS = ['','STOCK_ABOUT', 'STOCK_ADD', 'STOCK_APPLY', 'STOCK_BOLD', 'STOCK_CANCEL', 'STOCK_CDROM', 'STOCK_CLEAR', 'STOCK_CLOSE', 'STOCK_COLOR_PICKER', 'STOCK_CONNECT', 'STOCK_CONVERT', 'STOCK_COPY', 'STOCK_CUT', 'STOCK_DELETE', diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index bb020f8db49..0211b934a4e 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -330,9 +330,6 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM if (self.sidebar) { self.sidebar.do_attachement_update(self.dataset, self.datarecord.id); } - if (self.default_focus_field) { - self.default_focus_field.focus(); - } if (record.id) { self.do_push_state({id:record.id}); } @@ -581,6 +578,16 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM _.each(this.fields,function(field){ field.set({"force_readonly": false}); }); + var fields_order = self.fields_order.slice(0); + if (self.default_focus_field) { + fields_order.unshift(self.default_focus_field); + } + for (var i = 0; i < fields_order.length; i += 1) { + var field = self.fields[fields_order[i]]; + if (!field.get('effective_invisible') && !field.get('effective_readonly') && field.focus() !== false) { + break; + } + } } }, on_button_save: function() { @@ -721,7 +728,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM .filter(function (f) { return !f.is_valid(); }) .map(function (f) { return _.str.sprintf('<li>%s</li>', - _.escape(f.node.attrs.string || f.field.string)); + _.escape(f.string)); }).value(); warnings.unshift('<ul>'); warnings.push('</ul>'); @@ -865,7 +872,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM return { name: name, - string: field.node.attrs.string || field.field.string, + string: field.string, value: value, displayed: displayed, // convert undefined to false @@ -914,6 +921,9 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM register_field: function(field, name) { this.fields[name] = field; this.fields_order.push(name); + if (field.node.attrs.default_focus == '1') { + this.default_focus_field = field; + } field.on('focused', null, this.proxy('widgetFocused')) .on('blurred', null, this.proxy('widgetBlurred')); @@ -1176,6 +1186,10 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt if (!$tr || row_cols < colspan) { $tr = $('<tr/>').addClass('oe_form_group_row').appendTo($table); row_cols = cols; + } else if (tagName==='group') { + // When <group> <group/><group/> </group>, we need a spacing between the two groups + $child.addClass('oe_group_right') + } row_cols -= colspan; @@ -1520,7 +1534,9 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi this._super.apply(this, arguments); }, /** - * Sets up blur/focus forwarding from DOM elements to a widget (`this`) + * Sets up blur/focus forwarding from DOM elements to a widget (`this`). + * + * This method is an utility method that is meant to be called by child classes. * * @param {jQuery} $e jQuery object of elements to bind focus/blur on */ @@ -1770,7 +1786,7 @@ instance.web.form.FieldInterface = { */ is_syntax_valid: function() {}, /** - * Must set the focus on the field. + * Must set the focus on the field. Return false if field is not focusable. */ focus: function() {}, }; @@ -1799,8 +1815,10 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w this._super(field_manager, node); this.field_manager = field_manager; this.name = this.node.attrs.name; - this.set({'value': false}); this.field = this.field_manager.get_field(this.name); + this.widget = this.node.attrs.widget; + this.string = this.node.attrs.string || this.field.string || this.name; + this.set({'value': false}); this.set({required: this.modifiers['required'] === true}); // some events to make the property "effective_readonly" sync automatically with "readonly" and @@ -1872,7 +1890,7 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w is_false: function() { return this.get('value') === false; }, - _check_css_flags: function(show_invalid) { + _check_css_flags: function() { if (this.field.translate) { this.$element.find('.oe_field_translate').toggle(!this.field_manager.is_create_mode()); } @@ -2011,7 +2029,7 @@ instance.web.form.FieldEmail = instance.web.form.FieldChar.extend({ } else { this.$element.find('a') .attr('href', 'mailto:' + this.get('value')) - .text(this.get('value')); + .text(this.get('value') || ''); } }, on_button_clicked: function() { @@ -2040,7 +2058,7 @@ instance.web.form.FieldUrl = instance.web.form.FieldChar.extend({ if (!s) { tmp = "http://" + this.get('value'); } - this.$element.find('a').attr('href', tmp).text(tmp); + this.$element.find('a').attr('href', tmp).text(this.get('value') ? tmp : ''); } }, on_button_clicked: function() { @@ -2455,15 +2473,16 @@ instance.web.form.CompletionFieldMixin = { return this.orderer.add(dataset.name_search( search_val, new instance.web.CompoundDomain(self.build_domain(), [["id", "not in", blacklist]]), - 'ilike', this.limit + 1)).pipe(function(data) { + 'ilike', this.limit + 1, self.build_context())).pipe(function(data) { self.last_search = data; // possible selections for the m2o var values = _.map(data, function(x) { + x[1] = x[1].split("\n")[0]; return { label: _.str.escapeHTML(x[1]), - value:x[1], - name:x[1], - id:x[0] + value: x[1], + name: x[1], + id: x[0], }; }); @@ -2519,7 +2538,7 @@ instance.web.form.CompletionFieldMixin = { pop.select_element( self.field.relation, { - title: (view === 'search' ? _t("Search: ") : _t("Create: ")) + (this.string || this.name), + title: (view === 'search' ? _t("Search: ") : _t("Create: ")) + this.string, initial_ids: ids ? _.map(ids, function(x) {return x[0]}) : undefined, initial_view: view, disable_multiple_selection: true @@ -2548,6 +2567,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc this.last_search = []; this.floating = false; this.inhibit_on_change = false; + this.current_display = null; }, start: function() { this._super(); @@ -2574,8 +2594,8 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc fade: true, }); - this.$drop_down = this.$element.find(".oe-m2o-drop-down-button"); - this.$follow_button = $(".oe-m2o-cm-button", this.$element); + this.$drop_down = this.$element.find(".oe_m2o_drop_down_button"); + this.$follow_button = $(".oe_m2o_cm_button", this.$element); this.$follow_button.click(function() { if (!self.get('value')) { @@ -2588,7 +2608,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc self.get("value"), self.build_context(), { - title: _t("Open: ") + (self.string || self.name) + title: _t("Open: ") + self.string } ); pop.on_write_completed.add_last(function() { @@ -2599,11 +2619,15 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc }); // some behavior for input - this.$input.keyup(function() { - if (self.$input.val() === "") { - self.set({value: false}); - } else { - self.floating = true; + this.$input.keydown(function() { + if (self.current_display !== self.$input.val()) { + self.current_display = self.$input.val(); + if (self.$input.val() === "") { + self.set({value: false}); + self.floating = false; + } else { + self.floating = true; + } } }); this.$drop_down.click(function() { @@ -2641,7 +2665,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc } self.floating = false; } - if (used) { + if (used && self.get("value") === false) { tip_def.reject(); untip_def.reject(); tip_def = $.Deferred(); @@ -2696,7 +2720,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc this.$input.autocomplete("widget").addClass("openerp"); // used to correct a bug when selecting an element by pushing 'enter' in an editable list this.$input.keyup(function(e) { - if (e.which === 13) { + if (e.which === 13) { // ENTER if (isSelecting) e.stopPropagation(); } @@ -2717,7 +2741,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc return; } if (! no_recurse) { - var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.view.dataset.get_context()); + var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.build_context()); dataset.name_get([self.get("value")], function(data) { self.display_value["" + self.get("value")] = data[0][1]; self.render_value(true); @@ -2727,11 +2751,13 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc display_string: function(str) { var self = this; if (!this.get("effective_readonly")) { - this.$input.val(str); + this.$input.val(str.split("\n")[0]); + this.current_display = this.$input.val(); } else { + str = _.escape(str).split("\n").join("<br />"); this.$element.find('a') .unbind('click') - .text(str) + .html(str) .click(function () { self.do_action({ type: 'ir.actions.act_window', @@ -2749,7 +2775,9 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc var self = this; if (value_ instanceof Array) { this.display_value = {}; - this.display_value["" + value_[0]] = value_[1]; + if (! this.get_definition_options().always_reload) { + this.display_value["" + value_[0]] = value_[1]; + } value_ = value_[0]; } value_ = value_ || false; @@ -2883,25 +2911,36 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({ view.embedded_view = self.field.views[mode]; } if(view.view_type === "list") { - view.options.selectable = self.multi_selection; - view.options.sortable = false; + _.extend(view.options, { + selectable: self.multi_selection, + sortable: false, + import_enabled: false, + }); if (self.get("effective_readonly")) { - view.options.addable = null; - view.options.deletable = null; - view.options.reorderable = false; + _.extend(view.options, { + addable: null, + deletable: null, + reorderable: false, + }); } } else if (view.view_type === "form") { if (self.get("effective_readonly")) { view.view_type = 'form'; } - view.options.not_interactible_on_create = true; + _.extend(view.options, { + not_interactible_on_create: true, + }); } else if (view.view_type === "kanban") { - view.options.confirm_on_delete = false; + _.extend(view.options, { + confirm_on_delete: false, + }); if (self.get("effective_readonly")) { - view.options.action_buttons = false; - view.options.quick_creatable = false; - view.options.creatable = false; - view.options.read_only_mode = true; + _.extend(view.options, { + action_buttons: false, + quick_creatable: false, + creatable: false, + read_only_mode: true, + }); } } views.push(view); @@ -3115,7 +3154,7 @@ instance.web.form.One2ManyViewManager = instance.web.ViewManager.extend({ var id = self.o2m.dataset.index !== null ? self.o2m.dataset.ids[self.o2m.dataset.index] : null; var pop = new instance.web.form.FormOpenPopup(self.o2m.view); pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(), { - title: _t("Open: ") + self.name, + title: _t("Open: ") + self.o2m.string, create_function: function(data) { return self.o2m.dataset.create(data).then(function(r) { self.o2m.dataset.set_ids(self.o2m.dataset.ids.concat([r.result])); @@ -3193,7 +3232,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ pop.select_element( self.o2m.field.relation, { - title: _t("Create: ") + self.name, + title: _t("Create: ") + self.o2m.string, initial_view: "form", alternative_form_view: self.o2m.field.views ? self.o2m.field.views["form"] : undefined, create_function: function(data, callback, error_callback) { @@ -3221,7 +3260,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ var self = this; var pop = new instance.web.form.FormOpenPopup(self.o2m.view); pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(), { - title: _t("Open: ") + self.name, + title: _t("Open: ") + self.o2m.string, write_function: function(id, data) { return self.o2m.dataset.write(id, data, {}, function(r) { self.o2m.reload_current_view(); @@ -3495,6 +3534,7 @@ instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({ 'selectable': self.multi_selection, 'sortable': false, 'reorderable': false, + 'import_enabled': false, }); var embedded = (this.field.views || {}).tree; if (embedded) { @@ -3539,7 +3579,7 @@ instance.web.form.Many2ManyListView = instance.web.ListView.extend(/** @lends in pop.select_element( this.model, { - title: _t("Add: ") + this.name + title: _t("Add: ") + this.m2m_field.string }, new instance.web.CompoundDomain(this.m2m_field.build_domain(), ["!", ["id", "in", this.m2m_field.dataset.ids]]), this.m2m_field.build_context() @@ -3559,7 +3599,7 @@ instance.web.form.Many2ManyListView = instance.web.ListView.extend(/** @lends in var self = this; var pop = new instance.web.form.FormOpenPopup(this); pop.show_element(this.dataset.model, id, this.m2m_field.build_context(), { - title: _t("Open: ") + this.name, + title: _t("Open: ") + this.m2m_field.string, readonly: this.getParent().get("effective_readonly") }); pop.on_write_completed.add_last(function() { @@ -3657,7 +3697,7 @@ instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend( pop.select_element( this.field.relation, { - title: _t("Add: ") + this.name + title: _t("Add: ") + this.string }, new instance.web.CompoundDomain(this.build_domain(), ["!", ["id", "in", this.dataset.ids]]), this.build_context() @@ -3675,7 +3715,7 @@ instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend( var id = self.dataset.ids[self.dataset.index]; var pop = new instance.web.form.FormOpenPopup(self.view); pop.show_element(self.field.relation, id, self.build_context(), { - title: _t("Open: ") + self.name, + title: _t("Open: ") + self.string, write_function: function(id, data, options) { return self.dataset.write(id, data, {}).then(function() { self.reload_content(); @@ -3846,7 +3886,7 @@ instance.web.form.AbstractFormPopup = instance.web.OldWidget.extend({ if (this.options.alternative_form_view) { this.view_form.set_embedded_view(this.options.alternative_form_view); } - this.view_form.appendTo(this.$element.find(".oe-form-view-popup-form-placeholder")); + this.view_form.appendTo(this.$element.find(".oe_popup_form")); this.view_form.on_loaded.add_last(function() { var $buttons = self.view_form.$element.find(".oe_form_buttons"); var multi_select = self.row_id === null && ! self.options.disable_multiple_selection; @@ -3975,9 +4015,10 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend _.extend({'deletable': false, 'selectable': !self.options.disable_multiple_selection, 'read_only': true, + 'import_enabled': false, }, self.options.list_view_options || {})); self.view_list.popup = self; - self.view_list.appendTo($(".oe-select-create-popup-view-list", self.$element)).pipe(function() { + self.view_list.appendTo($(".oe_popup_list", self.$element)).pipe(function() { self.view_list.do_show(); }).pipe(function() { self.searchview.do_search(); @@ -3999,7 +4040,7 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend }); }); }); - this.searchview.appendTo($(".oe-select-create-popup-view-list", self.$element)); + this.searchview.appendTo($(".oe_popup_list", self.$element)); }, do_search: function(domains, contexts, groupbys) { var self = this; @@ -4161,9 +4202,9 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance. this._super.apply(this, arguments); }, initialize_content: function() { - this.$element.find('input.oe-binary-file').change(this.on_file_change); - this.$element.find('button.oe_binary_file_save').click(this.on_save_as); - this.$element.find('.oe-binary-file-clear').click(this.on_clear); + this.$element.find('input.oe_form_binary_file').change(this.on_file_change); + this.$element.find('button.oe_form_binary_file_save').click(this.on_save_as); + this.$element.find('.oe_form_binary_file_clear').click(this.on_clear); }, human_filesize : function(size) { var units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; @@ -4180,10 +4221,10 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance. // http://deepliquid.com/projects/Jcrop/demos.php?demo=handler if ($(e.target).val() !== '') { - this.$element.find('form.oe-binary-form input[name=session_id]').val(this.session.session_id); - this.$element.find('form.oe-binary-form').submit(); - this.$element.find('.oe-binary-progress').show(); - this.$element.find('.oe-binary').hide(); + this.$element.find('form.oe_form_binary_form input[name=session_id]').val(this.session.session_id); + this.$element.find('form.oe_form_binary_form').submit(); + this.$element.find('.oe_form_binary_progress').show(); + this.$element.find('.oe_form_binary').hide(); } }, on_file_uploaded: function(size, name, content_type, file_base64) { @@ -4195,8 +4236,8 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance. this.filename = name; this.on_file_uploaded_and_valid.apply(this, arguments); } - this.$element.find('.oe-binary-progress').hide(); - this.$element.find('.oe-binary').show(); + this.$element.find('.oe_form_binary_progress').hide(); + this.$element.find('.oe_form_binary').show(); }, on_file_uploaded_and_valid: function(size, name, content_type, file_base64) { }, @@ -4206,7 +4247,7 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance. this.do_warn(_t("Save As..."), _t("The field is empty, there's nothing to save !")); ev.stopPropagation(); } else if (this._dirty_flag) { - var link = this.$('.oe_binary_file_save_data')[0]; + var link = this.$('.oe_form_binary_file_save_data')[0]; link.download = this.filename || "download.bin"; // Works on only on Google Chrome //link.target = '_blank'; link.href = "data:application/octet-stream;base64," + value; @@ -4335,10 +4376,13 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({ }); instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ - tagName: "span", + template: "FieldStatus", start: function() { this._super(); this.selected_value = null; + if (this.$element.parent().is('header')) { + this.$element.after('<div class="oe_clear"/>'); + } // preview in start only for selection fields, because of the dynamic behavior of many2one fields. if (this.field.type in ['selection']) { this.render_list(); @@ -4450,6 +4494,9 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ elem.css("color", color); } }, + focus: function() { + return false; + }, }); /** diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index 92b633bf54d..4d2d1b4245f 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -24,6 +24,8 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi // if true, the view can't be editable, ignoring the view's and the context's // instructions 'read_only': false, + // if true, the 'Import', 'Export', etc... buttons will be shown + 'import_enabled': true, }, /** * Core class for list-type displays. @@ -140,13 +142,13 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi }); }, /** - * View startup method, the default behavior is to set the ``oe-listview`` + * View startup method, the default behavior is to set the ``oe_list`` * class on its root element and to perform an RPC load call. * * @returns {$.Deferred} loading promise */ start: function() { - this.$element.addClass('oe-listview').css('position: relative'); + this.$element.addClass('oe_list'); return this.reload_view(null, null, true); }, /** @@ -250,18 +252,19 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi this.setup_columns(this.fields_view.fields, grouped); this.$element.html(QWeb.render(this._template, this)); + this.$element.addClass(this.fields_view.arch.attrs['class']); // Head hook // Selecting records - this.$element.find('.all-record-selector').click(function(){ - self.$element.find('.oe-record-selector input').prop('checked', - self.$element.find('.all-record-selector').prop('checked') || false); + this.$element.find('.oe_list_record_selector').click(function(){ + self.$element.find('.oe_list_record_selector input').prop('checked', + self.$element.find('.oe_list_record_selector').prop('checked') || false); var selection = self.groups.get_selection(); $(self.groups).trigger( 'selected', [selection.ids, selection.records]); }); // Sorting columns - this.$element.find('thead').delegate('th.oe-sortable[data-id]', 'click', function (e) { + this.$element.find('thead').delegate('th.oe_sortable[data-id]', 'click', function (e) { e.stopPropagation(); var $this = $(this); self.dataset.sort($this.data('id')); @@ -270,7 +273,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi } else { $this.toggleClass("sortdown"); } - $this.siblings('.oe-sortable').removeClass("sortup sortdown"); + $this.siblings('.oe_sortable').removeClass("sortup sortdown"); self.reload_content(); }); @@ -322,7 +325,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi self.page = 0; } self.reload_content(); - }).find('.oe-pager-state') + }).find('.oe_list_pager_state') .click(function (e) { e.stopPropagation(); var $this = $(this); @@ -340,6 +343,8 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi self._limit = (isNaN(val) ? null : val); self.page = 0; self.reload_content(); + }).blur(function() { + $(this).trigger('change'); }) .val(self._limit || 'NaN'); }); @@ -372,18 +377,19 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi } var total = dataset.size(); - this.$pager.toggleClass('oe_list_pager_single_page', (total <= this.limit())); + var limit = this.limit() || total; + this.$pager.toggleClass('oe_list_pager_single_page', (total <= limit)); var spager = '-'; if (total) { - var range_start = this.page * this.limit() + 1; - var range_stop = range_start - 1 + this.limit(); + var range_start = this.page * limit + 1; + var range_stop = range_start - 1 + limit; if (range_stop > total) { range_stop = total; } spager = _.str.sprintf('%d-%d of %d', range_start, range_stop, total); } - this.$pager.find('.oe-pager-state').text(spager); + this.$pager.find('.oe_list_pager_state').text(spager); }, /** * Sets up the listview's columns: merges view and fields data, move @@ -542,10 +548,10 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi */ reload_content: function () { var self = this; - self.$element.find('.all-record-selector').prop('checked', false); + self.$element.find('.oe_list_record_selector').prop('checked', false); this.records.reset(); var reloaded = $.Deferred(); - this.$element.find('.oe-listview-content').append( + this.$element.find('.oe_list_content').append( this.groups.render(function () { if (self.dataset.index == null) { var has_one = false; @@ -810,7 +816,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi }, display_aggregates: function (aggregation) { var self = this; - var $footer_cells = this.$element.find('.oe-list-footer'); + var $footer_cells = this.$element.find('.oe_list_footer'); _(this.aggregate_columns).each(function (column) { if (!column['function']) { return; @@ -848,9 +854,9 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi } // Padding for column titles, footer and data rows var $rows = this.$element - .find('.oe-listview-header-columns, tr:not(thead tr)') + .find('.oe_list_header_columns, tr:not(thead tr)') .not(options['except']); - var newcols = new Array(count+1).join('<td class="oe-listview-padding"></td>'); + var newcols = new Array(count+1).join('<td class="oe_list_padding"></td>'); if (options.position === 'before') { $rows.prepend(newcols); } else { @@ -861,7 +867,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi * Removes all padding columns of the table */ unpad_columns: function () { - this.$element.find('.oe-listview-padding').remove(); + this.$element.find('.oe_list_padding').remove(); if (this.previous_colspan) { this.$element .find('thead tr:first th') @@ -976,18 +982,18 @@ instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web. this.$_element = $('<tbody>') .appendTo(document.body) - .delegate('th.oe-record-selector', 'click', function (e) { + .delegate('th.oe_list_record_selector', 'click', function (e) { e.stopPropagation(); var selection = self.get_selection(); $(self).trigger( 'selected', [selection.ids, selection.records]); }) - .delegate('td.oe-record-delete button', 'click', function (e) { + .delegate('td.oe_list_record_delete button', 'click', function (e) { e.stopPropagation(); var $row = $(e.target).closest('tr'); $(self).trigger('deleted', [[self.row_id($row)]]); }) - .delegate('td.oe-field-cell button', 'click', function (e) { + .delegate('td.oe_list_field_cell button', 'click', function (e) { e.stopPropagation(); var $target = $(e.currentTarget), field = $target.closest('td').data('field'), @@ -1085,20 +1091,20 @@ instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web. } var cells = []; if (this.options.selectable) { - cells.push('<th class="oe-record-selector"></td>'); + cells.push('<th class="oe_list_record_selector"></td>'); } _(this.columns).each(function(column) { if (column.invisible === '1') { return; } if (column.tag === 'button') { - cells.push('<td class="oe-button" title="' + column.string + '"> </td>'); + cells.push('<td class="oe_button" title="' + column.string + '"> </td>'); } else { cells.push('<td title="' + column.string + '"> </td>'); } }); if (this.options.deletable) { - cells.push('<td class="oe-record-delete"><button type="button" style="visibility: hidden"> </button></td>'); + cells.push('<td class="oe_list_record_delete"><button type="button" style="visibility: hidden"> </button></td>'); } cells.unshift('<tr>'); cells.push('</tr>'); @@ -1119,7 +1125,7 @@ instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web. return result; } var records = this.records; - this.$current.find('th.oe-record-selector input:checked') + this.$current.find('th.oe_list_record_selector input:checked') .closest('tr').each(function () { var record = records.get($(this).data('id')); result.ids.push(record.get('id')); @@ -1287,7 +1293,7 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we }); this.$row.children().last() .append($prev) - .append('<span class="oe-pager-state"></span>') + .append('<span class="oe_list_pager_state"></span>') .append($next); }, open: function (point_insertion) { @@ -1353,13 +1359,18 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we } placeholder.appendChild($row[0]); - var $group_column = $('<th class="oe-group-name">').appendTo($row); + var $group_column = $('<th class="oe_list_group_name">').appendTo($row); // Don't fill this if group_by_no_leaf but no group_by if (group.grouped_on) { var row_data = {}; row_data[group.grouped_on] = group; var group_column = _(self.columns).detect(function (column) { return column.id === group.grouped_on; }); + if (! group_column) { + throw new Error(_.str.sprintf( + _t("Grouping on field '%s' is not possible because that field does not appear in the list view."), + group.grouped_on)); + } try { $group_column.html(instance.web.format_cell( row_data, group_column, { @@ -1403,7 +1414,7 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we } }); if (self.options.deletable) { - $row.append('<td class="oe-group-pagination">'); + $row.append('<td class="oe_list_group_pagination">'); } }); return placeholder; @@ -1454,11 +1465,11 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we } else { if (dataset.size() == records.length) { // only one page - self.$row.find('td.oe-group-pagination').empty(); + self.$row.find('td.oe_list_group_pagination').empty(); } else { var pages = Math.ceil(dataset.size() / limit); self.$row - .find('.oe-pager-state') + .find('.oe_list_pager_state') .text(_.str.sprintf(_t("%(page)d/%(page_count)d"), { page: page + 1, page_count: pages diff --git a/addons/web/static/src/js/view_tree.js b/addons/web/static/src/js/view_tree.js index 9e938fe293a..e8bd7351f1f 100644 --- a/addons/web/static/src/js/view_tree.js +++ b/addons/web/static/src/js/view_tree.js @@ -84,6 +84,7 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie 'fields': this.fields, 'toolbar': has_toolbar })); + this.$element.addClass(this.fields_view.arch.attrs['class']); this.dataset.read_slice(this.fields_list()).then(function(records) { if (!has_toolbar) { @@ -179,7 +180,7 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie } }); if (is_loaded === 0) { - if (!$this.parent().hasClass('oe-open')) { + if (!$this.parent().hasClass('oe_open')) { self.getdata(record_id, children_ids); } } else { @@ -208,7 +209,7 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie }); if ($curr_node.length) { - $curr_node.addClass('oe-open'); + $curr_node.addClass('oe_open'); $curr_node.after(children_rows); } else { self.$element.find('tbody').html(children_rows); @@ -247,11 +248,11 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie // show & hide the contents showcontent: function (record_id, show) { this.$element.find('#treerow_' + record_id) - .toggleClass('oe-open', show); + .toggleClass('oe_open', show); _(this.records[record_id][this.children_field]).each(function (child_id) { var $child_row = this.$element.find('#treerow_' + child_id); - if ($child_row.hasClass('oe-open')) { + if ($child_row.hasClass('oe_open')) { this.showcontent(child_id, false); } $child_row.toggle(show); diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 35901e90165..cd2ccb72c49 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -136,7 +136,7 @@ instance.web.ActionManager = instance.web.Widget.extend({ }; } if (action.target === 'new') { - if (this.dialog == null) { + if (this.dialog === null) { this.dialog = new instance.web.Dialog(this, { width: '80%' }); if(on_close) this.dialog.on_close.add(on_close); @@ -144,8 +144,9 @@ instance.web.ActionManager = instance.web.Widget.extend({ this.dialog_viewmanager.destroy(); } this.dialog.dialog_title = action.name; - this.dialog_viewmanager = new instance.web.ViewManagerAction(this, action); + this.dialog_viewmanager = new instance.web.ViewManagerAction(this.dialog, action); this.dialog_viewmanager.appendTo(this.dialog.$element); + this.dialog_viewmanager.$element.addClass("oe_view_manager_" + (action.target || 'current')); this.dialog.open(); } else { this.dialog_stop(); @@ -158,7 +159,7 @@ instance.web.ActionManager = instance.web.Widget.extend({ this.inner_action = action; this.inner_viewmanager = new instance.web.ViewManagerAction(this, action); this.inner_viewmanager.appendTo(this.$element); - this.inner_viewmanager.$element.addClass("oe_view_manager_global"); + this.inner_viewmanager.$element.addClass("oe_view_manager_" + (action.target || 'current')); } }, ir_actions_act_window_close: function (action, on_closed) { @@ -862,13 +863,13 @@ instance.web.Sidebar = instance.web.Widget.extend({ }); self.items['files'] = attachments; self.redraw(); - this.$('.oe_sidebar_add_attachment .oe-binary-file').change(this.on_attachment_changed); + this.$('.oe_sidebar_add_attachment .oe_form_binary_file').change(this.on_attachment_changed); this.$element.find('.oe_sidebar_delete_item').click(this.on_attachment_delete); }, on_attachment_changed: function(e) { var $e = $(e.target); if ($e.val() !== '') { - this.$element.find('form.oe-binary-form').submit(); + this.$element.find('form.oe_form_binary_form').submit(); $e.parent().find('input[type=file]').prop('disabled', true); $e.parent().find('button').prop('disabled', true).find('img, span').toggle(); this.$('.oe_sidebar_add_attachment span').text(_t('Uploading...')); |
