diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index fdc7db1e2f2..81d8628c504 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -532,7 +532,7 @@ background-image: -webkit-radial-gradient(circle, #eee 0%, #ccc 40%, #bbb 100%); background-image: -moz-radial-gradient(#eee 0%, #ccc 40%, #bbb 100%); background-image: -ms-radial-gradient(#eee 0%, #ccc 40%, #bbb 100%); - background-image: radial-gradient(circle, #eee 0%, #ccc 40%, #bbb 100%); + background-image: radial-gradient(circle, #eeeeee 0%, #cccccc 40%, #bbbbbb 100%); } .openerp .oe_kanban_status_green { background: green; @@ -616,79 +616,6 @@ font-style: italic; text-decoration: none; } -.openerp .oe_notebook { - margin: 8px 0; - padding: 0 16px; - list-style: none; - zoom: 1; -} -.openerp .oe_notebook.ui-corner-all { - -moz-border-radius: 0; - -webkit-border-radius: 0; - border-radius: 0; -} -.openerp .oe_notebook:before, .openerp .oe_notebook:after { - display: table; - content: ""; - zoom: 1; -} -.openerp .oe_notebook:after { - clear: both; -} -.openerp .oe_notebook > li { - float: left; -} -.openerp .oe_notebook > li > a { - display: block; - color: #808080; -} -.openerp .oe_notebook > li.ui-tabs-active > a { - color: #4c4c4c; -} -.openerp .oe_notebook { - border-color: #ddd; - border-style: solid; - border-width: 0 0 1px; -} -.openerp .oe_notebook > li { - position: relative; -} -.openerp .oe_notebook > li > a { - padding: 0 12px; - margin-right: 2px; - line-height: 30px; - border: 1px solid transparent; - -moz-border-radius: 4px 4px 0 0; - -webkit-border-radius: 4px 4px 0 0; - border-radius: 4px 4px 0 0; -} -.openerp .oe_notebook > li > a:hover { - text-decoration: none; - background-color: #eee; - border-color: #eee #eee #ddd; -} -.openerp .ui-tabs .oe_notebook.ui-tabs-nav li.ui-tabs-active { - border-bottom: none; - padding-bottom: 1px; -} -.openerp .oe_notebook > li.ui-state-active > a, .openerp .oe_notebook > li.ui-state-active > a:hover { - background-color: #ffffff; - border: 1px solid #ddd; - border-bottom-color: transparent; - cursor: default; -} -.openerp .oe_notebook_page { - padding: 0; -} -.openerp .oe_notebook_page > label:not([for]) { - font-weight: normal !important; -} -.openerp div.ui-tabs { - padding: 3px 0px 3px 0px; -} -.openerp .ui-tabs-hide { - display: none; -} .openerp .oe_dropdown, .openerp .oe_dropdown_hover, .openerp .oe_dropdown_toggle { position: relative; cursor: pointer; diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index 632bc36c086..fc41de6f5e7 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -555,62 +555,6 @@ $sheet-padding: 16px text-decoration: none margin-bottom: 1px // }}} - // Notebook {{{ - .oe_notebook - margin: 8px 0 - padding: 0 16px - list-style: none - zoom: 1 - .oe_notebook.ui-corner-all - @include radius(0) - .oe_notebook:before, .oe_notebook:after - display: table - content: "" - zoom: 1 - .oe_notebook:after - clear: both - .oe_notebook > li - float: left - .oe_notebook > li > a - display: block - color: #808080 - .oe_notebook > li.ui-tabs-active > a - color: #4c4c4c - .oe_notebook - border-color: #ddd - border-style: solid - border-width: 0 0 1px - .oe_notebook > li - position: relative - .oe_notebook > li > a - padding: 0 12px - margin-right: 2px - line-height: 30px - border: 1px solid transparent - @include radius(4px 4px 0 0) - .oe_notebook > li > a:hover - text-decoration: none - background-color: #eee - border-color: #eee #eee #ddd - .ui-tabs .oe_notebook.ui-tabs-nav li.ui-tabs-active - border-bottom: none - padding-bottom: 1px - .oe_notebook > li.ui-state-active > a, .oe_notebook > li.ui-state-active > a:hover - background-color: #ffffff - border: 1px solid #ddd - border-bottom-color: transparent - cursor: default - .oe_notebook_page - padding: 0 - //Customize label weight according bootstrap3 - > label:not([for]) - font-weight: normal !important - // End of customize - div.ui-tabs - padding: 3px 0px 3px 0px - .ui-tabs-hide - display: none - // }}} // Dropdown {{{ .oe_dropdown, .oe_dropdown_hover, .oe_dropdown_toggle position: relative diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index edff8582e09..7ebfd4de1a3 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -1514,50 +1514,54 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt }, process_notebook: function($notebook) { var self = this; + + // Extract useful info from the notebook xml declaration var pages = []; $notebook.find('> page').each(function() { var $page = $(this); var page_attrs = $page.getAttributes(); page_attrs.id = _.uniqueId('notebook_page_'); - var $new_page = self.render_element('FormRenderingNotebookPage', page_attrs); - $page.contents().appendTo($new_page); - $page.before($new_page).remove(); - var ic = self.handle_common_properties($new_page, $page).invisibility_changer; - page_attrs.__page = $new_page; - page_attrs.__ic = ic; + page_attrs.contents = $page.html(); + page_attrs.ref = $page; // reference to the current page node in the xml declaration pages.push(page_attrs); - - $new_page.children().each(function() { - self.process($(this)); - }); }); - var $new_notebook = this.render_element('FormRenderingNotebook', { pages : pages }); - $notebook.contents().appendTo($new_notebook); + + // Render the notebook and replace $notebook with it + var $new_notebook = self.render_element('FormRenderingNotebook', {'pages': pages}); $notebook.before($new_notebook).remove(); - self.process($($new_notebook.children()[0])); - //tabs and invisibility handling - $new_notebook.tabs(); - _.each(pages, function(page, i) { - if (! page.__ic) - return; - page.__ic.on("change:effective_invisible", null, function() { - if (!page.__ic.get('effective_invisible') && page.autofocus) { - $new_notebook.tabs('select', i); - return; - } - var current = $new_notebook.tabs("option", "selected"); - if (! pages[current].__ic || ! pages[current].__ic.get("effective_invisible")) - return; - var first_visible = _.find(_.range(pages.length), function(i2) { - return (! pages[i2].__ic) || (! pages[i2].__ic.get("effective_invisible")); - }); - if (first_visible !== undefined) { - $new_notebook.tabs('select', first_visible); - } - }); - }); - this.handle_common_properties($new_notebook, $notebook); + // Bind the invisibility changers and find the page to display + var pageid_to_display; + _.each(pages, function(page) { + $tab = $new_notebook.find('a[href=#' + page.id + ']').parent(); + $content = $new_notebook.find('#' + page.id); + + // Case: ; + // We attach the autofocus attribute to the node because it can be useful during the + // page execution + self.attach_node_attr($tab, page.ref, 'autofocus'); + self.attach_node_attr($content, page.ref, 'autofocus'); + if (!pageid_to_display && page.autofocus) { + // If multiple autofocus, keep the first one + pageid_to_display = page.id; + } + + // Case: ; + self.handle_common_properties($tab, page.ref, instance.web.form.NotebookInvisibilityChanger); + self.handle_common_properties($content, page.ref, instance.web.form.NotebookInvisibilityChanger); + }); + if (!pageid_to_display) { + pageid_to_display = $new_notebook.find('div[role="tabpanel"]:not(.oe_form_invisible):first').attr('id'); + } + + // Display page. Note: we can't use bootstrap's show function because it is looking for + // document attached DOM, and the form view is only attached when everything is processed + $new_notebook.find('a[href=#' + pageid_to_display + ']').parent().addClass('active'); + $new_notebook.find('#' + pageid_to_display).addClass('active in'); // `in` class is required for bootstrap's fade + + self.process($new_notebook.children()); + self.handle_common_properties($new_notebook, $notebook); + return $new_notebook; }, process_separator: function($separator) { @@ -1591,16 +1595,25 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt } return $new_label; }, - handle_common_properties: function($new_element, $node) { + handle_common_properties: function($new_element, $node, InvisibilityChanger) { var str_modifiers = $node.attr("modifiers") || "{}"; var modifiers = JSON.parse(str_modifiers); var ic = null; - if (modifiers.invisible !== undefined) - ic = new instance.web.form.InvisibilityChanger(this.view, this.view, modifiers.invisible, $new_element); + if (modifiers.invisible !== undefined) { + var InvisibilityChangerCls = InvisibilityChanger || instance.web.form.InvisibilityChanger; + ic = new InvisibilityChangerCls(this.view, this.view, modifiers.invisible, $new_element); + } $new_element.addClass($node.attr("class") || ""); $new_element.attr('style', $node.attr('style')); return {invisibility_changer: ic,}; }, + /** + * Attach a node attribute to an html element to be able to use it after + * the processing of the page. + */ + attach_node_attr: function($new_element, $node, attr) { + $new_element.data('autofocus', $node.attr(attr)); + } }); /** @@ -1772,6 +1785,39 @@ instance.web.form.InvisibilityChanger = instance.web.Class.extend(instance.web.P }, }); +// Specialization of InvisibilityChanger for the `notebook` form element to handle more +// elegantly its special cases (i.e. activate the closest visible sibling) +instance.web.form.NotebookInvisibilityChanger = instance.web.form.InvisibilityChanger.extend({ + _check_visibility: function() { + this._super(); + if (this.get("effective_invisible") === true) { + // Switch to invisible + // Remove this element as active and set a visible sibling active (if there is one) + if (this.$el.hasClass('active')) { + this.$el.removeClass('active in'); + var visible_siblings = this.$el.siblings(':not(.oe_form_invisible)'); + if (visible_siblings.length) { + $(visible_siblings[0]).addClass('active in'); + } + } + } else { + // Switch to visible + // If there is no visible active sibling, set this element as active, + // otherwise: + // if that sibling has autofocus, do nothing + // otherwise, remove that sibling as active and set this element as active + var visible_active_sibling = this.$el.siblings(':not(.oe_form_invisible).active'); + if (!(visible_active_sibling.length)) { + this.$el.addClass('active in'); + } else if (!$(visible_active_sibling[0]).data('autofocus')) { + this.$el.addClass('active in'); + $(visible_active_sibling[0]).removeClass('active in'); + } + } + }, +}); + + /** Base class for all fields, custom widgets and buttons to be displayed in the form view. diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index e5b8286bdb9..dffa0a47fc3 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -888,17 +888,18 @@
-
-
- -
+
+
+ +
+