diff options
| author | Christophe Simonis <chs@openerp.com> | 2012-09-05 15:31:10 +0200 |
|---|---|---|
| committer | Christophe Simonis <chs@openerp.com> | 2012-09-05 15:31:10 +0200 |
| commit | 5bd23d30f514b5a971ed241ce33b1d47f5808638 (patch) | |
| tree | f8e68a6b24bffd0b7104536283a2ebe178140119 /addons/web/static/src | |
| parent | 522fb2e4b9fdf46abed3b5ca8ba43758b22253a1 (diff) | |
| parent | 80daa1b9565b2521d9b784878cbf81aca068a200 (diff) | |
merge upstream
bzr revid: chs@openerp.com-20120905133110-p11de3hgocaoc5b2
Diffstat (limited to 'addons/web/static/src')
| -rw-r--r-- | addons/web/static/src/css/base.css | 285 | ||||
| -rw-r--r-- | addons/web/static/src/css/base.sass | 313 | ||||
| -rw-r--r-- | addons/web/static/src/js/chrome.js | 138 | ||||
| -rw-r--r-- | addons/web/static/src/js/corelib.js | 50 | ||||
| -rw-r--r-- | addons/web/static/src/js/coresetup.js | 183 | ||||
| -rw-r--r-- | addons/web/static/src/js/data_export.js | 114 | ||||
| -rw-r--r-- | addons/web/static/src/js/data_import.js | 56 | ||||
| -rw-r--r-- | addons/web/static/src/js/search.js | 166 | ||||
| -rw-r--r-- | addons/web/static/src/js/test_support.js | 1 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_form.js | 439 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_list.js | 77 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_list_editable.js | 67 | ||||
| -rw-r--r-- | addons/web/static/src/js/view_tree.js | 26 | ||||
| -rw-r--r-- | addons/web/static/src/js/views.js | 219 | ||||
| -rw-r--r-- | addons/web/static/src/xml/base.xml | 72 |
15 files changed, 1054 insertions, 1152 deletions
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index eb641d5887e..226ccbd3513 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -20,50 +20,6 @@ font-style: normal; } -@-moz-keyframes bounce { - 0% { - -moz-transform: scale(0); - opacity: 0; - } - - 50% { - -moz-transform: scale(1.3); - opacity: 0.4; - } - - 75% { - -moz-transform: scale(0.9); - opacity: 0.7; - } - - 100% { - -moz-transform: scale(1); - opacity: 1; - } -} - -@-webkit-keyframes bounce { - 0% { - -webkit-transform: scale(0); - opacity: 0; - } - - 50% { - -webkit-transform: scale(1.3); - opacity: 0.4; - } - - 75% { - -webkit-transform: scale(0.9); - opacity: 0.7; - } - - 100% { - -webkit-transform: scale(1); - opacity: 1; - } -} - @media print { .oe_topbar, .oe_leftbar, .oe_loading { display: none !important; @@ -155,11 +111,26 @@ .openerp h4 { margin: 4px 0; } -.openerp .oe_semantic_html_override ul, .openerp .oe_semantic_html_override li, .openerp .oe_semantic_html_override ol { +.openerp .oe_semantic_html_override ul, .openerp .oe_semantic_html_override ol { margin: 0; padding: 0; } -.openerp .oe_semantic_html_override ul li, .openerp .oe_semantic_html_override li li, .openerp .oe_semantic_html_override ol li { +.openerp .oe_semantic_html_override ul ul, .openerp .oe_semantic_html_override ul ol, .openerp .oe_semantic_html_override ul li, .openerp .oe_semantic_html_override ol ul, .openerp .oe_semantic_html_override ol ol, .openerp .oe_semantic_html_override ol li { + margin: 0; + padding: 0; +} +.openerp .oe_semantic_html_override ul li, .openerp .oe_semantic_html_override ol li { + list-style-type: none; +} +.openerp ul.oe_semantic_html_override { + margin: 0; + padding: 0; +} +.openerp ul.oe_semantic_html_override ul, .openerp ul.oe_semantic_html_override ol, .openerp ul.oe_semantic_html_override li { + margin: 0; + padding: 0; +} +.openerp ul.oe_semantic_html_override li { list-style-type: none; } .openerp a.button:link, .openerp a.button:visited, .openerp button, .openerp input[type='submit'], .openerp .ui-dialog-buttonpane .ui-dialog-buttonset .ui-button { @@ -237,6 +208,9 @@ .openerp .ui-widget-content a { color: #7c7bad; } +.openerp .oe_bounce_container { + display: inline-block; +} .openerp.ui-dialog { display: none; padding: 6px; @@ -502,6 +476,7 @@ -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); border: none; + margin-bottom: 10px; } .openerp .oe_avatar + div { margin-left: 5px; @@ -519,9 +494,9 @@ padding: 0; margin: 0; background: none; - -moz-border-radius: none; - -webkit-border-radius: none; - border-radius: none; + -moz-border-radius: 0; + -webkit-border-radius: 0; + border-radius: 0; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; @@ -534,9 +509,9 @@ padding: 0; margin: 0; background: none; - -moz-border-radius: none; - -webkit-border-radius: none; - border-radius: none; + -moz-border-radius: 0; + -webkit-border-radius: 0; + border-radius: 0; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; @@ -574,6 +549,9 @@ background: #7c7bad; color: #eeeeee; } +.openerp .oe_tags { + margin-bottom: 1px; +} .openerp .oe_tags.oe_inline { min-width: 250px; } @@ -629,14 +607,22 @@ margin: 0; padding: 0; } +.openerp .oe_notebook ul, .openerp .oe_notebook ol, .openerp .oe_notebook li { + margin: 0; + padding: 0; +} .openerp .oe_notebook li { list-style-type: none; } -.openerp .oe_notebook ul, .openerp .oe_notebook li, .openerp .oe_notebook ol { +.openerp .oe_notebook ul, .openerp .oe_notebook ol { + margin: 0; + padding: 0; +} +.openerp .oe_notebook ul ul, .openerp .oe_notebook ul ol, .openerp .oe_notebook ul li, .openerp .oe_notebook ol ul, .openerp .oe_notebook ol ol, .openerp .oe_notebook ol li { margin: 0; padding: 0; } -.openerp .oe_notebook ul li, .openerp .oe_notebook li li, .openerp .oe_notebook ol li { +.openerp .oe_notebook ul li, .openerp .oe_notebook ol li { list-style-type: none; } .openerp .oe_notebook.ui-corner-all { @@ -942,11 +928,15 @@ -webkit-box-shadow: 0 0 18px rgba(0, 0, 0, 0.9); box-shadow: 0 0 18px rgba(0, 0, 0, 0.9); } -.openerp .oe_login .oe_login_pane ul, .openerp .oe_login .oe_login_pane li, .openerp .oe_login .oe_login_pane ol { +.openerp .oe_login .oe_login_pane ul, .openerp .oe_login .oe_login_pane ol { margin: 0; padding: 0; } -.openerp .oe_login .oe_login_pane ul li, .openerp .oe_login .oe_login_pane li li, .openerp .oe_login .oe_login_pane ol li { +.openerp .oe_login .oe_login_pane ul ul, .openerp .oe_login .oe_login_pane ul ol, .openerp .oe_login .oe_login_pane ul li, .openerp .oe_login .oe_login_pane ol ul, .openerp .oe_login .oe_login_pane ol ol, .openerp .oe_login .oe_login_pane ol li { + margin: 0; + padding: 0; +} +.openerp .oe_login .oe_login_pane ul li, .openerp .oe_login .oe_login_pane ol li { list-style-type: none; } .openerp .oe_login .oe_login_pane h2 { @@ -1028,11 +1018,15 @@ background-image: -o-linear-gradient(top, #646060, #262626); background-image: linear-gradient(to bottom, #646060, #262626); } -.openerp .oe_topbar ul, .openerp .oe_topbar li, .openerp .oe_topbar ol { +.openerp .oe_topbar ul, .openerp .oe_topbar ol { + margin: 0; + padding: 0; +} +.openerp .oe_topbar ul ul, .openerp .oe_topbar ul ol, .openerp .oe_topbar ul li, .openerp .oe_topbar ol ul, .openerp .oe_topbar ol ol, .openerp .oe_topbar ol li { margin: 0; padding: 0; } -.openerp .oe_topbar ul li, .openerp .oe_topbar li li, .openerp .oe_topbar ol li { +.openerp .oe_topbar ul li, .openerp .oe_topbar ol li { list-style-type: none; } .openerp .oe_topbar .oe_topbar_item { @@ -1107,11 +1101,15 @@ text-shadow: 0 1px 1px white; padding-bottom: 16px; } -.openerp .oe_leftbar ul, .openerp .oe_leftbar li, .openerp .oe_leftbar ol { +.openerp .oe_leftbar ul, .openerp .oe_leftbar ol { + margin: 0; + padding: 0; +} +.openerp .oe_leftbar ul ul, .openerp .oe_leftbar ul ol, .openerp .oe_leftbar ul li, .openerp .oe_leftbar ol ul, .openerp .oe_leftbar ol ol, .openerp .oe_leftbar ol li { margin: 0; padding: 0; } -.openerp .oe_leftbar ul li, .openerp .oe_leftbar li li, .openerp .oe_leftbar ol li { +.openerp .oe_leftbar ul li, .openerp .oe_leftbar ol li { list-style-type: none; } .openerp a.oe_logo { @@ -1206,16 +1204,16 @@ width: 100%; display: inline-block; } -.openerp .oe_secondary_submenu > li { +.openerp .oe_secondary_submenu li { position: relative; - padding: 1px 0 1px 20px; + padding: 1px 0 1px 20px !important; } -.openerp .oe_secondary_submenu > li a { +.openerp .oe_secondary_submenu li a { display: block; color: #4c4c4c; padding: 2px 4px 2px 0; } -.openerp .oe_secondary_submenu > li .oe_menu_label { +.openerp .oe_secondary_submenu li .oe_menu_label { position: absolute; top: 1px; right: 1px; @@ -1316,12 +1314,15 @@ width: 100%; table-layout: fixed; } -.openerp .oe_view_manager table.oe_view_manager_header ul, .openerp .oe_view_manager table.oe_view_manager_header li, .openerp .oe_view_manager table.oe_view_manager_header ol { - margin: 0; +.openerp .oe_view_manager table.oe_view_manager_header ul { padding: 0; + margin-right: 0; + margin-top: 0; + margin-bottom: 0; } -.openerp .oe_view_manager table.oe_view_manager_header ul li, .openerp .oe_view_manager table.oe_view_manager_header li li, .openerp .oe_view_manager table.oe_view_manager_header ol li { +.openerp .oe_view_manager table.oe_view_manager_header ul li { list-style-type: none; + margin: 0; } .openerp .oe_view_manager table.oe_view_manager_header .oe_header_row { clear: both; @@ -1432,11 +1433,15 @@ color: white; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); } +.openerp .oe_view_manager .oe_view_manager_switch { + margin-left: 8px; +} .openerp .oe_view_manager .oe_view_manager_switch li { text-align: center; width: 24px; height: 24px; line-height: 16px; + padding: 0; } .openerp .oe_view_manager .oe_view_manager_switch li a { position: relative; @@ -1968,6 +1973,35 @@ margin: -16px -16px 0 -16px; padding: 8px; } +.openerp .oe_form_sheetbg { + padding: 8px 0; +} +.openerp .oe_form_sheet_width { + min-width: 650px; + max-width: 860px; + margin: 0 auto; +} +.openerp .oe_form_sheet { + background: white; + min-height: 330px; + padding: 16px; +} +.openerp .oe_application .oe_form_sheetbg { + background: url(/web/static/src/img/form_sheetbg.png); + border-bottom: 1px solid #dddddd; +} +.openerp .oe_application .oe_form_sheet { + border: 1px solid #afafb6; + -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); + -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); + box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); +} +.openerp .oe_application .oe_form_sheet .ui-tabs { + margin: 0 -16px; +} +.openerp .oe_application .oe_form_sheet .oe_notebook_page { + padding: 0 16px; +} .openerp .oe_form header { position: relative; border-bottom: 1px solid #cacaca; @@ -1989,8 +2023,10 @@ margin: 0 auto; padding: 16px 0 48px; } -.openerp .oe_form div.oe_form_configuration div.oe_horizontal_separator { - margin: 12px 0 8px 0; +.openerp .oe_form .oe_grey { + color: #aaaaaa; + max-width: 650px; + margin: 0 0 10px 0; } .openerp .oe_form div.oe_form_configuration p, .openerp .oe_form div.oe_form_configuration ul, .openerp .oe_form div.oe_form_configuration ol { color: #aaaaaa; @@ -2005,11 +2041,11 @@ .openerp .oe_form div.oe_form_configuration .oe_form_group_cell div div { padding: 1px 0; } -.openerp ul.oe_form_steps, .openerp ul.oe_form_steps_clickable { +.openerp .oe_form ul.oe_form_steps, .openerp .oe_form ul.oe_form_steps_clickable { display: inline-block; padding-right: 18px; } -.openerp ul.oe_form_steps li, .openerp ul.oe_form_steps_clickable li { +.openerp .oe_form ul.oe_form_steps li, .openerp .oe_form ul.oe_form_steps_clickable li { display: inline-block; margin-right: -20px; background-color: #fcfcfc; @@ -2020,20 +2056,20 @@ background-image: -o-linear-gradient(top, #fcfcfc, #dedede); background-image: linear-gradient(to bottom, #fcfcfc, #dedede); } -.openerp ul.oe_form_steps li:first-child .label, .openerp ul.oe_form_steps_clickable li:first-child .label { +.openerp .oe_form ul.oe_form_steps li:first-child .label, .openerp .oe_form ul.oe_form_steps_clickable li:first-child .label { border-left: 1px solid #cacaca; padding-left: 14px; } -.openerp ul.oe_form_steps li:last-child, .openerp ul.oe_form_steps_clickable li:last-child { +.openerp .oe_form ul.oe_form_steps li:last-child, .openerp .oe_form ul.oe_form_steps_clickable li:last-child { border-right: 1px solid #cacaca; } -.openerp ul.oe_form_steps li:last-child .label, .openerp ul.oe_form_steps_clickable li:last-child .label { +.openerp .oe_form ul.oe_form_steps li:last-child .label, .openerp .oe_form ul.oe_form_steps_clickable li:last-child .label { padding-right: 14px; } -.openerp ul.oe_form_steps li:last-child .arrow, .openerp ul.oe_form_steps_clickable li:last-child .arrow { +.openerp .oe_form ul.oe_form_steps li:last-child .arrow, .openerp .oe_form ul.oe_form_steps_clickable li:last-child .arrow { display: none; } -.openerp ul.oe_form_steps li .label, .openerp ul.oe_form_steps_clickable li .label { +.openerp .oe_form ul.oe_form_steps li .label, .openerp .oe_form ul.oe_form_steps_clickable li .label { color: #4c4c4c; text-shadow: 0 1px 1px #fcfcfc, 0 -1px 1px #dedede; padding: 7px; @@ -2041,18 +2077,16 @@ padding-left: 24px; margin: 0; position: relative; - z-index: 10; } -.openerp ul.oe_form_steps li .arrow, .openerp ul.oe_form_steps_clickable li .arrow { +.openerp .oe_form ul.oe_form_steps li .arrow, .openerp .oe_form ul.oe_form_steps_clickable li .arrow { width: 17px; display: inline-block; vertical-align: top; overflow: hidden; margin-left: -5px; } -.openerp ul.oe_form_steps li .arrow span, .openerp ul.oe_form_steps_clickable li .arrow span { +.openerp .oe_form ul.oe_form_steps li .arrow span, .openerp .oe_form ul.oe_form_steps_clickable li .arrow span { position: relative; - z-index: 11; width: 24px; height: 24px; display: inline-block; @@ -2066,12 +2100,13 @@ -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; - -moz-transform: rotate(45deg); -webkit-transform: rotate(45deg); - -o-transform: rotate(45deg); + -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); } -.openerp ul.oe_form_steps li.oe_active, .openerp ul.oe_form_steps_clickable li.oe_active { +.openerp .oe_form ul.oe_form_steps li.oe_active, .openerp .oe_form ul.oe_form_steps_clickable li.oe_active { background-color: #729fcf; background-image: -webkit-gradient(linear, left top, left bottom, from(#729fcf), to(#3465a4)); background-image: -webkit-linear-gradient(top, #729fcf, #3465a4); @@ -2080,20 +2115,20 @@ background-image: -o-linear-gradient(top, #729fcf, #3465a4); background-image: linear-gradient(to bottom, #729fcf, #3465a4); } -.openerp ul.oe_form_steps li.oe_active .arrow span, .openerp ul.oe_form_steps_clickable li.oe_active .arrow span { +.openerp .oe_form ul.oe_form_steps li.oe_active .arrow span, .openerp .oe_form ul.oe_form_steps_clickable li.oe_active .arrow span { background-color: #3465a4; background: -moz-linear-gradient(135deg, #3465a4, #729fcf); background: -o-linear-gradient(135deg, #729fcf, #3465a4); background: -webkit-gradient(linear, left top, right bottom, from(#729fcf), to(#3465a4)); } -.openerp ul.oe_form_steps li.oe_active .label, .openerp ul.oe_form_steps_clickable li.oe_active .label { +.openerp .oe_form ul.oe_form_steps li.oe_active .label, .openerp .oe_form ul.oe_form_steps_clickable li.oe_active .label { color: white; text-shadow: 0 1px 1px #729fcf, 0 -1px 1px #3465a4; } -.openerp ul.oe_form_steps_clickable li { +.openerp .oe_form ul.oe_form_steps_clickable li { cursor: pointer; } -.openerp ul.oe_form_steps_clickable li:hover { +.openerp .oe_form ul.oe_form_steps_clickable li:hover { background-color: #e8e8e8; background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#cacaca)); background-image: -webkit-linear-gradient(top, #e8e8e8, #cacaca); @@ -2102,10 +2137,10 @@ background-image: -o-linear-gradient(top, #e8e8e8, #cacaca); background-image: linear-gradient(to bottom, #e8e8e8, #cacaca); } -.openerp ul.oe_form_steps_clickable li:hover .label { +.openerp .oe_form ul.oe_form_steps_clickable li:hover .label { text-shadow: 0 -1px 1px #fcfcfc, 0 1px 1px #dedede; } -.openerp ul.oe_form_steps_clickable li:hover .arrow span { +.openerp .oe_form ul.oe_form_steps_clickable li:hover .arrow span { background-color: #e8e8e8; background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#cacaca)); background-image: -webkit-linear-gradient(top, #e8e8e8, #cacaca); @@ -2114,10 +2149,10 @@ background-image: -o-linear-gradient(top, #e8e8e8, #cacaca); background-image: linear-gradient(to bottom, #e8e8e8, #cacaca); } -.openerp ul.oe_form_steps_clickable li .label { +.openerp .oe_form ul.oe_form_steps_clickable li .label { color: #7c7bad; } -.openerp ul.oe_form_steps_clickable li.oe_active:hover { +.openerp .oe_form ul.oe_form_steps_clickable li.oe_active:hover { background-color: #4c85c2; background-image: -webkit-gradient(linear, left top, left bottom, from(#4c85c2), to(#284d7d)); background-image: -webkit-linear-gradient(top, #4c85c2, #284d7d); @@ -2126,10 +2161,10 @@ background-image: -o-linear-gradient(top, #4c85c2, #284d7d); background-image: linear-gradient(to bottom, #4c85c2, #284d7d); } -.openerp ul.oe_form_steps_clickable li.oe_active:hover .label { +.openerp .oe_form ul.oe_form_steps_clickable li.oe_active:hover .label { text-shadow: 0 -1px 1px #729fcf, 0 1px 1px #3465a4; } -.openerp ul.oe_form_steps_clickable li.oe_active:hover .arrow span { +.openerp .oe_form ul.oe_form_steps_clickable li.oe_active:hover .arrow span { background-color: #284d7d; background: -moz-linear-gradient(135deg, #284d7d, #4c85c2); background: -o-linear-gradient(135deg, #4c85c2, #284d7d); @@ -2161,31 +2196,6 @@ .openerp .oe_form .oe_subtotal_footer label.oe_form_label_help { font-weight: normal; } -.openerp .oe_application .oe_form_sheetbg { - background: url(/web/static/src/img/form_sheetbg.png); - padding: 8px 0; - border-bottom: 1px solid #dddddd; -} -.openerp .oe_application .oe_form_sheet_width { - min-width: 650px; - max-width: 860px; - margin: 0 auto; -} -.openerp .oe_application .oe_form_sheet { - background: white; - min-height: 330px; - padding: 16px; - border: 1px solid #afafb6; - -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); - box-shadow: 0 0 10px rgba(0, 0, 0, 0.3); -} -.openerp .oe_application .oe_form_sheet .ui-tabs { - margin: 0 -16px; -} -.openerp .oe_application .oe_form_sheet .oe_notebook_page { - padding: 0 16px; -} .openerp .oe_form .oe_form_button { margin: 2px; } @@ -2196,7 +2206,7 @@ .openerp .oe_form td.oe_form_group_cell_label label { line-height: 18px; display: block; - min-width: 160px; + min-width: 140px; } .openerp .oe_form td.oe_form_group_cell + .oe_form_group_cell { padding-left: 6px; @@ -2227,7 +2237,7 @@ .openerp .oe_horizontal_separator { font-weight: bold; font-size: 20px; - margin: 8px 0px 8px 0px; + margin: 15px 0px 10px 0px; color: #7c7bad; } .openerp .oe_horizontal_separator:empty { @@ -2302,7 +2312,7 @@ -ms-box-sizing: border-box; box-sizing: border-box; background: white; - min-width: 70px; + min-width: 60px; color: #1f1f1f; } .openerp .oe_form input[readonly], .openerp .oe_form select[readonly], .openerp .oe_form textarea[readonly], .openerp .oe_form input[disabled], .openerp .oe_form select[disabled] { @@ -2441,17 +2451,32 @@ float: right; padding-left: 2px; } +.openerp.ui-autocomplete li.oe_m2o_dropdown_option a { + font-style: italic; + padding-left: 2em; +} +.openerp.ui-autocomplete li:not(.oe_m2o_dropdown_option) + li.oe_m2o_dropdown_option { + margin-top: 10px; +} .openerp .oe_form_field_status { margin: 0; padding: 0; } -.openerp .oe_form_field_status ul, .openerp .oe_form_field_status li, .openerp .oe_form_field_status ol { +.openerp .oe_form_field_status ul, .openerp .oe_form_field_status ol { + margin: 0; + padding: 0; +} +.openerp .oe_form_field_status ul ul, .openerp .oe_form_field_status ul ol, .openerp .oe_form_field_status ul li, .openerp .oe_form_field_status ol ul, .openerp .oe_form_field_status ol ol, .openerp .oe_form_field_status ol li { margin: 0; padding: 0; } -.openerp .oe_form_field_status ul li, .openerp .oe_form_field_status li li, .openerp .oe_form_field_status ol li { +.openerp .oe_form_field_status ul li, .openerp .oe_form_field_status ol li { list-style-type: none; } +.openerp .oe_form_field_status ul, .openerp .oe_form_field_status ol, .openerp .oe_form_field_status li { + margin: 0; + padding: 0; +} .openerp .oe_form_field_status li { list-style-type: none; } @@ -2519,10 +2544,11 @@ height: 27px; } .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field input, .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field textarea { + -moz-border-radius: 0; + -webkit-border-radius: 0; + border-radius: 0; border: 1px solid #aaaaff; - border-radius: 0px; - margin: 0px; - -webkit-border-radius: 0px; + margin: 0; } .openerp .oe_list.oe_list_editable.oe_editing .oe_form_field textarea { height: 60px; @@ -2622,6 +2648,7 @@ cursor: pointer; } .openerp .oe_list_content > tbody > tr { + height: 27px; border-top: 1px solid #dddddd; } .openerp .oe_list_content > tbody > tr > td.oe_list_field_cell { @@ -2684,6 +2711,12 @@ content: "รถ"; color: #404040; } +.openerp .oe_list_cannot_edit .oe_list_header_handle, .openerp .oe_list_cannot_edit .oe_list_field_handle { + display: none !important; +} +.openerp .oe_list_cannot_delete .oe_list_record_delete { + display: none !important; +} .openerp .tree_header { background-color: #f0f0f0; border-bottom: 1px solid #cacaca; diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index aa75956f0a1..13f740f218c 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -36,7 +36,7 @@ $sheet-max-width: 860px padding: 0 margin: 0 background: none - @include radius(none) + @include radius(0) @include box-shadow(none) @mixin vertical-gradient($startColor: #555, $endColor: #333) @@ -95,10 +95,23 @@ $sheet-max-width: 860px background: -webkit-gradient(linear, left top, right bottom, from($startColor), to($endColor)) @mixin transform($transform) - -moz-transform: $transform -webkit-transform: $transform - -o-transform: $transform + -moz-transform: $transform -ms-transform: $transform + -o-transform: $transform + transform: $transform + +@mixin keyframes($name) + @-webkit-keyframes #{$name} + @content + @-moz-keyframes #{$name} + @content + @-ms-keyframes #{$name} + @content + @-o-keyframes #{$name} + @content + @keyframes #{$name} + @content // Transforms the (readable) text of an inline element into an mmlicons icon, // allows for actual readable text in-code (and in readers?) with iconic looks @@ -114,43 +127,17 @@ $sheet-max-width: 860px @mixin ul-html-override() margin: 0 padding: 0 + ul, ol, li + margin: 0 + padding: 0 li list-style-type: none @mixin semantic-html-override() - ul, li, ol + ul, ol @include ul-html-override() // }}} -// CSS animation bounces {{{ -@-moz-keyframes bounce - 0% - -moz-transform: scale(0) - opacity: 0 - 50% - -moz-transform: scale(1.3) - opacity: 0.4 - 75% - -moz-transform: scale(0.9) - opacity: 0.7 - 100% - -moz-transform: scale(1) - opacity: 1 - -@-webkit-keyframes bounce - 0% - -webkit-transform: scale(0) - opacity: 0 - 50% - -webkit-transform: scale(1.3) - opacity: 0.4 - 75% - -webkit-transform: scale(0.9) - opacity: 0.7 - 100% - -webkit-transform: scale(1) - opacity: 1 -// }}} @media print .oe_topbar, .oe_leftbar, .oe_loading @@ -215,6 +202,8 @@ $sheet-max-width: 860px margin: 4px 0 .oe_semantic_html_override @include semantic-html-override + ul.oe_semantic_html_override + @include ul-html-override // }}} // Button style {{{ a.button:link, a.button:visited, button, input[type='submit'], .ui-dialog-buttonpane .ui-dialog-buttonset .ui-button @@ -258,6 +247,8 @@ $sheet-max-width: 860px // Jquery ui Overrides {{{ .ui-widget-content a color: $link-color + .oe_bounce_container + display: inline-block // Modal box &.ui-dialog @@ -429,6 +420,7 @@ $sheet-max-width: 860px @include radius(3px) @include box-shadow(0 1px 3px rgba(0, 0, 0, 0.3)) border: none + margin-bottom: 10px .oe_avatar + div margin-left: 5px .oe_image_small > img @@ -482,6 +474,7 @@ $sheet-max-width: 860px .text-core .text-wrap .text-dropdown .text-list .text-suggestion em font-style: italic text-decoration: none + margin-bottom: 1px // }}} // Tooltips {{{ &.oe_tooltip @@ -932,9 +925,9 @@ $sheet-max-width: 860px margin: 0 width: 100% display: inline-block - > li + li position: relative - padding: 1px 0 1px 20px + padding: 1px 0 1px 20px !important a display: block color: #4c4c4c @@ -1019,7 +1012,14 @@ $sheet-max-width: 860px table.oe_view_manager_header width: 100% table-layout: fixed - @include semantic-html-override + ul + padding: 0 + margin-right: 0 + margin-top: 0 + margin-bottom: 0 + li + list-style-type: none + margin: 0 .oe_header_row //min-height: 26px //line-height: 26px @@ -1104,11 +1104,13 @@ $sheet-max-width: 860px // }}} // ViewManager.switches {{{ .oe_view_manager_switch + margin-left: 8px li text-align: center width: 24px height: 24px line-height: 16px + padding: 0 a position: relative .oe_vm_switch_list:after, .oe_vm_switch_tree:after @@ -1509,11 +1511,34 @@ $sheet-max-width: 860px display: none !important .oe_form .oe_form_field_date width: auto + // Sheet and padding .oe_form_nosheet margin: 16px > header margin: -16px -16px 0 -16px padding: 8px + .oe_form_sheetbg + padding: 8px 0 + .oe_form_sheet_width + min-width: 650px + max-width: $sheet-max-width + margin: 0 auto + .oe_form_sheet + background: white + min-height: 330px + padding: 16px + // Sheet inline mode + .oe_application + .oe_form_sheetbg + background: url(/web/static/src/img/form_sheetbg.png) + border-bottom: 1px solid #ddd + .oe_form_sheet + border: 1px solid $tag-border + @include box-shadow(0 0 10px rgba(0,0,0,0.3)) + .ui-tabs + margin: 0 -16px + .oe_notebook_page + padding: 0 16px // }}} // FormView.custom tags and classes {{{ .oe_form @@ -1529,9 +1554,11 @@ $sheet-max-width: 860px max-width: $sheet-max-width margin: 0 auto padding: 16px 0 48px + .oe_grey + color: #aaa + max-width: 650px + margin: 0 0 10px 0 div.oe_form_configuration - div.oe_horizontal_separator - margin: 12px 0 8px 0 p, ul, ol color: #aaa max-width: 650px @@ -1541,117 +1568,92 @@ $sheet-max-width: 860px padding: 2px 0 .oe_form_group_cell div div padding: 1px 0 - - - ul.oe_form_steps, ul.oe_form_steps_clickable - display: inline-block - padding-right: 18px - li + ul.oe_form_steps, ul.oe_form_steps_clickable display: inline-block - margin-right: -20px - @include vertical-gradient(#fcfcfc, #dedede) - &:first-child .label - border-left: 1px solid #cacaca - padding-left: 14px - &:last-child - border-right: 1px solid #cacaca - .label - padding-right: 14px - .arrow - display: none - .label - color: #4c4c4c - text-shadow: 0 1px 1px #fcfcfc, 0 -1px 1px #dedede - padding: 7px - display: inline-block - padding-left: 24px - margin: 0 - position: relative - z-index: 10 - .arrow - width: 17px + padding-right: 18px + li display: inline-block - vertical-align: top - overflow: hidden - margin-left: -5px - span + margin-right: -20px + @include vertical-gradient(#fcfcfc, #dedede) + &:first-child .label + border-left: 1px solid #cacaca + padding-left: 14px + &:last-child + border-right: 1px solid #cacaca + .label + padding-right: 14px + .arrow + display: none + .label + color: #4c4c4c + text-shadow: 0 1px 1px #fcfcfc, 0 -1px 1px #dedede + padding: 7px + display: inline-block + padding-left: 24px + margin: 0 position: relative - z-index: 11 - width: 24px - height: 24px + .arrow + width: 17px display: inline-block - margin-left: -12px - margin-top: 3px - box-shadow: -1px 1px 2px rgba(255,255,255,0.2), inset -1px 1px 1px rgba(0,0,0,0.2) - @include skew-gradient(#fcfcfc, #dedede) - @include radius(3px) - @include transform(rotate(45deg)) - li.oe_active - @include vertical-gradient(#729fcf, #3465a4) - .arrow span - @include skew-gradient(#729fcf, #3465a4) - .label - color: white - text-shadow: 0 1px 1px #729fcf, 0 -1px 1px #3465a4 - - ul.oe_form_steps_clickable - li - cursor: pointer - &:hover - @include vertical-gradient(darken(#fcfcfc, 8%), darken(#dedede, 8%)) - .label - text-shadow: 0 -1px 1px #fcfcfc, 0 1px 1px #dedede + vertical-align: top + overflow: hidden + margin-left: -5px + span + position: relative + width: 24px + height: 24px + display: inline-block + margin-left: -12px + margin-top: 3px + box-shadow: -1px 1px 2px rgba(255,255,255,0.2), inset -1px 1px 1px rgba(0,0,0,0.2) + @include skew-gradient(#fcfcfc, #dedede) + @include radius(3px) + @include transform(rotate(45deg)) + li.oe_active + @include vertical-gradient(#729fcf, #3465a4) .arrow span + @include skew-gradient(#729fcf, #3465a4) + .label + color: white + text-shadow: 0 1px 1px #729fcf, 0 -1px 1px #3465a4 + ul.oe_form_steps_clickable + li + cursor: pointer + &:hover @include vertical-gradient(darken(#fcfcfc, 8%), darken(#dedede, 8%)) - .label - color: $link-color - li.oe_active - &:hover - @include vertical-gradient(darken(#729fcf, 10%), darken(#3465a4, 10%)) + .label + text-shadow: 0 -1px 1px #fcfcfc, 0 1px 1px #dedede + .arrow span + @include vertical-gradient(darken(#fcfcfc, 8%), darken(#dedede, 8%)) .label - text-shadow: 0 -1px 1px #729fcf, 0 1px 1px #3465a4 - .arrow span - @include skew-gradient(darken(#729fcf, 10%), darken(#3465a4, 10%)) + color: $link-color + li.oe_active + &:hover + @include vertical-gradient(darken(#729fcf, 10%), darken(#3465a4, 10%)) + .label + text-shadow: 0 -1px 1px #729fcf, 0 1px 1px #3465a4 + .arrow span + @include skew-gradient(darken(#729fcf, 10%), darken(#3465a4, 10%)) + .oe_subtotal_footer + width: 1% !important + td.oe_form_group_cell + text-align: right + padding: 0 !important + td.oe_form_group_cell_label + border-right: none + .oe_subtotal_footer_separator + width: 108px + border-top: 1px solid #cacaca + font-weight: bold + font-size: 18px + label:after + content: ":" + label.oe_subtotal_footer_separator + font-weight: bold !important + padding: 2px 11px 2px 0px !important + label.oe_form_label_help + font-weight: normal - .oe_form .oe_subtotal_footer - width: 1% !important - td.oe_form_group_cell - text-align: right - padding: 0 !important - td.oe_form_group_cell_label - border-right: none - .oe_subtotal_footer_separator - width: 108px - border-top: 1px solid #cacaca - font-weight: bold - font-size: 18px - label:after - content: ":" - label.oe_subtotal_footer_separator - font-weight: bold !important - padding: 2px 11px 2px 0px !important - label.oe_form_label_help - font-weight: normal - // no sheet in popups - .oe_application - .oe_form_sheetbg - background: url(/web/static/src/img/form_sheetbg.png) - padding: 8px 0 - border-bottom: 1px solid #ddd - .oe_form_sheet_width - min-width: 650px - max-width: $sheet-max-width - margin: 0 auto - .oe_form_sheet - background: white - min-height: 330px - padding: 16px - border: 1px solid $tag-border - @include box-shadow(0 0 10px rgba(0,0,0,0.3)) - .ui-tabs - margin: 0 -16px - .oe_notebook_page - padding: 0 16px // }}} // FormView.group {{{ .oe_form @@ -1663,7 +1665,7 @@ $sheet-max-width: 860px label line-height: 18px display: block - min-width: 160px + min-width: 140px td.oe_form_group_cell + .oe_form_group_cell padding-left: 6px .oe_form_group @@ -1692,7 +1694,7 @@ $sheet-max-width: 860px .oe_horizontal_separator font-weight: bold font-size: 20px - margin: 8px 0px 8px 0px + margin: 15px 0px 10px 0px color: $section-title-color .oe_horizontal_separator:empty height: 5px @@ -1749,7 +1751,7 @@ $sheet-max-width: 860px input[type="text"], input[type="password"], input[type="file"], select, textarea @include box-sizing(border) background: white - min-width: 70px + min-width: 60px color: #1f1f1f input[readonly], select[readonly], textarea[readonly], input[disabled], select[disabled] background: #E5E5E5 !important @@ -1866,6 +1868,12 @@ $sheet-max-width: 860px line-height: 14px float: right padding-left: 2px + &.ui-autocomplete + li.oe_m2o_dropdown_option a + font-style: italic + padding-left: 2em + li:not(.oe_m2o_dropdown_option) + li.oe_m2o_dropdown_option + margin-top: 10px // }}} // FormView.fieldstatus {{{ .oe_form_field_status @@ -1919,6 +1927,8 @@ $sheet-max-width: 860px background-color: #d2d2ff td.oe_readonly background-color: #eee + + $row-height: 27px .oe_list_editable .oe_list_content td.oe_list_field_cell @@ -1933,12 +1943,11 @@ $sheet-max-width: 860px display: none .oe_form_field input - height: 27px + height: $row-height input, textarea + @include radius(0) border: 1px solid #aaf - border-radius: 0px - margin: 0px - -webkit-border-radius: 0px + margin: 0 textarea height: 60px &.oe_form_field_float,&.oe_form_view_integer @@ -2023,6 +2032,7 @@ $sheet-max-width: 860px > tbody cursor: pointer > tr + height: $row-height border-top: 1px solid #ddd > td.oe_list_field_cell padding: 3px 6px @@ -2062,6 +2072,13 @@ $sheet-max-width: 860px .oe_list_handle @include text-to-icon("รถ") + .oe_list_cannot_edit + .oe_list_header_handle, .oe_list_field_handle + display: none !important + .oe_list_cannot_delete + .oe_list_record_delete + display: none !important + // }}} // Tree view {{{ .tree_header diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index e8cdf8d6ab5..736e10875f6 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -13,7 +13,7 @@ instance.web.Notification = instance.web.Widget.extend({ }, start: function() { this._super.apply(this, arguments); - this.$element.notify({ + this.$el.notify({ speed: 500, expires: 2500 }); @@ -24,7 +24,7 @@ instance.web.Notification = instance.web.Widget.extend({ if (sticky) { opts.expires = false; } - this.$element.notify('create', { + this.$el.notify('create', { title: title, text: text }, opts); @@ -35,7 +35,7 @@ instance.web.Notification = instance.web.Widget.extend({ if (sticky) { opts.expires = false; } - this.$element.notify('create', 'oe_notification_alert', { + this.$el.notify('create', 'oe_notification_alert', { title: title, text: text }, opts); @@ -123,22 +123,22 @@ instance.web.Dialog = instance.web.Widget.extend({ if (! this.dialog_inited) this.init_dialog(); var o = this.get_options(options); - instance.web.dialog(this.$element, o).dialog('open'); + instance.web.dialog(this.$el, o).dialog('open'); if (o.height === 'auto' && o.max_height) { - this.$element.css({ 'max-height': o.max_height, 'overflow-y': 'auto' }); + this.$el.css({ 'max-height': o.max_height, 'overflow-y': 'auto' }); } return this; }, init_dialog: function(options) { this.renderElement(); var o = this.get_options(options); - instance.web.dialog(this.$element, o); + instance.web.dialog(this.$el, o); var res = this.start(); this.dialog_inited = true; return res; }, close: function() { - this.$element.dialog('close'); + this.$el.dialog('close'); }, on_close: function() { if (this.__tmp_dialog_destroying) @@ -161,7 +161,7 @@ instance.web.Dialog = instance.web.Widget.extend({ this.__tmp_dialog_destroying = undefined; } if (! this.isDestroyed()) { - this.$element.dialog('destroy'); + this.$el.dialog('destroy'); } this._super(); } @@ -193,29 +193,9 @@ instance.web.CrashManager = instance.web.CallbackEnabled.extend({ on_traceback: function(error) { var self = this; var buttons = {}; - if (instance.session.openerp_entreprise) { - buttons[_t("Send OpenERP Enterprise Report")] = function() { - var $this = $(this); - var issuename = $('#issuename').val(); - var explanation = $('#explanation').val(); - var remark = $('#remark').val(); - // Call the send method from server to send mail with details - new instance.web.DataSet(self, 'publisher_warranty.contract').call_and_eval('send', [error.data,explanation,remark,issuename]).then(function(result){ - if (result === false) { - alert('There was a communication error.'); - } else { - $this.dialog('close'); - } - }); - }; - buttons[_t("Dont send")] = function() { - $(this).dialog("close"); - }; - } else { - buttons[_t("Ok")] = function() { - $(this).dialog("close"); - }; - } + buttons[_t("Ok")] = function() { + $(this).dialog("close"); + }; var dialog = new instance.web.Dialog(this, { title: "OpenERP " + _.str.capitalize(error.type), width: '80%', @@ -224,7 +204,7 @@ instance.web.CrashManager = instance.web.CallbackEnabled.extend({ min_height: '600px', buttons: buttons }).open(); - dialog.$element.html(QWeb.render('CrashManager.error', {session: instance.session, error: error})); + dialog.$el.html(QWeb.render('CrashManager.error', {session: instance.session, error: error})); }, on_javascript_exception: function(exception) { this.on_traceback({ @@ -270,12 +250,12 @@ instance.web.Loading = instance.web.Widget.extend({ this.count += increment; if (this.count > 0) { if (instance.session.debug) { - this.$element.text(_.str.sprintf( _t("Loading (%d)"), this.count)); + this.$el.text(_.str.sprintf( _t("Loading (%d)"), this.count)); } else { - this.$element.text(_t("Loading")); + this.$el.text(_t("Loading")); } - this.$element.show(); - this.getParent().$element.addClass('oe_wait'); + this.$el.show(); + this.getParent().$el.addClass('oe_wait'); } else { this.count = 0; clearTimeout(this.long_running_timer); @@ -284,8 +264,8 @@ instance.web.Loading = instance.web.Widget.extend({ this.blocked_ui = false; instance.web.unblockUI(); } - this.$element.fadeOut(); - this.getParent().$element.removeClass('oe_wait'); + this.$el.fadeOut(); + this.getParent().$el.removeClass('oe_wait'); } } }); @@ -317,7 +297,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ do_render: function() { var self = this; instance.webclient.toggle_bars(true); - self.$element.html(QWeb.render("DatabaseManager", { widget : self })); + self.$el.html(QWeb.render("DatabaseManager", { widget : self })); $('.oe_user_menu_placeholder').append(QWeb.render("DatabaseManager.user_menu",{ widget : self })); $('.oe_secondary_menus_container').append(QWeb.render("DatabaseManager.menu",{ widget : self })); $('ul.oe_secondary_submenu > li:first').addClass('oe_active') @@ -329,14 +309,14 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ event.preventDefault(); }); $('#back-to-login').click(self.do_exit); - self.$element.find("td").addClass("oe_form_group_cell"); - self.$element.find("tr td:first-child").addClass("oe_form_group_cell_label"); - self.$element.find("label").addClass("oe_form_label"); - self.$element.find("form[name=create_db_form]").validate({ submitHandler: self.do_create }); - self.$element.find("form[name=drop_db_form]").validate({ submitHandler: self.do_drop }); - self.$element.find("form[name=backup_db_form]").validate({ submitHandler: self.do_backup }); - self.$element.find("form[name=restore_db_form]").validate({ submitHandler: self.do_restore }); - self.$element.find("form[name=change_pwd_form]").validate({ + self.$el.find("td").addClass("oe_form_group_cell"); + self.$el.find("tr td:first-child").addClass("oe_form_group_cell_label"); + self.$el.find("label").addClass("oe_form_label"); + self.$el.find("form[name=create_db_form]").validate({ submitHandler: self.do_create }); + self.$el.find("form[name=drop_db_form]").validate({ submitHandler: self.do_drop }); + self.$el.find("form[name=backup_db_form]").validate({ submitHandler: self.do_backup }); + self.$el.find("form[name=restore_db_form]").validate({ submitHandler: self.do_restore }); + self.$el.find("form[name=change_pwd_form]").validate({ messages: { old_pwd: "Please enter your previous password", new_pwd: "Please enter your new password", @@ -349,7 +329,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ }); }, destroy: function () { - this.$element.find('#db-create, #db-drop, #db-backup, #db-restore, #db-change-password, #back-to-login').unbind('click').end().empty(); + this.$el.find('#db-create, #db-drop, #db-backup, #db-restore, #db-change-password, #back-to-login').unbind('click').end().empty(); this._super(); }, /** @@ -500,7 +480,7 @@ instance.web.DatabaseManager = instance.web.Widget.extend({ }); }, do_exit: function () { - this.$element.remove(); + this.$el.remove(); instance.webclient.toggle_bars(false); this.do_action('login'); } @@ -533,8 +513,8 @@ instance.web.Login = instance.web.Widget.extend({ }, start: function() { var self = this; - self.$element.find("form").submit(self.on_submit); - self.$element.find('.oe_login_manage_db').click(function() { + self.$el.find("form").submit(self.on_submit); + self.$el.find('.oe_login_manage_db').click(function() { self.do_action("database_manager"); }); var d; @@ -584,7 +564,7 @@ instance.web.Login = instance.web.Widget.extend({ */ do_login: function (db, login, password) { var self = this; - this.$element.removeClass('oe_login_invalid'); + this.$el.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) { @@ -603,7 +583,7 @@ instance.web.Login = instance.web.Widget.extend({ self.trigger('login_successful'); },function () { self.$(".oe_login_pane").fadeIn("fast", function() { - self.$element.addClass("oe_login_invalid"); + self.$el.addClass("oe_login_invalid"); }); }); }, @@ -663,7 +643,7 @@ instance.web.ChangePassword = instance.web.Widget.extend({ template: "ChangePassword", start: function() { var self = this; - self.$element.validate({ + self.$el.validate({ submitHandler: function (form) { self.rpc("/web/session/change_password",{ 'fields': $(form).serializeArray() @@ -700,7 +680,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 = this.getParent().$el.find('.oe_secondary_menus_container'); this.$secondary_menus.on('click', 'a[data-menu]', this.on_menu_click); return this.do_reload(); }, @@ -718,7 +698,7 @@ instance.web.Menu = instance.web.Widget.extend({ $toplevel.hide(); } this.$secondary_menus.html(QWeb.render("Menu.secondary", { widget : this })); - this.$element.on('click', 'a[data-menu]', this.on_menu_click); + this.$el.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) { @@ -733,7 +713,7 @@ instance.web.Menu = instance.web.Widget.extend({ } if (maximum_visible_links < this.data.data.children.length) { var $more = $(QWeb.render('Menu.more')), - $index = this.$element.find('li').eq(maximum_visible_links - 1); + $index = this.$el.find('li').eq(maximum_visible_links - 1); $index.after($more); //$('.oe_topbar').append($more); $more.find('.oe_menu_more').append($index.next().nextAll()); @@ -752,19 +732,19 @@ instance.web.Menu = instance.web.Widget.extend({ */ open_menu: function (id) { var $clicked_menu, $sub_menu, $main_menu; - $clicked_menu = this.$element.add(this.$secondary_menus).find('a[data-menu=' + id + ']'); + $clicked_menu = this.$el.add(this.$secondary_menus).find('a[data-menu=' + id + ']'); this.trigger('open_menu', id, $clicked_menu); if (this.$secondary_menus.has($clicked_menu).length) { $sub_menu = $clicked_menu.parents('.oe_secondary_menu'); - $main_menu = this.$element.find('a[data-menu=' + $sub_menu.data('menu-parent') + ']'); + $main_menu = this.$el.find('a[data-menu=' + $sub_menu.data('menu-parent') + ']'); } else { $sub_menu = this.$secondary_menus.find('.oe_secondary_menu[data-menu-parent=' + $clicked_menu.attr('data-menu') + ']'); $main_menu = $clicked_menu; } // Activate current main menu - this.$element.find('.oe_active').removeClass('oe_active'); + this.$el.find('.oe_active').removeClass('oe_active'); $main_menu.addClass('oe_active'); // Show current sub menu @@ -791,7 +771,7 @@ instance.web.Menu = instance.web.Widget.extend({ * @param {Number} id the action_id to match */ open_action: function (id) { - var $menu = this.$element.add(this.$secondary_menus).find('a[data-action-id="' + id + '"]'); + var $menu = this.$el.add(this.$secondary_menus).find('a[data-action-id="' + id + '"]'); var menu_id = $menu.data('menu'); if (menu_id) { this.open_menu(menu_id); @@ -807,14 +787,14 @@ instance.web.Menu = instance.web.Widget.extend({ if (!id) { return; } // find back the menuitem in dom to get the action - var $item = this.$element.find('a[data-menu=' + id + ']'); + var $item = this.$el.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) { + if(this.$el.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) { @@ -855,7 +835,7 @@ instance.web.UserMenu = instance.web.Widget.extend({ start: function() { var self = this; this._super.apply(this, arguments); - this.$element.on('click', '.oe_dropdown_menu li a[data-menu]', function(ev) { + this.$el.on('click', '.oe_dropdown_menu li a[data-menu]', function(ev) { ev.preventDefault(); var f = self['on_menu_' + $(this).data('menu')]; if (f) { @@ -866,7 +846,7 @@ instance.web.UserMenu = instance.web.Widget.extend({ do_update: function () { var self = this; var fct = function() { - var $avatar = self.$element.find('.oe_topbar_avatar'); + var $avatar = self.$el.find('.oe_topbar_avatar'); $avatar.attr('src', $avatar.data('default-src')); if (!self.session.uid) return; @@ -877,7 +857,7 @@ instance.web.UserMenu = instance.web.Widget.extend({ topbar_name = _.str.sprintf("%s (%s)", topbar_name, instance.session.db); if(res.company_id[0] > 1) topbar_name = _.str.sprintf("%s (%s)", topbar_name, res.company_id[1]); - self.$element.find('.oe_topbar_name').text(topbar_name); + self.$el.find('.oe_topbar_name').text(topbar_name); var avatar_src = _.str.sprintf('%s/web/binary/image?session_id=%s&model=res.users&field=image_small&id=%s', self.session.prefix, self.session.session_id, self.session.uid); $avatar.attr('src', avatar_src); }); @@ -927,10 +907,10 @@ instance.web.Client = instance.web.Widget.extend({ }, bind_events: function() { var self = this; - this.$element.on('mouseenter', '.oe_systray > div:not([data-tipsy=true])', function() { + this.$el.on('mouseenter', '.oe_systray > div:not([data-tipsy=true])', function() { $(this).attr('data-tipsy', 'true').tipsy().trigger('mouseenter'); }); - this.$element.on('click', '.oe_dropdown_toggle', function(ev) { + this.$el.on('click', '.oe_dropdown_toggle', function(ev) { ev.preventDefault(); var $toggle = $(this); var $menu = $toggle.siblings('.oe_dropdown_menu'); @@ -954,7 +934,7 @@ instance.web.Client = instance.web.Widget.extend({ instance.web.bus.on('click', this, function(ev) { $.fn.tipsy.clear(); if (!$(ev.target).is('input[type=file]')) { - self.$element.find('.oe_dropdown_menu.oe_opened, .oe_dropdown_toggle.oe_opened').removeClass('oe_opened'); + self.$el.find('.oe_dropdown_menu.oe_opened, .oe_dropdown_toggle.oe_opened').removeClass('oe_opened'); } }); }, @@ -963,9 +943,9 @@ instance.web.Client = instance.web.Widget.extend({ this.crashmanager = new instance.web.CrashManager(); instance.session.on_rpc_error.add(this.crashmanager.on_rpc_error); self.notification = new instance.web.Notification(this); - self.notification.appendTo(self.$element); + self.notification.appendTo(self.$el); self.loading = new instance.web.Loading(self); - self.loading.appendTo(self.$element); + self.loading.appendTo(self.$el); self.action_manager = new instance.web.ActionManager(self); self.action_manager.appendTo(self.$('.oe_application')); }, @@ -1035,25 +1015,21 @@ instance.web.WebClient = instance.web.Client.extend({ var self = this; self.toggle_bars(true); self.menu = new instance.web.Menu(self); - self.menu.replace(this.$element.find('.oe_menu_placeholder')); + self.menu.replace(this.$el.find('.oe_menu_placeholder')); self.menu.on('menu_click', this, this.on_menu_action); self.user_menu = new instance.web.UserMenu(self); - self.user_menu.replace(this.$element.find('.oe_user_menu_placeholder')); + self.user_menu.replace(this.$el.find('.oe_user_menu_placeholder')); self.user_menu.on_menu_logout.add(this.proxy('on_logout')); self.user_menu.on_action.add(this.proxy('on_menu_action')); self.user_menu.do_update(); self.bind_hashchange(); - if (!self.session.openerp_entreprise) { - var version_label = _t("OpenERP - Unsupported/Community Version"); - self.$element.find('.oe_footer_powered').append(_.str.sprintf('<span> - <a href="http://www.openerp.com/support-or-publisher-warranty-contract" target="_blank">%s</a></span>', version_label)); - } self.set_title(); }, destroy_content: function() { _.each(_.clone(this.getChildren()), function(el) { el.destroy(); }); - this.$element.children().remove(); + this.$el.children().remove(); }, do_reload: function() { var self = this; @@ -1085,7 +1061,7 @@ instance.web.WebClient = instance.web.Client.extend({ var state = $.bbq.getState(true); if (_.isEmpty(state) || state.action == "login") { self.menu.has_been_loaded.then(function() { - var first_menu_id = self.menu.$element.find("a:first").data("menu"); + var first_menu_id = self.menu.$el.find("a:first").data("menu"); if(first_menu_id) { self.menu.menu_click(first_menu_id); } @@ -1140,10 +1116,10 @@ instance.web.WebClient = instance.web.Client.extend({ }, set_content_full_screen: function(fullscreen) { if (fullscreen) { - $(".oe_webclient", this.$element).addClass("oe_content_full_screen"); + $(".oe_webclient", this.$el).addClass("oe_content_full_screen"); $("body").css({'overflow-y':'hidden'}); } else { - $(".oe_webclient", this.$element).removeClass("oe_content_full_screen"); + $(".oe_webclient", this.$el).removeClass("oe_content_full_screen"); $("body").css({'overflow-y':'scroll'}); } } diff --git a/addons/web/static/src/js/corelib.js b/addons/web/static/src/js/corelib.js index 5da12043994..c74c2d5dc03 100644 --- a/addons/web/static/src/js/corelib.js +++ b/addons/web/static/src/js/corelib.js @@ -525,8 +525,8 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, { _.each(this.getChildren(), function(el) { el.destroy(); }); - if(this.$element) { - this.$element.remove(); + if(this.$el) { + this.$el.remove(); } instance.web.PropertiesMixin.destroy.call(this); }, @@ -538,7 +538,7 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, { appendTo: function(target) { var self = this; return this.__widgetRenderAndInsert(function(t) { - self.$element.appendTo(t); + self.$el.appendTo(t); }, target); }, /** @@ -549,7 +549,7 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, { prependTo: function(target) { var self = this; return this.__widgetRenderAndInsert(function(t) { - self.$element.prependTo(t); + self.$el.prependTo(t); }, target); }, /** @@ -560,7 +560,7 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, { insertAfter: function(target) { var self = this; return this.__widgetRenderAndInsert(function(t) { - self.$element.insertAfter(t); + self.$el.insertAfter(t); }, target); }, /** @@ -571,7 +571,7 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, { insertBefore: function(target) { var self = this; return this.__widgetRenderAndInsert(function(t) { - self.$element.insertBefore(t); + self.$el.insertBefore(t); }, target); }, /** @@ -581,7 +581,7 @@ instance.web.WidgetMixin = _.extend({},instance.web.CallbackEnabledMixin, { */ replace: function(target) { return this.__widgetRenderAndInsert(_.bind(function(t) { - this.$element.replaceAll(t); + this.$el.replaceAll(t); }, this), target); }, __widgetRenderAndInsert: function(insertion, target) { @@ -640,8 +640,8 @@ instance.web.CallbackEnabled = instance.web.Class.extend(instance.web.CallbackEn * // stuff that you want to init before the rendering * }, * start: function() { - * // stuff you want to make after the rendering, `this.$element` holds a correct value - * this.$element.find(".my_button").click(/* an example of event binding * /); + * // stuff you want to make after the rendering, `this.$el` holds a correct value + * this.$el.find(".my_button").click(/* an example of event binding * /); * * // if you have some asynchronous operations, it's a good idea to return * // a promise in start() @@ -718,15 +718,15 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, { * @returns {*} this */ replaceElement: function ($el) { - var $oldel = this.$element; + var $oldel = this.$el; this.setElement($el); - if ($oldel && !$oldel.is(this.$element)) { - $oldel.replaceWith(this.$element); + if ($oldel && !$oldel.is(this.$el)) { + $oldel.replaceWith(this.$el); } return this; }, /** - * Re-sets the widget's root element (el/$el/$element). + * Re-sets the widget's root element (el/$el/$el). * * Includes: * * re-delegating events @@ -738,14 +738,14 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, { * @return {*} this */ setElement: function (element) { - // NB: completely useless, as WidgetMixin#init creates a $element + // NB: completely useless, as WidgetMixin#init creates a $el // always - if (this.$element) { + if (this.$el) { this.undelegateEvents(); } - this.$element = (element instanceof $) ? element : $(element); - this.el = this.$element[0]; + this.$el = (element instanceof $) ? element : $(element); + this.el = this.$el[0]; this.delegateEvents(); @@ -797,23 +797,23 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, { event += '.widget_events'; if (!selector) { - this.$element.on(event, method); + this.$el.on(event, method); } else { - this.$element.on(event, selector, method); + this.$el.on(event, selector, method); } } }, undelegateEvents: function () { - this.$element.off('.widget_events'); + this.$el.off('.widget_events'); }, /** - * Shortcut for ``this.$element.find(selector)`` + * Shortcut for ``this.$el.find(selector)`` * * @param {String} selector CSS selector, rooted in $el * @returns {jQuery} selector match */ $: function(selector) { - return this.$element.find(selector); + return this.$el.find(selector); }, /** * Informs the action manager to do an action. This supposes that @@ -1323,12 +1323,6 @@ instance.web.JsonRPC = instance.web.CallbackEnabled.extend({ deferred.resolve(response["result"], textStatus, jqXHR); } else if (response.error.data.type === "session_invalid") { self.uid = false; - // TODO deprecate or use a deferred on login.do_ask_login() - self.on_session_invalid(function() { - self.rpc(url, payload.params, - function() { deferred.resolve.apply(deferred, arguments); }, - function() { deferred.reject.apply(deferred, arguments); }); - }); } else { deferred.reject(response.error, $.Event()); } diff --git a/addons/web/static/src/js/coresetup.js b/addons/web/static/src/js/coresetup.js index a34a7dadd30..0c10d40f0ca 100644 --- a/addons/web/static/src/js/coresetup.js +++ b/addons/web/static/src/js/coresetup.js @@ -35,7 +35,6 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess this.username = false; this.user_context= {}; this.db = false; - this.openerp_entreprise = false; this.module_list = instance._modules.slice(); this.module_loaded = {}; _(this.module_list).each(function (mod) { @@ -78,8 +77,7 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess db: result.db, username: result.login, uid: result.uid, - user_context: result.context, - openerp_entreprise: result.openerp_entreprise + user_context: result.context }); }); }, @@ -103,8 +101,7 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess db: result.db, username: result.login, uid: result.uid, - user_context: result.context, - openerp_entreprise: result.openerp_entreprise + user_context: result.context }); if (!_volatile) { self.set_cookie('session_id', self.session_id); @@ -116,20 +113,6 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess this.set_cookie('session_id', ''); return this.rpc("/web/session/destroy", {}); }, - on_session_valid: function() { - }, - /** - * Called when a rpc call fail due to an invalid session. - * By default, it's a noop - */ - on_session_invalid: function(retry_callback) { - }, - /** - * Fetches a cookie stored by an openerp session - * - * @private - * @param name the cookie's name - */ get_cookie: function (name) { if (!this.name) { return null; } var nameEQ = this.name + '|' + name + '='; @@ -163,9 +146,8 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess /** * Load additional web addons of that instance and init them * - * @param {Boolean} [no_session_valid_signal=false] prevents load_module from triggering ``on_session_valid``. */ - load_modules: function(no_session_valid_signal) { + load_modules: function() { var self = this; return this.rpc('/web/session/modules', {}).pipe(function(result) { var lang = self.user_context.lang, @@ -198,9 +180,6 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess return loaded.then(function() { self.on_modules_loaded(); self.trigger('module_loaded'); - if (!no_session_valid_signal) { - self.on_session_valid(); - } }); }); }, @@ -520,82 +499,6 @@ $.async_when = function() { return old_async_when.apply(this, arguments); }; -/** Setup blockui */ -if ($.blockUI) { - $.blockUI.defaults.baseZ = 1100; - $.blockUI.defaults.message = '<div class="oe_blockui_spin_container">'; - $.blockUI.defaults.css.border = '0'; - $.blockUI.defaults.css["background-color"] = ''; -} - -var messages_by_seconds = [ - [0, "Loading..."], - [30, "Still Loading..."], - [60, "Still Loading...<br />Please be patient."], - [120, "Hey, guess what?<br />It's still loading."], - [300, "You may not believe it,<br/>but the application is actually loading..."], -]; - -instance.web.Throbber = instance.web.Widget.extend({ - template: "Throbber", - start: function() { - var opts = { - lines: 13, // The number of lines to draw - length: 7, // The length of each line - width: 4, // The line thickness - radius: 10, // The radius of the inner circle - rotate: 0, // The rotation offset - color: '#FFF', // #rgb or #rrggbb - speed: 1, // Rounds per second - trail: 60, // Afterglow percentage - shadow: false, // Whether to render a shadow - hwaccel: false, // Whether to use hardware acceleration - className: 'spinner', // The CSS class to assign to the spinner - zIndex: 2e9, // The z-index (defaults to 2000000000) - top: 'auto', // Top position relative to parent in px - left: 'auto' // Left position relative to parent in px - }; - this.spin = new Spinner(opts).spin(this.$element[0]); - this.start_time = new Date().getTime(); - this.act_message(); - }, - act_message: function() { - var self = this; - setTimeout(function() { - if (self.isDestroyed()) - return; - var seconds = (new Date().getTime() - self.start_time) / 1000; - var mes; - _.each(messages_by_seconds, function(el) { - if (seconds >= el[0]) - mes = el[1]; - }); - self.$(".oe_throbber_message").html(mes); - self.act_message(); - }, 1000); - }, - destroy: function() { - if (this.spin) - this.spin.stop(); - this._super(); - }, -}); -instance.web.Throbber.throbbers = []; - -instance.web.blockUI = function() { - var tmp = $.blockUI.apply($, arguments); - var throbber = new instance.web.Throbber(); - instance.web.Throbber.throbbers.push(throbber); - throbber.appendTo($(".oe_blockui_spin_container")); - return tmp; -} -instance.web.unblockUI = function() { - _.each(instance.web.Throbber.throbbers, function(el) { - el.destroy(); - }); - return $.unblockUI.apply($, arguments); -} - /** Setup default session */ instance.session = new instance.web.Session(); @@ -679,6 +582,86 @@ instance.session.on('module_loaded', this, function () { $.timeago.settings.translator = instance.web._t; }); +/** Setup blockui */ +if ($.blockUI) { + $.blockUI.defaults.baseZ = 1100; + $.blockUI.defaults.message = '<div class="oe_blockui_spin_container">'; + $.blockUI.defaults.css.border = '0'; + $.blockUI.defaults.css["background-color"] = ''; +} + +var messages_by_seconds = function() { + return [ + [0, _t("Loading...")], + [30, _t("Still loading...")], + [60, _t("Still loading...<br />Please be patient.")], + [120, _t("Don't leave yet,<br />it's still loading...")], + [300, _t("You may not believe it,<br />but the application is actually loading...")], + [600, _t("You know, sometimes,<br />OpenERP can be a little bit slow,<br />because it's loading...")], + [3600, _t("Maybe you should consider pressing F5...")], + ]; +}; + +instance.web.Throbber = instance.web.Widget.extend({ + template: "Throbber", + start: function() { + var opts = { + lines: 13, // The number of lines to draw + length: 7, // The length of each line + width: 4, // The line thickness + radius: 10, // The radius of the inner circle + rotate: 0, // The rotation offset + color: '#FFF', // #rgb or #rrggbb + speed: 1, // Rounds per second + trail: 60, // Afterglow percentage + shadow: false, // Whether to render a shadow + hwaccel: false, // Whether to use hardware acceleration + className: 'spinner', // The CSS class to assign to the spinner + zIndex: 2e9, // The z-index (defaults to 2000000000) + top: 'auto', // Top position relative to parent in px + left: 'auto' // Left position relative to parent in px + }; + this.spin = new Spinner(opts).spin(this.$el[0]); + this.start_time = new Date().getTime(); + this.act_message(); + }, + act_message: function() { + var self = this; + setTimeout(function() { + if (self.isDestroyed()) + return; + var seconds = (new Date().getTime() - self.start_time) / 1000; + var mes; + _.each(messages_by_seconds(), function(el) { + if (seconds >= el[0]) + mes = el[1]; + }); + self.$(".oe_throbber_message").html(mes); + self.act_message(); + }, 1000); + }, + destroy: function() { + if (this.spin) + this.spin.stop(); + this._super(); + }, +}); +instance.web.Throbber.throbbers = []; + +instance.web.blockUI = function() { + var tmp = $.blockUI.apply($, arguments); + var throbber = new instance.web.Throbber(); + instance.web.Throbber.throbbers.push(throbber); + throbber.appendTo($(".oe_blockui_spin_container")); + return tmp; +} +instance.web.unblockUI = function() { + _.each(instance.web.Throbber.throbbers, function(el) { + el.destroy(); + }); + return $.unblockUI.apply($, arguments); +} + /** * Registry for all the client actions key: tag value: widget */ diff --git a/addons/web/static/src/js/data_export.js b/addons/web/static/src/js/data_export.js index f8e669e1b4a..29aea6362f7 100644 --- a/addons/web/static/src/js/data_export.js +++ b/addons/web/static/src/js/data_export.js @@ -21,31 +21,31 @@ instance.web.DataExport = instance.web.Dialog.extend({ ], close: function(event, ui){ self.close();} }); - self.$element.removeClass('ui-dialog-content ui-widget-content'); - self.$element.find('#add_field').click(function() { + self.$el.removeClass('ui-dialog-content ui-widget-content'); + self.$el.find('#add_field').click(function() { if ($('#field-tree-structure tr.ui-selected')) { - var fld = self.$element.find('#field-tree-structure tr.ui-selected').find('a'); + var fld = self.$el.find('#field-tree-structure tr.ui-selected').find('a'); for (var i = 0; i < fld.length; i++) { var id = $(fld[i]).attr('id').split('-')[1]; var string = $(fld[i]).attr('string'); self.add_field(id, string); } - self.$element.find('#field-tree-structure tr').removeClass('ui-selected'); + self.$el.find('#field-tree-structure tr').removeClass('ui-selected'); } }); - self.$element.find('#remove_field').click(function() { - self.$element.find('#fields_list option:selected').remove(); + self.$el.find('#remove_field').click(function() { + self.$el.find('#fields_list option:selected').remove(); }); - self.$element.find('#remove_all_field').click(function() { - self.$element.find('#fields_list').empty(); + self.$el.find('#remove_all_field').click(function() { + self.$el.find('#fields_list').empty(); }); - this.$element.find('#export_new_list').click(this.on_show_save_list); + this.$el.find('#export_new_list').click(this.on_show_save_list); var got_fields = new $.Deferred(); - this.$element.find('#import_compat').change(function() { - self.$element.find('#fields_list').empty(); - self.$element.find('#field-tree-structure').remove(); - var import_comp = self.$element.find("#import_compat").val(); + this.$el.find('#import_compat').change(function() { + self.$el.find('#fields_list').empty(); + self.$el.find('#field-tree-structure').remove(); + var import_comp = self.$el.find("#import_compat").val(); self.rpc("/web/export/get_fields", { model: self.dataset.model, import_compat: Boolean(import_comp) @@ -61,7 +61,7 @@ instance.web.DataExport = instance.web.Dialog.extend({ this.show_exports_list()); }, do_setup_export_formats: function (formats) { - var $fmts = this.$element.find('#export_format'); + var $fmts = this.$el.find('#export_format'); _(formats).each(function (format) { var opt = new Option(format.label, format.tag); if (format.error) { @@ -76,8 +76,8 @@ instance.web.DataExport = instance.web.Dialog.extend({ }, show_exports_list: function() { var self = this; - if (self.$element.find('#saved_export_list').is(':hidden')) { - self.$element.find('#ExistsExportList').show(); + if (self.$el.find('#saved_export_list').is(':hidden')) { + self.$el.find('#ExistsExportList').show(); return; } return this.exports.read_slice(['name'], { @@ -86,35 +86,35 @@ instance.web.DataExport = instance.web.Dialog.extend({ if (!export_list.length) { return; } - self.$element.find('#ExistsExportList').append(QWeb.render('Exists.ExportList', {'existing_exports': export_list})); - self.$element.find('#saved_export_list').change(function() { - self.$element.find('#fields_list option').remove(); - var export_id = self.$element.find('#saved_export_list option:selected').val(); + self.$el.find('#ExistsExportList').append(QWeb.render('Exists.ExportList', {'existing_exports': export_list})); + self.$el.find('#saved_export_list').change(function() { + self.$el.find('#fields_list option').remove(); + var export_id = self.$el.find('#saved_export_list option:selected').val(); if (export_id) { self.rpc('/web/export/namelist', {'model': self.dataset.model, export_id: parseInt(export_id)}, self.do_load_export_field); } }); - self.$element.find('#delete_export_list').click(function() { - var select_exp = self.$element.find('#saved_export_list option:selected'); + self.$el.find('#delete_export_list').click(function() { + var select_exp = self.$el.find('#saved_export_list option:selected'); if (select_exp.val()) { self.exports.unlink([parseInt(select_exp.val(), 10)]); select_exp.remove(); - if (self.$element.find('#saved_export_list option').length <= 1) { - self.$element.find('#ExistsExportList').hide(); + if (self.$el.find('#saved_export_list option').length <= 1) { + self.$el.find('#ExistsExportList').hide(); } } }); }); }, do_load_export_field: function(field_list) { - var export_node = this.$element.find("#fields_list"); + var export_node = this.$el.find("#fields_list"); _(field_list).each(function (field) { export_node.append(new Option(field.label, field.name)); }); }, on_show_save_list: function() { var self = this; - var current_node = self.$element.find("#savenewlist"); + var current_node = self.$el.find("#savenewlist"); if (!(current_node.find("label")).length) { current_node.append(QWeb.render('ExportNewList')); current_node.find("#add_export_list").click(function() { @@ -150,14 +150,14 @@ instance.web.DataExport = instance.web.Dialog.extend({ if (!export_list_id.result) { return; } - self.$element.find("#saved_export_list").append( + self.$el.find("#saved_export_list").append( new Option(value, export_list_id.result)); - if (self.$element.find("#saved_export_list").is(":hidden")) { + if (self.$el.find("#saved_export_list").is(":hidden")) { self.show_exports_list(); } }); this.on_show_save_list(); - this.$element.find("#fields_list option").remove(); + this.$el.find("#fields_list option").remove(); }, on_click: function(id, record) { var self = this; @@ -173,7 +173,7 @@ instance.web.DataExport = instance.web.Dialog.extend({ } if (!record.loaded) { - var import_comp = self.$element.find("#import_compat").val(); + var import_comp = self.$el.find("#import_compat").val(); self.rpc("/web/export/get_fields", { model: model, prefix: prefix, @@ -191,44 +191,44 @@ instance.web.DataExport = instance.web.Dialog.extend({ }, on_show_data: function(result, after) { var self = this; - var imp_cmpt = Boolean(self.$element.find("#import_compat").val()); + var imp_cmpt = Boolean(self.$el.find("#import_compat").val()); if (after) { - var current_tr = self.$element.find("tr[id='treerow-" + after + "']"); + var current_tr = self.$el.find("tr[id='treerow-" + after + "']"); current_tr.addClass('open'); current_tr.find('img').attr('src','/web/static/src/img/collapse.gif'); current_tr.after(QWeb.render('ExportTreeView-Secondary.children', {'fields': result})); } else { - self.$element.find('#left_field_panel').append(QWeb.render('ExportTreeView-Secondary', {'fields': result})); + self.$el.find('#left_field_panel').append(QWeb.render('ExportTreeView-Secondary', {'fields': result})); } _.each(result, function(record) { self.records[record.id] = record.value; if (record.required) { - var required_fld = self.$element.find("tr[id='treerow-" + record.id + "']").find('#tree-column'); + var required_fld = self.$el.find("tr[id='treerow-" + record.id + "']").find('#tree-column'); required_fld.addClass("oe_export_requiredfield"); } - self.$element.find("img[id='parentimg-" + record.id +"']").click(function() { + self.$el.find("img[id='parentimg-" + record.id +"']").click(function() { self.on_click(this.id, record); }); - self.$element.find("tr[id='treerow-" + record.id + "']").click(function(e) { + self.$el.find("tr[id='treerow-" + record.id + "']").click(function(e) { if (e.shiftKey) { var frst_click, scnd_click = ''; if (self.row_index == 0) { self.row_index = this.rowIndex; - frst_click = self.$element.find("tr[id^='treerow-']")[self.row_index-1]; + frst_click = self.$el.find("tr[id^='treerow-']")[self.row_index-1]; $(frst_click).addClass("ui-selected"); } else { if (this.rowIndex >=self.row_index) { for (var i = (self.row_index-1); i < this.rowIndex; i++) { - scnd_click = self.$element.find("tr[id^='treerow-']")[i]; + scnd_click = self.$el.find("tr[id^='treerow-']")[i]; if (!$(scnd_click).find('#tree-column').hasClass("oe_export_readonlyfield")) { $(scnd_click).addClass("ui-selected"); } } } else { for (var i = (self.row_index-1); i >= (this.rowIndex-1); i--) { - scnd_click = self.$element.find("tr[id^='treerow-']")[i]; + scnd_click = self.$el.find("tr[id^='treerow-']")[i]; if (!$(scnd_click).find('#tree-column').hasClass("oe_export_readonlyfield")) { $(scnd_click).addClass("ui-selected"); } @@ -238,10 +238,10 @@ instance.web.DataExport = instance.web.Dialog.extend({ } self.row_index = this.rowIndex; - self.$element.find("tr[id='treerow-" + record.id + "']").keyup(function() { + self.$el.find("tr[id='treerow-" + record.id + "']").keyup(function() { self.row_index = 0; }); - var o2m_selection = self.$element.find("tr[id='treerow-" + record.id + "']").find('#tree-column'); + var o2m_selection = self.$el.find("tr[id='treerow-" + record.id + "']").find('#tree-column'); if ($(o2m_selection).hasClass("oe_export_readonlyfield")) { return false; } @@ -252,14 +252,14 @@ instance.web.DataExport = instance.web.Dialog.extend({ $(this).addClass('ui-selected').find('a').focus(); } } else if (!e.shiftKey) { - self.$element.find("tr.ui-selected") + self.$el.find("tr.ui-selected") .removeClass("ui-selected").find('a').blur(); $(this).addClass("ui-selected").find('a').focus(); } return false; }); - self.$element.find("tr[id='treerow-" + record.id + "']").keydown(function(e) { + self.$el.find("tr[id='treerow-" + record.id + "']").keydown(function(e) { var keyCode = e.keyCode || e.which; var arrow = {left: 37, up: 38, right: 39, down: 40 }; switch (keyCode) { @@ -297,19 +297,19 @@ instance.web.DataExport = instance.web.Dialog.extend({ break; } }); - self.$element.find("tr[id='treerow-" + record.id + "']").dblclick(function() { - var $o2m_selection = self.$element.find("tr[id^='treerow-" + record.id + "']").find('#tree-column'); + self.$el.find("tr[id='treerow-" + record.id + "']").dblclick(function() { + var $o2m_selection = self.$el.find("tr[id^='treerow-" + record.id + "']").find('#tree-column'); if (!$o2m_selection.hasClass("oe_export_readonlyfield")) { self.add_field(record.id, $(this).find("a").attr("string")); } }); }); - self.$element.find('#fields_list').mouseover(function(event) { + self.$el.find('#fields_list').mouseover(function(event) { if (event.relatedTarget) { if (event.relatedTarget.attributes['id'] && event.relatedTarget.attributes['string']) { var field_id = event.relatedTarget.attributes["id"]["value"]; if (field_id && field_id.split("-")[0] === 'export') { - if (!self.$element.find("tr[id='treerow-" + field_id.split("-")[1] + "']").find('#tree-column').hasClass("oe_export_readonlyfield")) { + if (!self.$el.find("tr[id='treerow-" + field_id.split("-")[1] + "']").find('#tree-column').hasClass("oe_export_readonlyfield")) { self.add_field(field_id.split("-")[1], event.relatedTarget.attributes["string"]["value"]); } } @@ -319,7 +319,7 @@ instance.web.DataExport = instance.web.Dialog.extend({ }, showcontent: function(id) { // show & hide the contents - var $this = this.$element.find("tr[id='treerow-" + id + "']"); + var $this = this.$el.find("tr[id='treerow-" + id + "']"); var is_open = $this.hasClass('open'); $this.toggleClass('open'); @@ -329,7 +329,7 @@ instance.web.DataExport = instance.web.Dialog.extend({ } else { first_child.attr('src', '/web/static/src/img/collapse.gif'); } - var child_field = this.$element.find("tr[id^='treerow-" + id +"/']"); + var child_field = this.$el.find("tr[id^='treerow-" + id +"/']"); var child_len = (id.split("/")).length + 1; for (var i = 0; i < child_field.length; i++) { var $child = $(child_field[i]); @@ -345,15 +345,15 @@ instance.web.DataExport = instance.web.Dialog.extend({ } }, add_field: function(field_id, string) { - var field_list = this.$element.find('#fields_list'); - if (this.$element.find("#fields_list option[value='" + field_id + "']") - && !this.$element.find("#fields_list option[value='" + field_id + "']").length) { + var field_list = this.$el.find('#fields_list'); + if (this.$el.find("#fields_list option[value='" + field_id + "']") + && !this.$el.find("#fields_list option[value='" + field_id + "']").length) { field_list.append(new Option(string, field_id)); } }, get_fields: function() { var export_field = []; - this.$element.find("#fields_list option").each(function() { + this.$el.find("#fields_list option").each(function() { export_field.push($(this).val()); }); if (!export_field.length) { @@ -363,7 +363,7 @@ instance.web.DataExport = instance.web.Dialog.extend({ }, on_click_export_data: function() { var self = this; - var exported_fields = this.$element.find('#fields_list option').map(function () { + var exported_fields = this.$el.find('#fields_list option').map(function () { // DOM property is textContent, but IE8 only knows innerText return {name: self.records[this.value] || this.value, label: this.textContent || this.innerText}; @@ -375,7 +375,7 @@ instance.web.DataExport = instance.web.Dialog.extend({ } exported_fields.unshift({name: 'id', label: 'External ID'}); - var export_format = this.$element.find("#export_format").val(); + var export_format = this.$el.find("#export_format").val(); instance.web.blockUI(); this.session.get_file({ url: '/web/export/' + export_format, @@ -385,13 +385,13 @@ instance.web.DataExport = instance.web.Dialog.extend({ ids: this.dataset.ids, domain: this.dataset.domain, import_compat: Boolean( - this.$element.find("#import_compat").val()) + this.$el.find("#import_compat").val()) })}, complete: instance.web.unblockUI }); }, close: function() { - this.$element.remove(); + this.$el.remove(); this._super(); } }); diff --git a/addons/web/static/src/js/data_import.js b/addons/web/static/src/js/data_import.js index 620878569ce..3c677b0ec26 100644 --- a/addons/web/static/src/js/data_import.js +++ b/addons/web/static/src/js/data_import.js @@ -75,9 +75,9 @@ instance.web.DataImport = instance.web.Dialog.extend({ } }); this.toggle_import_button(false); - 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.$el.find('#csvfile').change(this.on_autodetect_data); + this.$el.find('fieldset').change(this.on_autodetect_data); + this.$el.delegate('fieldset legend', 'click', function() { $(this).parent().toggleClass('oe_closed'); }); this.ready.push(new instance.web.DataSet(this, this.model).call( @@ -156,19 +156,19 @@ instance.web.DataImport = instance.web.Dialog.extend({ }); }, toggle_import_button: function (newstate) { - instance.web.dialog(this.$element, 'widget') + instance.web.dialog(this.$el, 'widget') .find('.oe_import_dialog_button') .button('option', 'disabled', !newstate); }, do_import: function() { - if(!this.$element.find('#csvfile').val()) { return; } - var lines_to_skip = parseInt(this.$element.find('#csv_skip').val(), 10); - var with_headers = this.$element.find('#file_has_headers').prop('checked'); + if(!this.$el.find('#csvfile').val()) { return; } + var lines_to_skip = parseInt(this.$el.find('#csv_skip').val(), 10); + var with_headers = this.$el.find('#file_has_headers').prop('checked'); if (!lines_to_skip && with_headers) { lines_to_skip = 1; } var indices = [], fields = []; - this.$element.find(".sel_fields").each(function(index, element) { + this.$el.find(".sel_fields").each(function(index, element) { var val = element.value; if (!val) { return; @@ -177,7 +177,7 @@ instance.web.DataImport = instance.web.Dialog.extend({ fields.push(val); }); - jsonp(this.$element.find('#import_data'), { + jsonp(this.$el.find('#import_data'), { url: '/web/import/import_data', data: { model: this.model, @@ -190,19 +190,19 @@ instance.web.DataImport = instance.web.Dialog.extend({ }, this.on_import_results); }, on_autodetect_data: function() { - if(!this.$element.find('#csvfile').val()) { return; } - jsonp(this.$element.find('#import_data'), { + if(!this.$el.find('#csvfile').val()) { return; } + jsonp(this.$el.find('#import_data'), { url: '/web/import/detect_data' }, this.on_import_results); }, on_import_results: function(results) { - this.$element.find('#result').empty(); - var headers, result_node = this.$element.find("#result"); + this.$el.find('#result').empty(); + var headers, result_node = this.$el.find("#result"); if (results['error']) { result_node.append(QWeb.render('ImportView.error', { 'error': results['error']})); - this.$element.find('fieldset').removeClass('oe_closed'); + this.$el.find('fieldset').removeClass('oe_closed'); return; } if (results['success']) { @@ -214,8 +214,8 @@ instance.web.DataImport = instance.web.Dialog.extend({ } if (results['records']) { - var lines_to_skip = parseInt(this.$element.find('#csv_skip').val(), 10), - with_headers = this.$element.find('#file_has_headers').prop('checked'); + var lines_to_skip = parseInt(this.$el.find('#csv_skip').val(), 10), + with_headers = this.$el.find('#file_has_headers').prop('checked'); headers = with_headers ? results.records[0] : null; result_node.append(QWeb.render('ImportView.result', { @@ -224,17 +224,17 @@ instance.web.DataImport = instance.web.Dialog.extend({ : with_headers ? results.records.slice(1) : results.records })); - this.$element.find('fieldset').addClass('oe_closed'); + this.$el.find('fieldset').addClass('oe_closed'); } - this.$element.find('form').removeClass('oe_import_no_result'); + this.$el.find('form').removeClass('oe_import_no_result'); - this.$element.delegate('.oe_m2o_drop_down_button', 'click', function () { + this.$el.delegate('.oe_m2o_drop_down_button', 'click', function () { $(this).prev('input').focus(); }); var self = this; this.ready.then(function () { - var $fields = self.$element.find('.sel_fields').bind('blur', function () { + var $fields = self.$el.find('.sel_fields').bind('blur', function () { if (this.value && !_(self.all_fields).contains(this.value)) { this.value = ''; } @@ -315,9 +315,9 @@ instance.web.DataImport = instance.web.Dialog.extend({ find_duplicate_fields: function() { // Maps values to DOM nodes, in order to discover duplicates var values = {}, duplicates = {}; - this.$element.find(".sel_fields").each(function(index, element) { + this.$el.find(".sel_fields").each(function(index, element) { var value = element.value; - var $element = $(element).removeClass('duplicate_fld'); + var $el = $(element).removeClass('duplicate_fld'); if (!value) { return; } if (!(value in values)) { @@ -329,13 +329,13 @@ instance.web.DataImport = instance.web.Dialog.extend({ } else { duplicates[value] = [same_valued_field, element]; } - $element.add(same_valued_field).addClass('duplicate_fld'); + $el.add(same_valued_field).addClass('duplicate_fld'); } }); return duplicates; }, on_check_field_values: function () { - this.$element.find("#message, #msg").remove(); + this.$el.find("#message, #msg").remove(); var required_valid = this.check_required(); @@ -343,7 +343,7 @@ instance.web.DataImport = instance.web.Dialog.extend({ if (_.isEmpty(duplicates)) { this.toggle_import_button(required_valid); } else { - var $err = $('<div id="msg" style="color: red;">'+_t("Destination fields should only be selected once, some fields are selected more than once:")+'</div>').insertBefore(this.$element.find('#result')); + var $err = $('<div id="msg" style="color: red;">'+_t("Destination fields should only be selected once, some fields are selected more than once:")+'</div>').insertBefore(this.$el.find('#result')); var $dupes = $('<dl>').appendTo($err); _(duplicates).each(function(elements, value) { $('<dt>').text(value).appendTo($dupes); @@ -372,7 +372,7 @@ instance.web.DataImport = instance.web.Dialog.extend({ return f.id; }; - var selected_fields = _(this.$element.find('.sel_fields').get()).chain() + var selected_fields = _(this.$el.find('.sel_fields').get()).chain() .pluck('value') .compact() .map(resolve_field_id) @@ -380,13 +380,13 @@ instance.web.DataImport = instance.web.Dialog.extend({ var missing_fields = _.difference(this.required_fields, selected_fields); if (missing_fields.length) { - this.$element.find("#result").before('<div id="message" style="color:red">' + _t("*Required Fields are not selected :") + missing_fields + '.</div>'); + this.$el.find("#result").before('<div id="message" style="color:red">' + _t("*Required Fields are not selected :") + missing_fields + '.</div>'); return false; } return true; }, destroy: function() { - this.$element.remove(); + this.$el.remove(); this._super(); } }); diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js index a7625631aa5..8e9a31922b8 100644 --- a/addons/web/static/src/js/search.js +++ b/addons/web/static/src/js/search.js @@ -126,21 +126,21 @@ my.InputView = instance.web.Widget.extend({ template: 'SearchView.InputView', start: function () { var p = this._super.apply(this, arguments); - this.$element.on('focus', this.proxy('onFocus')); - this.$element.on('blur', this.proxy('onBlur')); - this.$element.on('keydown', this.proxy('onKeydown')); + this.$el.on('focus', this.proxy('onFocus')); + this.$el.on('blur', this.proxy('onBlur')); + this.$el.on('keydown', this.proxy('onKeydown')); return p; }, onFocus: function () { this.trigger('focused', this); }, onBlur: function () { - this.$element.text(''); + this.$el.text(''); this.trigger('blurred', this); }, getSelection: function () { // get Text node - var root = this.$element[0].childNodes[0]; + var root = this.$el[0].childNodes[0]; if (!root || !root.textContent) { // if input does not have a child node, or the child node is an // empty string, then the selection can only be (0, 0) @@ -202,7 +202,7 @@ my.InputView = instance.web.Widget.extend({ break; case $.ui.keyCode.RIGHT: sel = this.getSelection(); - var len = this.$element.text().length; + var len = this.$el.text().length; if (sel.start !== len || sel.start !== sel.end) { e.stopPropagation(); } @@ -223,17 +223,17 @@ my.FacetView = instance.web.Widget.extend({ }, start: function () { var self = this; - this.$element.on('focus', function () { self.trigger('focused', self); }); - this.$element.on('blur', function () { self.trigger('blurred', self); }); - this.$element.on('click', function (e) { + this.$el.on('focus', function () { self.trigger('focused', self); }); + this.$el.on('blur', function () { self.trigger('blurred', self); }); + this.$el.on('click', function (e) { if ($(e.target).is('.oe_facet_remove')) { self.model.destroy(); return false; } - self.$element.focus(); + self.$el.focus(); e.stopPropagation(); }); - this.$element.on('keydown', function (e) { + this.$el.on('keydown', function (e) { var keys = $.ui.keyCode; switch (e.which) { case keys.BACKSPACE: @@ -242,7 +242,7 @@ my.FacetView = instance.web.Widget.extend({ return false; } }); - var $e = self.$element.find('> span:last-child'); + var $e = self.$el.find('> span:last-child'); var q = $.when(this._super()); return q.pipe(function () { var values = self.model.values.map(function (value) { @@ -253,7 +253,7 @@ my.FacetView = instance.web.Widget.extend({ }); }, model_changed: function () { - this.$element.text(this.$element.text() + '*'); + this.$el.text(this.$el.text() + '*'); } }); my.FacetValueView = instance.web.Widget.extend({ @@ -268,7 +268,7 @@ my.FacetValueView = instance.web.Widget.extend({ this._super(); }, model_changed: function () { - this.$element.text(this.$element.text() + '*'); + this.$el.text(this.$el.text() + '*'); } }); @@ -313,7 +313,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea .on('add change reset remove', this.proxy('renderFacets')); if (this.hidden) { - this.$element.hide(); + this.$el.hide(); } if (this.headless) { this.ready.resolve(); @@ -331,12 +331,12 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea } // Launch a search on clicking the oe_searchview_search button - this.$element.on('click', 'button.oe_searchview_search', function (e) { + this.$el.on('click', 'button.oe_searchview_search', function (e) { e.stopImmediatePropagation(); self.do_search(); }); - this.$element.on('keydown', + this.$el.on('keydown', '.oe_searchview_input, .oe_searchview_facet', function (e) { switch(e.which) { case $.ui.keyCode.LEFT: @@ -350,31 +350,31 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea } }); - this.$element.on('click', '.oe_searchview_clear', function (e) { + this.$el.on('click', '.oe_searchview_clear', function (e) { e.stopImmediatePropagation(); self.query.reset(); }); - this.$element.on('click', '.oe_searchview_unfold_drawer', function (e) { + this.$el.on('click', '.oe_searchview_unfold_drawer', function (e) { e.stopImmediatePropagation(); - self.$element.toggleClass('oe_searchview_open_drawer'); + self.$el.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'); + self.$el.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) { - if (e.target === self.$element.find('.oe_searchview_facets')[0]) { - self.$element.find('.oe_searchview_input:last').focus(); + this.$el.on('click', function (e) { + if (e.target === self.$el.find('.oe_searchview_facets')[0]) { + self.$el.find('.oe_searchview_input:last').focus(); } }); // when the completion list opens/refreshes, automatically select the // first completion item so if the user just hits [RETURN] or [TAB] it // automatically selects it - this.$element.on('autocompleteopen', function () { - var menu = self.$element.data('autocomplete').menu; + this.$el.on('autocompleteopen', function () { + var menu = self.$el.data('autocomplete').menu; menu.activate( $.Event({ type: "mouseenter" }), menu.element.children().first()); @@ -383,15 +383,15 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea return $.when(p, this.ready); }, show: function () { - this.$element.show(); + this.$el.show(); }, hide: function () { - this.$element.hide(); + this.$el.hide(); }, subviewForRoot: function (subview_root) { return _(this.input_subviews).detect(function (subview) { - return subview.$element[0] === subview_root; + return subview.$el[0] === subview_root; }); }, siblingSubview: function (subview, direction, wrap_around) { @@ -406,12 +406,12 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea focusPreceding: function (subview_root) { return this.siblingSubview( this.subviewForRoot(subview_root), -1, true) - .$element.focus(); + .$el.focus(); }, focusFollowing: function (subview_root) { return this.siblingSubview( this.subviewForRoot(subview_root), +1, true) - .$element.focus(); + .$el.focus(); }, /** @@ -430,19 +430,19 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea // autocomplete only correctly handles being initialized on the actual // editable element (and only an element with a @value in 1.8 e.g. - // input or textarea), cheat by setting val() on $element - this.$element.on('keydown', function () { + // input or textarea), cheat by setting val() on $el + this.$el.on('keydown', function () { // keydown is triggered *before* the element's value is set, so // delay this. Pray that setTimeout are executed in FIFO (if they // have the same delay) as autocomplete uses the exact same trick. // FIXME: brittle as fuck setTimeout(function () { - self.$element.val(self.currentInputValue()); + self.$el.val(self.currentInputValue()); }, 0); }); - this.$element.autocomplete({ + this.$el.autocomplete({ source: this.proxy('complete_global_search'), select: this.proxy('select_completion'), focus: function (e) { e.preventDefault(); }, @@ -479,7 +479,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea * div[contenteditable].oe_searchview_input) */ currentInputValue: function () { - return this.$element.find('div.oe_searchview_input:focus').text(); + return this.$el.find('div.oe_searchview_input:focus').text(); }, /** * Provide auto-completion result for req.term (an array to `resp`) @@ -509,22 +509,22 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea var input_index = _(this.input_subviews).indexOf( this.subviewForRoot( - this.$element.find('div.oe_searchview_input:focus')[0])); + this.$el.find('div.oe_searchview_input:focus')[0])); this.query.add(ui.item.facet, {at: input_index / 2}); }, childFocused: function () { - this.$element.addClass('oe_focused'); + this.$el.addClass('oe_focused'); }, childBlurred: function () { - var val = this.$element.val(); - this.$element.val(''); - var complete = this.$element.data('autocomplete'); + var val = this.$el.val(); + this.$el.val(''); + var complete = this.$el.data('autocomplete'); if ((val && complete.term === undefined) || complete.previous !== undefined) { throw new Error("new jquery.ui version altering implementation" + " details relied on"); } delete complete.term; - this.$element.removeClass('oe_focused') + this.$el.removeClass('oe_focused') .trigger('blur'); }, /** @@ -538,7 +538,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea // _2: undefined if event=change, otherwise model var self = this; var started = []; - var $e = this.$element.find('div.oe_searchview_facets'); + var $e = this.$el.find('div.oe_searchview_facets'); _.invoke(this.input_subviews, 'destroy'); this.input_subviews = []; @@ -569,7 +569,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea input_to_focus = self.input_subviews[(options.at + 1) * 2]; } - input_to_focus.$element.focus(); + input_to_focus.$el.focus(); }); }, @@ -664,7 +664,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea // build drawer var drawer_started = $.when.apply( null, _(this.select_for_drawer()).invoke( - 'appendTo', this.$element.find('.oe_searchview_drawer'))); + 'appendTo', this.$el.find('.oe_searchview_drawer'))); // load defaults var defaults_fetched = $.when.apply(null, _(this.inputs).invoke( @@ -680,7 +680,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea */ on_filters_management: function(e) { var self = this; - var select = this.$element.find(".oe_search-view-filters-management"); + var select = this.$el.find(".oe_search-view-filters-management"); var val = select.val(); switch(val) { case 'advanced_filter': @@ -989,7 +989,7 @@ instance.web.search.FilterGroup = instance.web.search.Input.extend(/** @lends in this.view.query.on('add remove change reset', this.proxy('search_change')); }, start: function () { - this.$element.on('click', 'li', this.proxy('toggle_filter')); + this.$el.on('click', 'li', this.proxy('toggle_filter')); return $.when(null); }, /** @@ -998,7 +998,7 @@ instance.web.search.FilterGroup = instance.web.search.Input.extend(/** @lends in */ search_change: function () { var self = this; - var $filters = this.$element.find('> li').removeClass('oe_selected'); + var $filters = this.$el.find('> li').removeClass('oe_selected'); var facet = this.view.query.find(_.bind(this.match_facet, this)); if (!facet) { return; } facet.values.each(function (v) { @@ -1299,17 +1299,17 @@ instance.web.search.CharField = instance.web.search.Field.extend( /** @lends ins }); instance.web.search.NumberField = instance.web.search.Field.extend(/** @lends instance.web.search.NumberField# */{ value_from: function () { - if (!this.$element.val()) { + if (!this.$el.val()) { return null; } - var val = this.parse(this.$element.val()), - check = Number(this.$element.val()); + var val = this.parse(this.$el.val()), + check = Number(this.$el.val()); if (isNaN(val) || val !== check) { - this.$element.addClass('error'); + this.$el.addClass('error'); throw new instance.web.search.Invalid( - this.attrs.name, this.$element.val(), this.error_message); + this.attrs.name, this.$el.val(), this.error_message); } - this.$element.removeClass('error'); + this.$el.removeClass('error'); return val; } }); @@ -1542,9 +1542,9 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({ 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'); + this.$el.on('submit', 'form', this.proxy('save_current')); + this.$el.on('click', 'h4', function () { + self.$el.toggleClass('oe_opened'); }); // FIXME: local eval of domain and context to get rid of special endpoint return this.rpc('/web/searchview/get_filters', { @@ -1552,7 +1552,7 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({ }).pipe(this.proxy('set_filters')); }, clear_selection: function () { - this.$element.find('li.oe_selected').removeClass('oe_selected'); + this.$el.find('li.oe_selected').removeClass('oe_selected'); }, append_filter: function (filter) { var self = this; @@ -1564,7 +1564,7 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({ } else { var id = filter.id; $filter = this.filters[key] = $('<li></li>') - .appendTo(this.$element.find('.oe_searchview_custom_list')) + .appendTo(this.$el.find('.oe_searchview_custom_list')) .addClass(filter.user_id ? 'oe_searchview_custom_private' : 'oe_searchview_custom_public') .text(filter.name); @@ -1599,8 +1599,8 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({ }, save_current: function () { var self = this; - var $name = this.$element.find('input:first'); - var private_filter = !this.$element.find('input:last').prop('checked'); + var $name = this.$el.find('input:first'); + var private_filter = !this.$el.find('input:last').prop('checked'); var search = this.view.build_search_data(); this.rpc('/web/session/eval_domain_and_context', { @@ -1622,7 +1622,7 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({ return self.model.call('create_or_replace', [filter]).then(function (id) { filter.id = id; self.append_filter(filter); - self.$element + self.$el .removeClass('oe_opened') .find('form')[0].reset(); }); @@ -1667,8 +1667,8 @@ instance.web.search.Filters = instance.web.search.Input.extend({ } return $.when( - this.render_column(col1, $('<div>').appendTo(this.$element)), - this.render_column(col2, $('<div>').appendTo(this.$element))); + this.render_column(col1, $('<div>').appendTo(this.$el)), + this.render_column(col2, $('<div>').appendTo(this.$el))); }, render_column: function (column, $el) { return $.when.apply(null, _(column).map(function (group) { @@ -1684,10 +1684,10 @@ instance.web.search.Advanced = instance.web.search.Input.extend({ _in_drawer: true, start: function () { var self = this; - this.$element + this.$el .on('keypress keydown keyup', function (e) { e.stopPropagation(); }) .on('click', 'h4', function () { - self.$element.toggleClass('oe_opened'); + self.$el.toggleClass('oe_opened'); }).on('click', 'button.oe_add_condition', function () { self.append_proposition(); }).on('submit', 'form', function (e) { @@ -1706,7 +1706,7 @@ instance.web.search.Advanced = instance.web.search.Input.extend({ }, append_proposition: function () { return (new instance.web.search.ExtendedSearchProposition(this, this.fields)) - .appendTo(this.$element.find('ul')); + .appendTo(this.$el.find('ul')); }, commit_search: function () { var self = this; @@ -1733,7 +1733,7 @@ instance.web.search.Advanced = instance.web.search.Input.extend({ // add new empty proposition this.append_proposition(); // TODO: API on searchview - this.view.$element.removeClass('oe_searchview_open_drawer'); + this.view.$el.removeClass('oe_searchview_open_drawer'); } }); @@ -1757,16 +1757,16 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @ }, start: function () { var _this = this; - this.$element.find(".searchview_extended_prop_field").change(function() { + this.$el.find(".searchview_extended_prop_field").change(function() { _this.changed(); }); - this.$element.find('.searchview_extended_delete_prop').click(function () { + this.$el.find('.searchview_extended_delete_prop').click(function () { _this.destroy(); }); this.changed(); }, changed: function() { - var nval = this.$element.find(".searchview_extended_prop_field").val(); + var nval = this.$el.find(".searchview_extended_prop_field").val(); if(this.attrs.selected == null || nval != this.attrs.selected.name) { this.select_field(_.detect(this.fields, function(x) {return x.name == nval;})); } @@ -1781,7 +1781,7 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @ if(this.attrs.selected != null) { this.value.destroy(); this.value = null; - this.$element.find('.searchview_extended_prop_op').html(''); + this.$el.find('.searchview_extended_prop_op').html(''); } this.attrs.selected = field; if(field == null) { @@ -1797,9 +1797,9 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @ _.each(this.value.operators, function(operator) { $('<option>', {value: operator.value}) .text(String(operator.text)) - .appendTo(self.$element.find('.searchview_extended_prop_op')); + .appendTo(self.$el.find('.searchview_extended_prop_op')); }); - var $value_loc = this.$element.find('.searchview_extended_prop_value').empty(); + var $value_loc = this.$el.find('.searchview_extended_prop_value').empty(); this.value.appendTo($value_loc); }, @@ -1807,7 +1807,7 @@ instance.web.search.ExtendedSearchProposition = instance.web.Widget.extend(/** @ if ( this.attrs.selected == null) return null; var field = this.attrs.selected; - var op = this.$element.find('.searchview_extended_prop_op')[0]; + var op = this.$el.find('.searchview_extended_prop_op')[0]; var operator = op.options[op.selectedIndex]; return { label: _.str.sprintf(_t('%(field)s %(operator)s "%(value)s"'), { @@ -1851,7 +1851,7 @@ instance.web.search.ExtendedSearchProposition.Char = instance.web.search.Extende {value: "!=", text: _lt("is not equal to")} ], get_value: function() { - return this.$element.val(); + return this.$el.val(); } }); instance.web.search.ExtendedSearchProposition.DateTime = instance.web.search.ExtendedSearchProposition.Field.extend({ @@ -1875,7 +1875,7 @@ instance.web.search.ExtendedSearchProposition.DateTime = instance.web.search.Ext start: function() { var ready = this._super(); this.datewidget = new (this.widget())(this); - this.datewidget.appendTo(this.$element); + this.datewidget.appendTo(this.$el); return ready; } }); @@ -1893,11 +1893,11 @@ instance.web.search.ExtendedSearchProposition.Integer = instance.web.search.Exte {value: "<=", text: _lt("less or equal than")} ], toString: function () { - return this.$element.val(); + return this.$el.val(); }, get_value: function() { try { - return instance.web.parse_value(this.$element.val(), {'widget': 'integer'}); + return instance.web.parse_value(this.$el.val(), {'widget': 'integer'}); } catch (e) { return ""; } @@ -1917,11 +1917,11 @@ instance.web.search.ExtendedSearchProposition.Float = instance.web.search.Extend {value: "<=", text: _lt("less or equal than")} ], toString: function () { - return this.$element.val(); + return this.$el.val(); }, get_value: function() { try { - return instance.web.parse_value(this.$element.val(), {'widget': 'float'}); + return instance.web.parse_value(this.$el.val(), {'widget': 'float'}); } catch (e) { return ""; } @@ -1934,12 +1934,12 @@ instance.web.search.ExtendedSearchProposition.Selection = instance.web.search.Ex {value: "!=", text: _lt("is not")} ], toString: function () { - var select = this.$element[0]; + var select = this.$el[0]; var option = select.options[select.selectedIndex]; return option.label || option.text; }, get_value: function() { - return this.$element.val(); + return this.$el.val(); } }); instance.web.search.ExtendedSearchProposition.Boolean = instance.web.search.ExtendedSearchProposition.Field.extend({ diff --git a/addons/web/static/src/js/test_support.js b/addons/web/static/src/js/test_support.js index 314a12c91c6..8e1317ba2b0 100644 --- a/addons/web/static/src/js/test_support.js +++ b/addons/web/static/src/js/test_support.js @@ -12,7 +12,6 @@ openerp.test_support = { username: false, user_context: {}, db: false, - openerp_entreprise: false, // this.module_list = openerp._modules.slice(); // this.module_loaded = {}; // _(this.module_list).each(function (mod) { diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index b8c9acfef49..f65da67d8fb 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -23,10 +23,6 @@ instance.web.form.FieldManagerMixin = { */ get_field: function(field_name) {}, /** - * Called by the field when the translate button is clicked. - */ - open_translate_dialog: function(field) {}, - /** * Returns true when the view is in create mode. */ is_create_mode: function() {}, @@ -102,8 +98,8 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM w.off('focused blurred'); w.destroy(); }); - if (this.$element) { - this.$element.off('.formBlur'); + if (this.$el) { + this.$el.off('.formBlur'); } this._super(); }, @@ -122,11 +118,11 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM this.rendering_engine.set_tags_registry(this.tags_registry); if (!this.extract_qweb_template(data)) { this.rendering_engine.set_fields_view(data); - var $dest = this.$element.hasClass("oe_form_container") ? this.$element : this.$element.find('.oe_form_container'); + var $dest = this.$el.hasClass("oe_form_container") ? this.$el : this.$el.find('.oe_form_container'); this.rendering_engine.render_to($dest); } - this.$element.on('mousedown.formBlur', function () { + this.$el.on('mousedown.formBlur', function () { self.__clicked_inside = true; }); @@ -134,31 +130,31 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM if (this.options.$buttons) { this.$buttons.appendTo(this.options.$buttons); } else { - this.$element.find('.oe_form_buttons').replaceWith(this.$buttons); + this.$el.find('.oe_form_buttons').replaceWith(this.$buttons); } this.$buttons.on('click','.oe_form_button_create',this.on_button_create); this.$buttons.on('click','.oe_form_button_edit',this.on_button_edit); this.$buttons.on('click','.oe_form_button_save',this.on_button_save); this.$buttons.on('click','.oe_form_button_cancel',this.on_button_cancel); - this.$sidebar = this.options.$sidebar || this.$element.find('.oe_form_sidebar'); + this.$sidebar = this.options.$sidebar || this.$el.find('.oe_form_sidebar'); if (!this.sidebar && this.options.$sidebar) { this.sidebar = new instance.web.Sidebar(this); this.sidebar.appendTo(this.$sidebar); - if(this.fields_view.toolbar) { + if (this.fields_view.toolbar) { this.sidebar.add_toolbar(this.fields_view.toolbar); } - this.sidebar.add_items('other', [ - { label: _t('Delete'), callback: self.on_button_delete }, - { label: _t('Duplicate'), callback: self.on_button_duplicate }, + 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(); } } - ]); + ])); } this.has_been_loaded.resolve(); // Add bounce effect on button 'Edit' when click on readonly page view. - this.$element.find(".oe_form_field,label").on('click', function (e) { + this.$el.find(".oe_form_field,label").on('click', function (e) { if(self.get("actual_mode") == "view") { var $button = self.options.$buttons.find(".oe_form_button_edit"); $button.effect('bounce', {distance: 18, times: 5}, 150) @@ -215,7 +211,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM this.default_focus_field = null; this.default_focus_button = null; this.translatable_fields = []; - this.$element.find('.oe_form_container').empty(); + this.$el.find('.oe_form_container').empty(); }, widgetFocused: function() { @@ -263,7 +259,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM var self = this; options = options || {}; if (this.sidebar) { - this.sidebar.$element.show(); + this.sidebar.$el.show(); } if (this.$buttons) { this.$buttons.show(); @@ -271,11 +267,11 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM if (this.$pager) { this.$pager.show(); } - this.$element.show().css({ + this.$el.show().css({ opacity: '0', filter: 'alpha(opacity = 0)' }); - this.$element.add(this.$buttons).removeClass('oe_form_dirty'); + this.$el.add(this.$buttons).removeClass('oe_form_dirty'); var shown = this.has_been_loaded; if (options.reload !== false) { @@ -293,7 +289,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM } return shown.pipe(function() { self._actualize_mode(options.mode || self.options.initial_mode); - self.$element.css({ + self.$el.css({ opacity: '1', filter: 'alpha(opacity = 100)' }); @@ -301,7 +297,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM }, do_hide: function () { if (this.sidebar) { - this.sidebar.$element.hide(); + this.sidebar.$el.hide(); } if (this.$buttons) { this.$buttons.hide(); @@ -325,7 +321,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM if (this.qweb) { this.kill_current_form(); this.rendering_engine.set_fields_view(this.get_fvg_from_qweb(record)); - var $dest = this.$element.hasClass("oe_form_container") ? this.$element : this.$element.find('.oe_form_container'); + var $dest = this.$el.hasClass("oe_form_container") ? this.$el : this.$el.find('.oe_form_container'); this.rendering_engine.render_to($dest); } @@ -357,7 +353,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM } else { self.do_push_state({}); } - self.$element.add(self.$buttons).removeClass('oe_form_dirty'); + self.$el.add(self.$buttons).removeClass('oe_form_dirty'); self.autofocus(); }); }, @@ -379,7 +375,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM this.trigger("view_content_has_changed"); }, do_notify_change: function() { - this.$element.add(this.$buttons).addClass('oe_form_dirty'); + this.$el.add(this.$buttons).addClass('oe_form_dirty'); }, on_pager_action: function(action) { if (this.can_be_discarded()) { @@ -410,7 +406,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM if (this.options.$pager) { this.$pager.appendTo(this.options.$pager); } else { - this.$element.find('.oe_form_pager').replaceWith(this.$pager); + this.$el.find('.oe_form_pager').replaceWith(this.$pager); } this.$pager.on('click','a[data-pager-action]',function() { var action = $(this).data('pager-action'); @@ -653,7 +649,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM check_actual_mode: function(source, options) { var self = this; if(this.get("actual_mode") === "view") { - self.$element.removeClass('oe_form_editable').addClass('oe_form_readonly'); + self.$el.removeClass('oe_form_editable').addClass('oe_form_readonly'); self.$buttons.find('.oe_form_buttons_edit').hide(); self.$buttons.find('.oe_form_buttons_view').show(); self.$sidebar.show(); @@ -661,7 +657,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM field.set({"force_readonly": true}); }); } else { - self.$element.removeClass('oe_form_readonly').addClass('oe_form_editable'); + self.$el.removeClass('oe_form_readonly').addClass('oe_form_editable'); self.$buttons.find('.oe_form_buttons_edit').show(); self.$buttons.find('.oe_form_buttons_view').hide(); self.$sidebar.hide(); @@ -689,7 +685,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM }, on_button_save: function() { var self = this; - return this.do_save().then(function(result) { + return this.do_save().then(function(result) { self.to_view_mode(); }); }, @@ -752,17 +748,18 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM return def.promise(); }, can_be_discarded: function() { - return !this.$element.is('.oe_form_dirty') || confirm(_t("Warning, the record has been modified, your changes will be discarded.")); + return !this.$el.is('.oe_form_dirty') || confirm(_t("Warning, the record has been modified, your changes will be discarded.")); }, /** * Triggers saving the form's record. Chooses between creating a new * record or saving an existing one depending on whether the record * already has an id property. * - * @param {Function} [success] callback on save success - * @param {Boolean} [prepend_on_create=false] if ``do_save`` creates a new record, should that record be inserted at the start of the dataset (by default, records are added at the end) + * @param {Boolean} [prepend_on_create=false] if ``do_save`` creates a new + * record, should that record be inserted at the start of the dataset (by + * default, records are added at the end) */ - do_save: function(success, prepend_on_create) { + do_save: function(prepend_on_create) { var self = this; return this.mutating_mutex.exec(function() { return self.is_initialized.pipe(function() { try { @@ -797,21 +794,21 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM self.set({'display_invalid_fields': false}); var save_deferral; if (!self.datarecord.id) { - // console.log("FormView(", self, ") : About to create", values); + // Creation save save_deferral = self.dataset.create(values).pipe(function(r) { - return self.on_created(r, undefined, prepend_on_create); + return self.on_created(r, prepend_on_create); }, null); } else if (_.isEmpty(values) && ! self.force_dirty) { - // console.log("FormView(", self, ") : Nothing to save"); + // Not dirty, noop save save_deferral = $.Deferred().resolve({}).promise(); } else { self.force_dirty = false; - // console.log("FormView(", self, ") : About to save", values); + // Write save save_deferral = self.dataset.write(self.datarecord.id, values, {}).pipe(function(r) { return self.on_saved(r); }, null); } - return save_deferral.then(success); + return save_deferral; } } catch (e) { console.error(e); @@ -830,14 +827,19 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM warnings.push('</ul>'); this.do_warn("The following fields are invalid :", warnings.join('')); }, - on_saved: function(r, success) { + /** + * Reload the form after saving + * + * @param {Object} r result of the write function. + */ + on_saved: function(r) { if (!r.result) { // should not happen in the server, but may happen for internal purpose return $.Deferred().reject(); } else { return $.when(this.reload()).pipe(function () { - return r; }) - .then(success); + return r; + }); } }, /** @@ -850,10 +852,10 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM * * Updates the pager and sidebar displays * * @param {Object} r - * @param {Function} success callback to execute after having updated the dataset - * @param {Boolean} [prepend_on_create=false] adds the newly created record at the beginning of the dataset instead of the end + * @param {Boolean} [prepend_on_create=false] adds the newly created record + * at the beginning of the dataset instead of the end */ - on_created: function(r, success, prepend_on_create) { + on_created: function(r, prepend_on_create) { if (!r.result) { // should not happen in the server, but may happen for internal purpose return $.Deferred().reject(); @@ -872,8 +874,8 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM } //openerp.log("The record has been created with id #" + this.datarecord.id); return $.when(this.reload()).pipe(function () { - return _.extend(r, {created: true}); }) - .then(success); + return _.extend(r, {created: true}); + }); } }, on_action: function (action) { @@ -993,14 +995,14 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM buttons: [ {text: _t("Close"), click: function () { d.close(); }}, {text: _t("Save default"), click: function () { - var $defaults = d.$element.find('#formview_default_fields'); + var $defaults = d.$el.find('#formview_default_fields'); var field_to_set = $defaults.val(); if (!field_to_set) { $defaults.parent().addClass('oe_form_invalid'); return; } - var condition = d.$element.find('#formview_default_conditions').val(), - all_users = d.$element.find('#formview_default_all').is(':checked'); + var condition = d.$el.find('#formview_default_conditions').val(), + all_users = d.$el.find('#formview_default_all').is(':checked'); new instance.web.DataSet(self, 'ir.values').call( 'set_default', [ self.dataset.model, @@ -1043,9 +1045,6 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM is_create_mode: function() { return this.get("actual_mode") === "create"; }, - open_translate_dialog: function(field) { - return this._super(field); - }, }); /** @@ -1054,7 +1053,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM instance.web.form.FormRenderingEngineInterface = instance.web.Class.extend({ set_fields_view: function(fields_view) {}, set_fields_registry: function(fields_registry) {}, - render_to: function($element) {}, + render_to: function($el) {}, }); /** @@ -1459,7 +1458,7 @@ instance.web.form.FormDialog = instance.web.Dialog.extend({ this.form = new instance.web.FormView(this, this.dataset, this.view_id, { pager: false }); - this.form.appendTo(this.$element); + this.form.appendTo(this.$el); this.form.on_created.add_last(this.on_form_dialog_saved); this.form.on_saved.add_last(this.on_form_dialog_saved); return this; @@ -1551,7 +1550,7 @@ instance.web.form.compute_domain = function(expr, fields) { /** * Must be applied over an class already possessing the PropertiesMixin. * - * Apply the result of the "invisible" domain to this.$element. + * Apply the result of the "invisible" domain to this.$el. */ instance.web.form.InvisibilityChangerMixin = { init: function(field_manager, invisible_domain) { @@ -1582,16 +1581,16 @@ instance.web.form.InvisibilityChangerMixin = { this._check_visibility(); }, _check_visibility: function() { - this.$element.toggleClass('oe_form_invisible', this.get("effective_invisible")); + this.$el.toggleClass('oe_form_invisible', this.get("effective_invisible")); }, }; instance.web.form.InvisibilityChanger = instance.web.Class.extend(instance.web.PropertiesMixin, instance.web.form.InvisibilityChangerMixin, { - init: function(parent, field_manager, invisible_domain, $element) { + init: function(parent, field_manager, invisible_domain, $el) { this.setParent(parent); instance.web.PropertiesMixin.init.call(this); instance.web.form.InvisibilityChangerMixin.init.call(this, field_manager, invisible_domain); - this.$element = $element; + this.$el = $el; this.start(); }, }); @@ -1615,7 +1614,7 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi }, renderElement: function() { this._super(); - this.$element.addClass(this.node.attrs["class"] || ""); + this.$el.addClass(this.node.attrs["class"] || ""); }, destroy: function() { $.fn.tipsy.clear(); @@ -1649,7 +1648,7 @@ instance.web.form.FormWidget = instance.web.Widget.extend(instance.web.form.Invi }, do_attach_tooltip: function(widget, trigger, options) { widget = widget || this; - trigger = trigger || this.$element; + trigger = trigger || this.$el; options = _.extend({ delayIn: 500, delayOut: 0, @@ -1736,11 +1735,11 @@ instance.web.form.WidgetButton = instance.web.form.FormWidget.extend({ }, start: function() { this._super.apply(this, arguments); - this.$element.click(this.on_click); + this.$el.click(this.on_click); if (this.node.attrs.help || instance.session.debug) { this.do_attach_tooltip(); } - this.setupFocus(this.$element); + this.setupFocus(this.$el); }, on_click: function() { var self = this; @@ -1799,8 +1798,8 @@ instance.web.form.WidgetButton = instance.web.form.FormWidget.extend({ }, check_disable: function() { var disabled = (this.force_disabled || !this.view.is_interactible_record()); - this.$element.prop('disabled', disabled); - this.$element.css('color', disabled ? 'grey' : ''); + this.$el.prop('disabled', disabled); + this.$el.css('color', disabled ? 'grey' : ''); } }); @@ -1876,6 +1875,10 @@ instance.web.form.FieldInterface = { * Must set the focus on the field. Return false if field is not focusable. */ focus: function() {}, + /** + * Called when the translate button is clicked. + */ + on_translate: function() {}, }; /** @@ -1929,14 +1932,12 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w var self = this; this._super(); if (this.field.translate) { - this.$element.addClass('oe_form_field_translatable'); - this.$element.find('.oe_field_translate').click(_.bind(function() { - this.field_manager.open_translate_dialog(this); - }, this)); + this.$el.addClass('oe_form_field_translatable'); + this.$el.find('.oe_field_translate').click(this.on_translate); } - this.$label = this.view.$element.find('label[for=' + this.id_for_label + ']'); + this.$label = this.view.$el.find('label[for=' + this.id_for_label + ']'); if (instance.session.debug) { - this.do_attach_tooltip(this, this.$label[0] || this.$element); + this.do_attach_tooltip(this, this.$label[0] || this.$el); this.$label.off('dblclick').on('dblclick', function() { console.log("Field '%s' of type '%s' in View: %o", self.name, (self.node.attrs.widget || self.field.type), self.view); window.w = self; @@ -1955,7 +1956,7 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w * Private. Do not use. */ _set_required: function() { - this.$element.toggleClass('oe_form_required', this.get("required")); + this.$el.toggleClass('oe_form_required', this.get("required")); }, set_value: function(value_) { this._inhibit_on_change = true; @@ -1980,11 +1981,11 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w }, _check_css_flags: function() { if (this.field.translate) { - this.$element.find('.oe_field_translate').toggle(!this.field_manager.is_create_mode()); + this.$el.find('.oe_field_translate').toggle(!this.field_manager.is_create_mode()); } if (!this.disable_utility_classes) { if (this.field_manager.get('display_invalid_fields')) { - this.$element.toggleClass('oe_form_invalid', !this.is_valid()); + this.$el.toggleClass('oe_form_invalid', !this.is_valid()); } } }, @@ -1994,6 +1995,13 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w set_input_id: function(id) { this.id_for_label = id; }, + on_translate: function() { + var self = this; + var trans = new instance.web.DataSet(this, 'ir.translation'); + return trans.call_button('translate_fields', [this.view.dataset.model, this.view.datarecord.id, this.name, this.view.dataset.get_context()]).then(function(r) { + self.do_action(r.result); + }); + }, }); /** @@ -2042,7 +2050,7 @@ instance.web.form.FieldChar = instance.web.form.AbstractField.extend(instance.we }, initialize_content: function() { var self = this; - var $input = this.$element.find('input'); + var $input = this.$el.find('input'); $input.change(function() { self.set({'value': instance.web.parse_value($input.val(), self)}); }); @@ -2055,18 +2063,18 @@ instance.web.form.FieldChar = instance.web.form.AbstractField.extend(instance.we render_value: function() { var show_value = instance.web.format_value(this.get('value'), this, ''); if (!this.get("effective_readonly")) { - this.$element.find('input').val(show_value); + this.$el.find('input').val(show_value); } else { if (this.password) { show_value = new Array(show_value.length + 1).join('*'); } - this.$element.text(show_value); + this.$el.text(show_value); } }, is_syntax_valid: function() { if (!this.get("effective_readonly")) { try { - var value_ = instance.web.parse_value(this.$element.find('input').val(), this, ''); + var value_ = instance.web.parse_value(this.$el.find('input').val(), this, ''); return true; } catch(e) { return false; @@ -2090,7 +2098,7 @@ instance.web.form.FieldEmail = instance.web.form.FieldChar.extend({ template: 'FieldEmail', initialize_content: function() { this._super(); - var $button = this.$element.find('button'); + var $button = this.$el.find('button'); $button.click(this.on_button_clicked); this.setupFocus($button); }, @@ -2098,7 +2106,7 @@ instance.web.form.FieldEmail = instance.web.form.FieldChar.extend({ if (!this.get("effective_readonly")) { this._super(); } else { - this.$element.find('a') + this.$el.find('a') .attr('href', 'mailto:' + this.get('value')) .text(this.get('value') || ''); } @@ -2116,7 +2124,7 @@ instance.web.form.FieldUrl = instance.web.form.FieldChar.extend({ template: 'FieldUrl', initialize_content: function() { this._super(); - var $button = this.$element.find('button'); + var $button = this.$el.find('button'); $button.click(this.on_button_clicked); this.setupFocus($button); }, @@ -2129,7 +2137,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(this.get('value') ? tmp : ''); + this.$el.find('a').attr('href', tmp).text(this.get('value') ? tmp : ''); } }, on_button_clicked: function() { @@ -2178,8 +2186,8 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({ }, start: function() { var self = this; - this.$input = this.$element.find('input.oe_datepicker_master'); - this.$input_picker = this.$element.find('input.oe_datepicker_container'); + this.$input = this.$el.find('input.oe_datepicker_master'); + this.$input_picker = this.$el.find('input.oe_datepicker_container'); this.$input.change(this.on_change); this.picker({ onClose: this.on_picker_select, @@ -2187,9 +2195,10 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({ changeMonth: true, changeYear: true, showWeek: true, - showButtonPanel: true + showButtonPanel: true, + firstDay: Date.CultureInfo.firstDayOfWeek }); - this.$element.find('img.oe_datepicker_trigger').click(function() { + this.$el.find('img.oe_datepicker_trigger').click(function() { if (self.get("effective_readonly") || self.picker('widget').is(':visible')) { self.$input.focus(); return; @@ -2226,7 +2235,7 @@ instance.web.DateTimeWidget = instance.web.Widget.extend({ set_readonly: function(readonly) { this.readonly = readonly; this.$input.prop('readonly', this.readonly); - this.$element.find('img.oe_datepicker_trigger').toggleClass('oe_input_icon_disabled', readonly); + this.$el.find('img.oe_datepicker_trigger').toggleClass('oe_input_icon_disabled', readonly); }, is_valid_: function() { var value_ = this.$input.val(); @@ -2276,7 +2285,7 @@ instance.web.form.FieldDatetime = instance.web.form.AbstractField.extend(instanc this.datewidget.on_change.add_last(_.bind(function() { this.set({'value': this.datewidget.get_value()}); }, this)); - this.datewidget.appendTo(this.$element); + this.datewidget.appendTo(this.$el); this.setupFocus(this.datewidget.$input); } }, @@ -2288,7 +2297,7 @@ instance.web.form.FieldDatetime = instance.web.form.AbstractField.extend(instanc if (!this.get("effective_readonly")) { this.datewidget.set_value(this.get('value')); } else { - this.$element.text(instance.web.format_value(this.get('value'), this, '')); + this.$el.text(instance.web.format_value(this.get('value'), this, '')); } }, is_syntax_valid: function() { @@ -2316,16 +2325,21 @@ instance.web.form.FieldDate = instance.web.form.FieldDatetime.extend({ instance.web.form.FieldText = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, { template: 'FieldText', + init: function (field_manager, node) { + this._super(field_manager, node); + }, initialize_content: function() { - this.$textarea = this.$element.find('textarea'); + var self = this; + this.$textarea = this.$el.find('textarea'); + this.default_height = this.$textarea.css('height'); if (!this.get("effective_readonly")) { this.$textarea.change(_.bind(function() { - this.set({'value': instance.web.parse_value(this.$textarea.val(), this)}); + self.set({'value': instance.web.parse_value(self.$textarea.val(), self)}); }, this)); } else { this.$textarea.attr('disabled', 'disabled'); } - this.$element.keyup(function (e) { + this.$el.keyup(function (e) { if (e.which === $.ui.keyCode.ENTER) { e.stopPropagation(); } @@ -2333,15 +2347,17 @@ instance.web.form.FieldText = instance.web.form.AbstractField.extend(instance.we this.setupFocus(this.$textarea); }, set_value: function(value_) { - this._super.apply(this, arguments); + this._super(value_); this.render_value(); + $(window).resize(); }, render_value: function() { var show_value = instance.web.format_value(this.get('value'), this, ''); - this.$textarea.val(show_value); - if (show_value && this.view.options.resize_textareas) { - this.do_resize(this.view.options.resize_textareas); + if (show_value === '') { + this.$textarea.css('height', parseInt(this.default_height)+"px"); } + this.$textarea.val(show_value); + this.$textarea.autosize(); }, is_syntax_valid: function() { if (!this.get("effective_readonly")) { @@ -2357,29 +2373,9 @@ instance.web.form.FieldText = instance.web.form.AbstractField.extend(instance.we is_false: function() { return this.get('value') === '' || this._super(); }, - focus: function($element) { + focus: function($el) { this.$textarea.focus(); }, - do_resize: function(max_height) { - max_height = parseInt(max_height, 10); - var $input = this.$textarea, - $div = $('<div style="position: absolute; z-index: 1000; top: 0"/>').width($input.width()), - new_height; - $div.text($input.val()); - _.each('font-family,font-size,white-space'.split(','), function(style) { - $div.css(style, $input.css(style)); - }); - $div.appendTo($('body')); - new_height = $div.height(); - if (new_height < 90) { - new_height = 90; - } - if (!isNaN(max_height) && new_height > max_height) { - new_height = max_height; - } - $div.remove(); - $input.height(new_height); - }, }); /** @@ -2391,20 +2387,13 @@ instance.web.form.FieldText = instance.web.form.AbstractField.extend(instance.we */ instance.web.form.FieldTextHtml = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, { template: 'FieldTextHtml', - init: function() { - this._super.apply(this, arguments); - if (this.field.type !== 'html') { - throw new Error(_.str.sprintf( - _t("Error with field %s, it is not allowed to use the widget 'html' with any other field type than 'html'"), this.string)); - } - }, initialize_content: function() { var self = this; if (! this.get("effective_readonly")) { self._updating_editor = false; - this.$textarea = this.$element.find('textarea'); + this.$textarea = this.$el.find('textarea'); var width = ((this.node.attrs || {}).editor_width || 468); - var height = ((this.node.attrs || {}).editor_height || 100); + var height = ((this.node.attrs || {}).editor_height || 250); this.$textarea.cleditor({ width: width, // width not including margins, borders or padding height: height, // height not including margins, borders or padding @@ -2435,7 +2424,7 @@ instance.web.form.FieldTextHtml = instance.web.form.AbstractField.extend(instanc this.$cleditor.updateFrame(); this._updating_editor = false; } else { - this.$element.html(this.get('value')); + this.$el.html(this.get('value')); } }, }); @@ -2445,9 +2434,9 @@ instance.web.form.FieldBoolean = instance.web.form.AbstractField.extend({ start: function() { var self = this; this._super.apply(this, arguments); - this.$checkbox = $("input", this.$element); + this.$checkbox = $("input", this.$el); this.setupFocus(this.$checkbox); - this.$element.click(_.bind(function() { + this.$el.click(_.bind(function() { this.set({'value': this.$checkbox.is(':checked')}); }, this)); var check_readonly = function() { @@ -2469,7 +2458,7 @@ instance.web.form.FieldProgressBar = instance.web.form.AbstractField.extend({ template: 'FieldProgressBar', start: function() { this._super.apply(this, arguments); - this.$element.progressbar({ + this.$el.progressbar({ value: this.get('value'), disabled: this.get("effective_readonly") }); @@ -2481,7 +2470,7 @@ instance.web.form.FieldProgressBar = instance.web.form.AbstractField.extend({ show_value = 0; } var formatted_value = instance.web.format_value(show_value, { type : 'float' }, '0'); - this.$element.progressbar('option', 'value', show_value).find('span').html(formatted_value + '%'); + this.$el.progressbar('option', 'value', show_value).find('span').html(formatted_value + '%'); } }); @@ -2512,9 +2501,9 @@ instance.web.form.FieldSelection = instance.web.form.AbstractField.extend(instan // changing the selected value), takes the action as validating the // row var ischanging = false; - var $select = this.$element.find('select') + var $select = this.$el.find('select') .change(_.bind(function() { - this.set({'value': this.values[this.$element.find('select')[0].selectedIndex][0]}); + this.set({'value': this.values[this.$el.find('select')[0].selectedIndex][0]}); }, this)) .change(function () { ischanging = true; }) .click(function () { ischanging = false; }) @@ -2537,27 +2526,27 @@ instance.web.form.FieldSelection = instance.web.form.AbstractField.extend(instan for (var i = 0, ii = this.values.length; i < ii; i++) { if (this.values[i][0] === this.get('value')) index = i; } - this.$element.find('select')[0].selectedIndex = index; + this.$el.find('select')[0].selectedIndex = index; } else { var self = this; var option = _(this.values) .detect(function (record) { return record[0] === self.get('value'); }); - this.$element.text(option ? option[1] : this.values[0][1]); + this.$el.text(option ? option[1] : this.values[0][1]); } }, is_syntax_valid: function() { if (this.get("effective_readonly")) { return true; } - var value_ = this.values[this.$element.find('select')[0].selectedIndex]; + var value_ = this.values[this.$el.find('select')[0].selectedIndex]; return !! value_; }, focus: function() { - this.$element.find('select:first').focus(); + this.$el.find('select:first').focus(); } }); -// jquery autocomplete tweak to allow html +// jquery autocomplete tweak to allow html and classnames (function() { var proto = $.ui.autocomplete.prototype, initSource = proto._initSource; @@ -2584,7 +2573,8 @@ instance.web.form.FieldSelection = instance.web.form.AbstractField.extend(instan return $( "<li></li>" ) .data( "item.autocomplete", item ) .append( $( "<a></a>" )[ this.options.html ? "html" : "text" ]( item.label ) ) - .appendTo( ul ); + .appendTo( ul ) + .addClass(item.classname); } }); })(); @@ -2624,25 +2614,36 @@ instance.web.form.CompletionFieldMixin = { // search more... if more results that max if (values.length > self.limit) { values = values.slice(0, self.limit); - values.push({label: _t("<em>ย ย ย Search More...</em>"), action: function() { - dataset.name_search(search_val, self.build_domain(), 'ilike' - , false, function(data) { - self._search_create_popup("search", data); - }); - }}); + values.push({ + label: _t("Search More..."), + action: function() { + dataset.name_search(search_val, self.build_domain(), 'ilike', false, function(data) { + self._search_create_popup("search", data); + }); + }, + classname: 'oe_m2o_dropdown_option' + }); } // quick create var raw_result = _(data.result).map(function(x) {return x[1];}); if (search_val.length > 0 && !_.include(raw_result, search_val)) { - values.push({label: _.str.sprintf(_t('<em>ย ย ย Create "<strong>%s</strong>"</em>'), - $('<span />').text(search_val).html()), action: function() { - self._quick_create(search_val); - }}); + values.push({ + label: _.str.sprintf(_t('Create "<strong>%s</strong>"'), + $('<span />').text(search_val).html()), + action: function() { + self._quick_create(search_val); + }, + classname: 'oe_m2o_dropdown_option' + }); } // create... - values.push({label: _t("<em>ย ย ย Create and Edit...</em>"), action: function() { - self._search_create_popup("form", undefined, {}); - }}); + values.push({ + label: _t("Create and Edit..."), + action: function() { + self._search_create_popup("form", undefined, self._create_context(search_val)); + }, + classname: 'oe_m2o_dropdown_option' + }); return values; }); @@ -2653,7 +2654,7 @@ instance.web.form.CompletionFieldMixin = { _quick_create: function(name) { var self = this; var slow_create = function () { - self._search_create_popup("form", undefined, {"default_name": name}); + self._search_create_popup("form", undefined, self._create_context(name)); }; if (self.options.quick_create === undefined || self.options.quick_create) { new instance.web.DataSet(this, this.field.relation, self.build_context()) @@ -2690,6 +2691,13 @@ instance.web.form.CompletionFieldMixin = { * To implement. */ add_id: function(id) {}, + _create_context: function(name) { + var tmp = {}; + var field = (this.options || {}).create_name_field; + if (field !== false && (this.options || {}).quick_create !== false) + tmp["default_" + field] = name || "name"; + return tmp; + }, }; instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instance.web.form.CompletionFieldMixin, instance.web.form.ReinitializeFieldMixin, { @@ -2724,7 +2732,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc }, render_editable: function() { var self = this; - this.$input = this.$element.find("input"); + this.$input = this.$el.find("input"); self.$input.tipsy({ title: function() { @@ -2744,8 +2752,8 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc self.$input.tipsy("hide"); }); - this.$drop_down = this.$element.find(".oe_m2o_drop_down_button"); - this.$follow_button = $(".oe_m2o_cm_button", this.$element); + this.$drop_down = this.$el.find(".oe_m2o_drop_down_button"); + this.$follow_button = $(".oe_m2o_cm_button", this.$el); this.$follow_button.click(function() { if (!self.get('value')) { @@ -2838,7 +2846,21 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc self.tip_def.reject(); } }; - this.$input.focusout(anyoneLoosesFocus); + var ignore_blur = false; + this.$input.on({ + focusout: anyoneLoosesFocus, + focus: function () { self.trigger('focused'); }, + autocompleteopen: function () { ignore_blur = true; }, + autocompleteclose: function () { ignore_blur = false; }, + blur: function () { + // autocomplete open + if (ignore_blur) { return; } + if (_(self.getChildren()).any(function (child) { + return child instanceof instance.web.form.AbstractFormPopup; + })) { return; } + self.trigger('blurred'); + } + }); var isSelecting = false; // autocomplete @@ -2880,7 +2902,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc } isSelecting = false; }); - this.setupFocus(this.$input.add(this.$follow_button)); + this.setupFocus(this.$follow_button); }, render_value: function(no_recurse) { var self = this; @@ -2919,7 +2941,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc if (follow) link += "<br />"; } - var $link = this.$element.find('.oe_form_uri') + var $link = this.$el.find('.oe_form_uri') .unbind('click') .html(link); if (! this.options.no_open) @@ -2934,7 +2956,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc }); return false; }); - $(".oe_form_m2o_follow", this.$element).html(follow); + $(".oe_form_m2o_follow", this.$el).html(follow); } }, set_value: function(value_) { @@ -3035,7 +3057,7 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({ }, start: function() { this._super.apply(this, arguments); - this.$element.addClass('oe_form_field oe_form_field_one2many'); + this.$el.addClass('oe_form_field oe_form_field_one2many'); var self = this; @@ -3145,7 +3167,7 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({ } } else if (view_type === "form") { if (self.get("effective_readonly")) { - $(".oe_form_buttons", controller.$element).children().remove(); + $(".oe_form_buttons", controller.$el).children().remove(); } controller.on_record_loaded.add_last(function() { once.resolve(); @@ -3166,7 +3188,7 @@ instance.web.form.FieldOne2Many = instance.web.form.AbstractField.extend({ }); this.is_setted.then(function() { $.async_when().then(function () { - self.viewmanager.appendTo(self.$element); + self.viewmanager.appendTo(self.$el); }); }); return def; @@ -3387,7 +3409,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ }, start: function () { var ret = this._super(); - this.$element + this.$el .off('mousedown.handleButtons') .on('mousedown.handleButtons', 'table button', this.proxy('_button_down')); return ret; @@ -3401,7 +3423,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ // If the form has not been modified, the view can only be valid // NB: is_dirty will also be set on defaults/onchanges/whatever? // oe_form_dirty seems to only be set on actual user actions - if (!form.$element.is('.oe_form_dirty')) { + if (!form.$el.is('.oe_form_dirty')) { return true; } this.o2m._dirty_flag = true; @@ -3465,7 +3487,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ return self.o2m.dataset.read_ids.apply(self.o2m.dataset, arguments); }, form_view_options: {'not_interactible_on_create':true}, - readonly: self.o2m.get("effective_readonly") + readonly: !this.is_action_enabled('edit') || self.o2m.get("effective_readonly") }); }, do_button_action: function (name, id, callback) { @@ -3515,7 +3537,7 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ return; } // FIXME: why isn't there an API for this? - if (this.editor.form.$element.hasClass('oe_form_dirty')) { + if (this.editor.form.$el.hasClass('oe_form_dirty')) { this.save_edition(); return; } @@ -3553,7 +3575,11 @@ instance.web.form.One2ManyListView = instance.web.ListView.extend({ }); instance.web.form.One2ManyList = instance.web.ListView.List.extend({ pad_table_to: function (count) { - this._super(count > 0 ? count - 1 : 0); + if (!this.view.is_action_enabled('create')) { + this._super(count); + } else { + this._super(count > 0 ? count - 1 : 0); + } // magical invocation of wtf does that do if (this.view.o2m.get('effective_readonly')) { @@ -3566,6 +3592,11 @@ instance.web.form.One2ManyList = instance.web.ListView.List.extend({ }).length; if (this.options.selectable) { columns++; } if (this.options.deletable) { columns++; } + + if (!this.view.is_action_enabled('create')) { + return; + } + var $cell = $('<td>', { colspan: columns, 'class': 'oe_form_field_one2many_list_row_add' @@ -3643,7 +3674,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in if (this.get("effective_readonly")) return; var self = this; - self.$text = $("textarea", this.$element); + self.$text = $("textarea", this.$el); self.$text.textext({ plugins : 'tags arrow autocomplete', autocomplete: { @@ -3701,7 +3732,7 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in self._drop_shown = true; }); self.tags = self.$text.textext()[0].tags(); - $("textarea", this.$element).focusout(function() { + $("textarea", this.$el).focusout(function() { self.$text.trigger("setInputData", ""); }).keydown(function(e) { if (e.which === $.ui.keyCode.TAB && self._drop_shown) { @@ -3735,10 +3766,10 @@ instance.web.form.FieldMany2ManyTags = instance.web.form.AbstractField.extend(in data = _.map(values, function(el) { return indexed[el]; }); if (! self.get("effective_readonly")) { self.tags.containerElement().children().remove(); - $("textarea", self.$element).css("padding-left", "3px"); + $("textarea", self.$el).css("padding-left", "3px"); self.tags.addTags(_.map(data, function(el) {return {name: el[1], id:el[0]};})); } else { - self.$element.html(QWeb.render("FieldMany2ManyTag", {elements: data})); + self.$el.html(QWeb.render("FieldMany2ManyTag", {elements: data})); } }; if (! values || values.length > 0) { @@ -3766,7 +3797,7 @@ instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({ }, start: function() { this._super.apply(this, arguments); - this.$element.addClass('oe_form_field oe_form_field_many2many'); + this.$el.addClass('oe_form_field oe_form_field_many2many'); var self = this; @@ -3829,7 +3860,7 @@ instance.web.form.FieldMany2Many = instance.web.form.AbstractField.extend({ loaded.resolve(); }); $.async_when().then(function () { - self.list_view.appendTo(self.$element); + self.list_view.appendTo(self.$el); }); return loaded; }, @@ -3957,7 +3988,7 @@ instance.web.form.FieldMany2ManyKanban = instance.web.form.AbstractField.extend( }); this.kanban_view.do_switch_view.add_last(_.bind(this.open_popup, this)); $.async_when().then(function () { - self.kanban_view.appendTo(self.$element); + self.kanban_view.appendTo(self.$el); }); return loaded; }, @@ -4041,7 +4072,7 @@ instance.web.form.Many2ManyQuickCreate = instance.web.Widget.extend({ }, start: function () { var self = this; - self.$text = this.$element.find('input').css("width", "200px"); + self.$text = this.$el.find('input').css("width", "200px"); self.$text.textext({ plugins : 'arrow autocomplete', autocomplete: { @@ -4149,8 +4180,8 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.extend({ }, title: this.options.title || "", buttons: [{text:"tmp"}], - }, this.$element).open(); - this.$buttonpane = dialog.$element.dialog("widget").find(".ui-dialog-buttonpane").html(""); + }, this.$el).open(); + this.$buttonpane = dialog.$el.dialog("widget").find(".ui-dialog-buttonpane").html(""); this.start(); }, on_write_completed: function() {}, @@ -4173,7 +4204,7 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.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_popup_form")); + this.view_form.appendTo(this.$el.find(".oe_popup_form")); this.view_form.on_loaded.add_last(function() { var multi_select = self.row_id === null && ! self.options.disable_multiple_selection; self.$buttonpane.html(QWeb.render("AbstractFormPopup.buttons", { @@ -4213,7 +4244,7 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.extend({ this.destroy(); }, destroy: function () { - this.$element.dialog('close'); + this.$el.dialog('close'); this._super(); }, }); @@ -4305,7 +4336,7 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend e.cancel = true; }); self.view_list.popup = self; - self.view_list.appendTo($(".oe_popup_list", self.$element)).pipe(function() { + self.view_list.appendTo($(".oe_popup_list", self.$el)).pipe(function() { self.view_list.do_show(); }).pipe(function() { self.searchview.do_search(); @@ -4323,7 +4354,7 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend }); }); }); - this.searchview.appendTo($(".oe_popup_list", self.$element)); + this.searchview.appendTo($(".oe_popup_list", self.$el)); }, do_search: function(domains, contexts, groupbys) { var self = this; @@ -4349,7 +4380,7 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend this.searchview.hide(); } if (this.view_list) { - this.view_list.$element.hide(); + this.view_list.$el.hide(); } this.setup_form_view(); }, @@ -4382,7 +4413,7 @@ instance.web.form.FieldReference = instance.web.form.AbstractField.extend(instan var sel = this.selection.get_value(); this.m2o.field.relation = sel; this.m2o.set_value(false); - this.m2o.$element.toggle(sel !== false); + this.m2o.$el.toggle(sel !== false); } }, destroy_content: function() { @@ -4486,9 +4517,9 @@ instance.web.form.FieldBinary = instance.web.form.AbstractField.extend(instance. this._super.apply(this, arguments); }, initialize_content: function() { - 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); + this.$el.find('input.oe_form_binary_file').change(this.on_file_change); + this.$el.find('button.oe_form_binary_file_save').click(this.on_save_as); + this.$el.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']; @@ -4505,10 +4536,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_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(); + this.$el.find('form.oe_form_binary_form input[name=session_id]').val(this.session.session_id); + this.$el.find('form.oe_form_binary_form').submit(); + this.$el.find('.oe_form_binary_progress').show(); + this.$el.find('.oe_form_binary').hide(); } }, on_file_uploaded: function(size, name, content_type, file_base64) { @@ -4520,8 +4551,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_form_binary_progress').hide(); - this.$element.find('.oe_form_binary').show(); + this.$el.find('.oe_form_binary_progress').hide(); + this.$el.find('.oe_form_binary').show(); }, on_file_uploaded_and_valid: function(size, name, content_type, file_base64) { }, @@ -4575,7 +4606,7 @@ instance.web.form.FieldBinaryFile = instance.web.form.FieldBinary.extend({ this._super(); if (this.get("effective_readonly")) { var self = this; - this.$element.find('a').click(function() { + this.$el.find('a').click(function() { if (self.get('value')) { self.on_save_as(); } @@ -4595,12 +4626,12 @@ instance.web.form.FieldBinaryFile = instance.web.form.FieldBinary.extend({ } else { show_value = (this.get('value') != null && this.get('value') !== false) ? this.get('value') : ''; } - this.$element.find('input').eq(0).val(show_value); + this.$el.find('input').eq(0).val(show_value); } else { - this.$element.find('a').show(!!this.get('value')); + this.$el.find('a').show(!!this.get('value')); if (this.get('value')) { var show_value = _t("Download") + " " + (this.view.datarecord[this.node.attrs.filename] || ''); - this.$element.find('a').text(show_value); + this.$el.find('a').text(show_value); } } }, @@ -4608,7 +4639,7 @@ instance.web.form.FieldBinaryFile = instance.web.form.FieldBinary.extend({ this.binary_value = true; this.set({'value': file_base64}); var show_value = name + " (" + this.human_filesize(size) + ")"; - this.$element.find('input').eq(0).val(show_value); + this.$el.find('input').eq(0).val(show_value); this.set_filename(name); }, set_filename: function(value_) { @@ -4619,7 +4650,7 @@ instance.web.form.FieldBinaryFile = instance.web.form.FieldBinary.extend({ }, on_clear: function() { this._super.apply(this, arguments); - this.$element.find('input').eq(0).val(''); + this.$el.find('input').eq(0).val(''); this.set_filename(''); } }); @@ -4646,8 +4677,8 @@ instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({ url = "/web/static/src/img/placeholder.png"; } var $img = $(QWeb.render("FieldBinaryImage-img", { widget: this, url: url })); - this.$element.find('> img').remove(); - this.$element.prepend($img); + this.$el.find('> img').remove(); + this.$el.prepend($img); $img.load(function() { if (! self.options.size) return; @@ -4685,11 +4716,11 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ // backward compatibility this.loaded = new $.Deferred(); if (this.options.clickable) { - this.$element.on('click','li',this.on_click_stage); + this.$el.on('click','li',this.on_click_stage); } // TODO move the following into css :after - if (this.$element.parent().is('header')) { - this.$element.after('<div class="oe_clear"/>'); + if (this.$el.parent().is('header')) { + this.$el.after('<div class="oe_clear"/>'); } }, set_value: function(value_) { @@ -4750,7 +4781,7 @@ instance.web.form.FieldStatus = instance.web.form.AbstractField.extend({ render_elements: function () { var self = this; var content = instance.web.qweb.render("FieldStatus.content", {widget: this}); - this.$element.html(content); + this.$el.html(content); var colors = JSON.parse((this.node.attrs || {}).statusbar_colors || "{}"); var color = colors[this.selected_value]; if (color) { diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js index 95dfa78fd63..6c46003a380 100644 --- a/addons/web/static/src/js/view_list.js +++ b/addons/web/static/src/js/view_list.js @@ -145,7 +145,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi * @returns {$.Deferred} loading promise */ start: function() { - this.$element.addClass('oe_list'); + this.$el.addClass('oe_list'); return this.reload_view(null, null, true); }, /** @@ -248,20 +248,26 @@ 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']); + this.$el.html(QWeb.render(this._template, this)); + this.$el.addClass(this.fields_view.arch.attrs['class']); + + // add css classes that reflect the (absence of) access rights + this.$el.toggleClass('oe_list_cannot_create', !this.is_action_enabled('create')) + .toggleClass('oe_list_cannot_edit', !this.is_action_enabled('edit')) + .toggleClass('oe_list_cannot_delete', !this.is_action_enabled('delete')); + // Head hook // Selecting records - 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); + this.$el.find('.oe_list_record_selector').click(function(){ + self.$el.find('.oe_list_record_selector input').prop('checked', + self.$el.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.$el.find('thead').delegate('th.oe_sortable[data-id]', 'click', function (e) { e.stopPropagation(); var $this = $(this); self.dataset.sort($this.data('id')); @@ -281,7 +287,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi if (this.options.$buttons) { this.$buttons.appendTo(this.options.$buttons); } else { - this.$element.find('.oe_list_buttons').replaceWith(this.$buttons); + this.$el.find('.oe_list_buttons').replaceWith(this.$buttons); } this.$buttons.find('.oe_list_add') .click(this.proxy('do_add_record')) @@ -298,7 +304,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi if (this.options.$buttons) { this.$pager.appendTo(this.options.$pager); } else { - this.$element.find('.oe_list_pager').replaceWith(this.$pager); + this.$el.find('.oe_list_pager').replaceWith(this.$pager); } this.$pager @@ -351,13 +357,13 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi if (!this.sidebar && this.options.$sidebar) { this.sidebar = new instance.web.Sidebar(this); this.sidebar.appendTo(this.options.$sidebar); - this.sidebar.add_items('other', [ - { label: _t("Import"), callback: this.on_sidebar_import }, + this.sidebar.add_items('other', _.compact([ + self.is_action_enabled('create') && { label: _t("Import"), callback: this.on_sidebar_import }, { label: _t("Export"), callback: this.on_sidebar_export }, - { label: _t('Delete'), callback: this.do_delete_selected } - ]); + self.is_action_enabled('delete') && { label: _t('Delete'), callback: this.do_delete_selected } + ])); this.sidebar.add_toolbar(this.fields_view.toolbar); - this.sidebar.$element.hide(); + this.sidebar.$el.hide(); } }, /** @@ -450,7 +456,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi }, do_hide: function () { if (this.sidebar) { - this.sidebar.$element.hide(); + this.sidebar.$el.hide(); } if (this.$buttons) { this.$buttons.hide(); @@ -490,10 +496,10 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi */ reload_content: function () { var self = this; - self.$element.find('.oe_list_record_selector').prop('checked', false); + self.$el.find('.oe_list_record_selector').prop('checked', false); this.records.reset(); var reloaded = $.Deferred(); - this.$element.find('.oe_list_content').append( + this.$el.find('.oe_list_content').append( this.groups.render(function () { if (self.dataset.index == null) { var has_one = false; @@ -595,7 +601,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi if (!ids.length) { this.dataset.index = 0; if (this.sidebar) { - this.sidebar.$element.hide(); + this.sidebar.$el.hide(); } this.compute_aggregates(); return; @@ -603,7 +609,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi this.dataset.index = _(this.dataset.ids).indexOf(ids[0]); if (this.sidebar) { - this.sidebar.$element.show(); + this.sidebar.$el.show(); } this.compute_aggregates(_(records).map(function (record) { @@ -763,7 +769,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.$el.find('.oe_list_footer'); _(this.aggregate_columns).each(function (column) { if (!column['function']) { return; @@ -789,7 +795,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi pad_columns: function (count, options) { options = options || {}; // padding for action/pager header - var $first_header = this.$element.find('thead tr:first th'); + var $first_header = this.$el.find('thead tr:first th'); var colspan = $first_header.attr('colspan'); if (colspan) { if (!this.previous_colspan) { @@ -798,7 +804,7 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi $first_header.attr('colspan', parseInt(colspan, 10) + count); } // Padding for column titles, footer and data rows - var $rows = this.$element + var $rows = this.$el .find('.oe_list_header_columns, tr:not(thead tr)') .not(options['except']); var newcols = new Array(count+1).join('<td class="oe_list_padding"></td>'); @@ -812,23 +818,23 @@ 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_list_padding').remove(); + this.$el.find('.oe_list_padding').remove(); if (this.previous_colspan) { - this.$element + this.$el .find('thead tr:first th') .attr('colspan', this.previous_colspan); this.previous_colspan = null; } }, no_result: function () { - this.$element.find('.oe_view_nocontent').remove(); + this.$el.find('.oe_view_nocontent').remove(); if (this.groups.group_by || !this.options.action || !this.options.action.help) { return; } - this.$element.find('table:first').hide(); - this.$element.prepend( + this.$el.find('table:first').hide(); + this.$el.prepend( $('<div class="oe_view_nocontent">').html(this.options.action.help) ); } @@ -1478,27 +1484,27 @@ instance.web.ListView.Groups = instance.web.Class.extend( /** @lends instance.we }, render: function (post_render) { var self = this; - var $element = $('<tbody>'); - this.elements = [$element[0]]; + var $el = $('<tbody>'); + this.elements = [$el[0]]; this.datagroup.list( _(this.view.visible_columns).chain() .filter(function (column) { return column.tag === 'field' }) .pluck('name').value(), function (groups) { - $element[0].appendChild( + $el[0].appendChild( self.render_groups(groups)); if (post_render) { post_render(); } }, function (dataset) { self.render_dataset(dataset).then(function (list) { self.children[null] = list; self.elements = - [list.$current.replaceAll($element)[0]]; + [list.$current.replaceAll($el)[0]]; self.setup_resequence_rows(list, dataset); if (post_render) { post_render(); } }); }); - return $element; + return $el; }, /** * Returns the ids of all selected records for this group, and the records @@ -1995,7 +2001,7 @@ instance.web.list.Column = instance.web.Class.extend({ if (!(aggregation_func in this)) { return {}; } - var C = function (label, fn) { + var C = function (fn, label) { this['function'] = fn; this.label = label; }; @@ -2115,6 +2121,11 @@ instance.web.list.ProgressBar = instance.web.list.Column.extend({ } }); instance.web.list.Handle = instance.web.list.Column.extend({ + init: function () { + this._super.apply(this, arguments); + // Handle overrides the field to not be form-editable. + this.modifiers.readonly = true; + }, /** * Return styling hooks for a drag handle * diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js index 9a101a5ac1a..892221a347b 100644 --- a/addons/web/static/src/js/view_list_editable.js +++ b/addons/web/static/src/js/view_list_editable.js @@ -45,16 +45,22 @@ openerp.web.list_editable = function (instance) { } }); this.on('edit:after', this, function () { - self.$element.add(self.$buttons).addClass('oe_editing'); + self.$el.add(self.$buttons).addClass('oe_editing'); }); this.on('save:after cancel:after', this, function () { - self.$element.add(self.$buttons).removeClass('oe_editing'); + self.$el.add(self.$buttons).removeClass('oe_editing'); }); }, destroy: function () { instance.web.bus.off('resize', this, this.resize_fields); this._super(); }, + do_hide: function () { + if (this.editor.is_editing()) { + this.cancel_edition(true); + } + this._super(); + }, /** * Handles the activation of a record in editable mode (making a record * editable), called *after* the record has become editable. @@ -87,8 +93,8 @@ openerp.web.list_editable = function (instance) { */ do_add_record: function () { if (this.editable()) { - this.$element.find('table:first').show(); - this.$element.find('.oe_view_nocontent').remove(); + this.$el.find('table:first').show(); + this.$el.find('.oe_view_nocontent').remove(); this.start_edition(); } else { this._super(); @@ -99,7 +105,7 @@ openerp.web.list_editable = function (instance) { // tree/@editable takes priority on everything else if present. var result = this._super(data, grouped); if (this.editable()) { - this.$element.addClass('oe_list_editable'); + this.$el.addClass('oe_list_editable'); // FIXME: any hook available to ensure this is only done once? this.$buttons .off('click', '.oe_list_save') @@ -109,7 +115,7 @@ openerp.web.list_editable = function (instance) { e.preventDefault(); self.cancel_edition(); }); - this.$element + this.$el .off('click', 'tbody td:not(.oe_list_field_cell)') .on('click', 'tbody td:not(.oe_list_field_cell)', function () { if (!self.editor.is_editing()) { @@ -120,12 +126,12 @@ openerp.web.list_editable = function (instance) { // Editor is not restartable due to formview not being // restartable this.editor = this.make_editor(); - var editor_ready = this.editor.prependTo(this.$element) + var editor_ready = this.editor.prependTo(this.$el) .then(this.proxy('setup_events')); return $.when(result, editor_ready); } else { - this.$element.removeClass('oe_list_editable'); + this.$el.removeClass('oe_list_editable'); } return result; @@ -203,7 +209,7 @@ openerp.web.list_editable = function (instance) { } // FIXME: need better way to get the field back from bubbling (delegated) DOM events somehow - field.$element.attr('data-fieldname', field_name); + field.$el.attr('data-fieldname', field_name); self.fields_for_resize.push({field: field, cell: cell}); }, options).pipe(function () { $recordRow.addClass('oe_edition'); @@ -249,8 +255,8 @@ openerp.web.list_editable = function (instance) { var position = $cell.position(); // jquery does not understand !important - field.$element.attr('style', 'width: '+$cell.outerWidth()+'px !important') - field.$element.css({ + field.$el.attr('style', 'width: '+$cell.outerWidth()+'px !important'); + field.$el.css({ top: position.top, left: position.left, minHeight: $cell.outerHeight() @@ -354,14 +360,17 @@ openerp.web.list_editable = function (instance) { 'class': 'oe_form_container', version: '7.0' }); - _(view.arch.children).each(function (widget) { - var modifiers = JSON.parse(widget.attrs.modifiers || '{}'); - widget.attrs.nolabel = true; - if (modifiers['tree_invisible'] || widget.tag === 'button') { - modifiers.invisible = true; - } - widget.attrs.modifiers = JSON.stringify(modifiers); - }); + _(view.arch.children).chain() + .zip(this.columns) + .each(function (ar) { + var widget = ar[0], column = ar[1]; + var modifiers = _.extend({}, column.modifiers); + widget.attrs.nolabel = true; + if (modifiers['tree_invisible'] || widget.tag === 'button') { + modifiers.invisible = true; + } + widget.attrs.modifiers = JSON.stringify(modifiers); + }); return view; }, handle_onwrite: function (source_record) { @@ -391,7 +400,7 @@ openerp.web.list_editable = function (instance) { }, setup_events: function () { var self = this; - this.editor.$element.on('keyup keydown', function (e) { + this.editor.$el.on('keyup keydown', function (e) { if (!self.editor.is_editing()) { return; } var key = _($.ui.keyCode).chain() .map(function (v, k) { return {name: k, code: v}; }) @@ -540,7 +549,7 @@ openerp.web.list_editable = function (instance) { if (--field_index < 0) { return $.when(); } field = fields[fields_order[field_index]]; - } while (!field.$element.is(':visible')); + } while (!field.$el.is(':visible')); // and focus it field.focus(); @@ -563,7 +572,7 @@ openerp.web.list_editable = function (instance) { if (++field_index >= fields_order.length) { return $.when(); } field = fields[fields_order[field_index]]; - } while (!field.$element.is(':visible')); + } while (!field.$el.is(':visible')); field.focus(); return $.when(); @@ -572,11 +581,11 @@ openerp.web.list_editable = function (instance) { var form = this.editor.form; var last_field = _(form.fields_order).chain() .map(function (name) { return form.fields[name]; }) - .filter(function (field) { return field.$element.is(':visible'); }) + .filter(function (field) { return field.$el.is(':visible'); }) .last() .value(); // tabbed from last field in form - if (last_field && last_field.$element.has(e.target).length) { + if (last_field && last_field.$el.has(e.target).length) { e.preventDefault(); return this._next(); } @@ -620,7 +629,7 @@ openerp.web.list_editable = function (instance) { var _super = this._super(); this.form.embedded_view = this._validate_view( this.delegate.edition_view(this)); - var form_ready = this.form.appendTo(this.$element).then( + var form_ready = this.form.appendTo(this.$el).then( self.form.proxy('do_hide')); return $.when(_super, form_ready); }, @@ -678,7 +687,7 @@ openerp.web.list_editable = function (instance) { // Is actually in the form && (field = form.fields[focus_field]) // And is visible - && field.$element.is(':visible')) { + && field.$el.is(':visible')) { // focus it field.focus(); return; @@ -687,7 +696,7 @@ openerp.web.list_editable = function (instance) { _(form.fields_order).detect(function (name) { // look for first visible field in fields_order, focus it var field = form.fields[name]; - if (!field.$element.is(':visible')) { + if (!field.$el.is(':visible')) { return false; } // Stop as soon as a field got focused @@ -716,7 +725,7 @@ openerp.web.list_editable = function (instance) { save: function () { var self = this; return this.form - .do_save(null, this.delegate.prepends_on_create()) + .do_save(this.delegate.prepends_on_create()) .pipe(function (result) { var created = result.created && !self.record.id; if (created) { @@ -750,7 +759,7 @@ openerp.web.list_editable = function (instance) { instance.web.ListView.List.include(/** @lends instance.web.ListView.List# */{ row_clicked: function (event) { - if (!this.view.editable()) { + if (!this.view.editable() || ! this.view.is_action_enabled('edit')) { return this._super.apply(this, arguments); } var record_id = $(event.currentTarget).data('id'); diff --git a/addons/web/static/src/js/view_tree.js b/addons/web/static/src/js/view_tree.js index 2181b2aa157..e0493a446e2 100644 --- a/addons/web/static/src/js/view_tree.js +++ b/addons/web/static/src/js/view_tree.js @@ -84,13 +84,13 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie }); this.fields = fields_view.fields; this.hook_row_click(); - this.$element.html(QWeb.render('TreeView', { + this.$el.html(QWeb.render('TreeView', { 'title': this.fields_view.arch.attrs.string, 'fields_view': this.fields_view.arch.children, 'fields': this.fields, 'toolbar': has_toolbar })); - this.$element.addClass(this.fields_view.arch.attrs['class']); + this.$el.addClass(this.fields_view.arch.attrs['class']); this.dataset.read_slice(this.fields_list()).then(function(records) { self.store_record(records); @@ -102,7 +102,7 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie return; } - var $select = self.$element.find('select') + var $select = self.$el.find('select') .change(function () { var $option = $(this).find(':selected'); self.getdata($option.val()); @@ -120,10 +120,10 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie $select.change(); } }); - this.$element.find("#tree_view_expand").click(function(){ + this.$el.find("#tree_view_expand").click(function(){ self.expand_all(); }); - this.$element.find("#tree_view_collapse").click(function(){ + this.$el.find("#tree_view_collapse").click(function(){ self.collpase_all(); }); // TODO store open nodes in url ?... @@ -143,14 +143,14 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie }, expand_all: function(){ var self = this; - var tr = this.$element.find(".oe-treeview-table tbody tr[id^='treerow_']"); + var tr = this.$el.find(".oe-treeview-table tbody tr[id^='treerow_']"); _.each(tr,function(rec){ self.showcontent($(rec).attr('data-id'),true); }); }, collpase_all: function(){ var self = this; - var root_tr = this.$element.find(".oe-treeview-table tbody tr[data-level='"+1+"']"); + var root_tr = this.$el.find(".oe-treeview-table tbody tr[data-level='"+1+"']"); _.each(root_tr,function(rec){ if($(rec).hasClass('oe_open')){ self.showcontent($(rec).attr('data-id'),false); @@ -187,12 +187,12 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie */ hook_row_click: function () { var self = this; - this.$element.delegate('.treeview-td span, .treeview-tr span', 'click', function (e) { + this.$el.delegate('.treeview-td span, .treeview-tr span', 'click', function (e) { e.stopImmediatePropagation(); self.activate($(this).closest('tr').data('id')); }); - this.$element.delegate('.treeview-tr', 'click', function () { + this.$el.delegate('.treeview-tr', 'click', function () { var $this = $(this), record_id = $this.data('id'), bool = $this.parent().hasClass('oe_open'); @@ -220,7 +220,7 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie render_data: function(groupby){ var self = this; _.each(_.keys(groupby),function(key){ - var $curr_node = self.$element.find('#treerow_' + key); + var $curr_node = self.$el.find('#treerow_' + key); var record = groupby[key]; var children_rows = QWeb.render('TreeView.rows', { 'records': record, @@ -235,7 +235,7 @@ instance.web.TreeView = instance.web.View.extend(/** @lends instance.web.TreeVie $curr_node.addClass('oe_open'); $curr_node.after(children_rows); } else { - self.$element.find('tbody').html(children_rows); + self.$el.find('tbody').html(children_rows); } }); self.collpase_all(); @@ -272,11 +272,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) + this.$el.find('#treerow_' + record_id) .toggleClass('oe_open', show); _(this.records[record_id][this.children_field]).each(function (child_id) { - var $child_row = this.$element.find('#treerow_' + child_id); + var $child_row = this.$el.find('#treerow_' + child_id); if ($child_row.hasClass('oe_open')) { this.showcontent(child_id, false); } diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index 0831d0c5f8e..95693ca9c50 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -20,7 +20,7 @@ instance.web.ActionManager = instance.web.Widget.extend({ }, start: function() { this._super.apply(this, arguments); - this.$element.on('click', '.oe_breadcrumb_item', this.on_breadcrumb_clicked); + this.$el.on('click', '.oe_breadcrumb_item', this.on_breadcrumb_clicked); }, dialog_stop: function () { if (this.dialog) { @@ -53,10 +53,10 @@ instance.web.ActionManager = instance.web.Widget.extend({ } var item = _.extend({ show: function(index) { - this.widget.$element.show(); + this.widget.$el.show(); }, hide: function() { - this.widget.$element.hide(); + this.widget.$el.hide(); }, destroy: function() { this.widget.destroy(); @@ -277,14 +277,14 @@ instance.web.ActionManager = instance.web.Widget.extend({ } this.dialog.dialog_title = action.name; this.dialog_widget = widget; - this.dialog_widget.appendTo(this.dialog.$element); + this.dialog_widget.appendTo(this.dialog.$el); this.dialog.open(); } else { this.dialog_stop(); this.inner_action = action; this.inner_widget = widget; post_process(); - this.inner_widget.appendTo(this.$element); + this.inner_widget.appendTo(this.$el); } }, ir_actions_act_window: function (action, on_close) { @@ -376,7 +376,7 @@ instance.web.ViewManager = instance.web.Widget.extend({ start: function() { this._super(); var self = this; - this.$element.find('.oe_view_manager_switch a').click(function() { + this.$el.find('.oe_view_manager_switch a').click(function() { self.on_mode_switch($(this).data('view-type')); }).tipsy(); var views_ids = {}; @@ -385,9 +385,9 @@ instance.web.ViewManager = instance.web.Widget.extend({ deferred : $.Deferred(), controller : null, options : _.extend({ - $buttons : self.$element.find('.oe_view_manager_buttons'), - $sidebar : self.flags.sidebar ? self.$element.find('.oe_view_manager_sidebar') : undefined, - $pager : self.$element.find('.oe_view_manager_pager'), + $buttons : self.$el.find('.oe_view_manager_buttons'), + $sidebar : self.flags.sidebar ? self.$el.find('.oe_view_manager_sidebar') : undefined, + $pager : self.$el.find('.oe_view_manager_pager'), action : self.action, action_views_ids : views_ids }, self.flags, self.flags[view.view_type] || {}, view.options || {}) @@ -395,7 +395,7 @@ instance.web.ViewManager = instance.web.Widget.extend({ views_ids[view.view_type] = view.view_id; }); if (this.flags.views_switcher === false) { - this.$element.find('.oe_view_manager_switch').hide(); + this.$el.find('.oe_view_manager_switch').hide(); } // If no default view defined, switch to the first one in sequence var default_view = this.flags.default_view || this.views_src[0].view_type; @@ -432,9 +432,9 @@ instance.web.ViewManager = instance.web.Widget.extend({ this.searchview[(view.controller.searchable === false || this.searchview.hidden) ? 'hide' : 'show'](); } - this.$element + this.$el .find('.oe_view_manager_switch a').parent().removeClass('active'); - this.$element + this.$el .find('.oe_view_manager_switch a').filter('[data-view-type="' + view_type + '"]') .parent().addClass('active'); @@ -442,7 +442,7 @@ instance.web.ViewManager = instance.web.Widget.extend({ _.each(_.keys(self.views), function(view_name) { var controller = self.views[view_name].controller; if (controller) { - var container = self.$element.find(".oe_view_manager_view_" + view_name + ":first"); + var container = self.$el.find(".oe_view_manager_view_" + view_name + ":first"); if (view_name === view_type) { container.show(); controller.do_show(view_options || {}); @@ -451,10 +451,10 @@ instance.web.ViewManager = instance.web.Widget.extend({ controller.do_hide(); } // put the <footer> in the dialog's buttonpane - if (self.$element.parent('.ui-dialog-content') && self.$element.find('footer')) { - self.$element.parent('.ui-dialog-content').parent().find('div.ui-dialog-buttonset').hide() - self.$element.find('footer').appendTo( - self.$element.parent('.ui-dialog-content').parent().find('div.ui-dialog-buttonpane') + if (self.$el.parent('.ui-dialog-content') && self.$el.find('footer')) { + self.$el.parent('.ui-dialog-content').parent().find('div.ui-dialog-buttonset').hide() + self.$el.find('footer').appendTo( + self.$el.parent('.ui-dialog-content').parent().find('div.ui-dialog-buttonpane') ); } } @@ -491,7 +491,7 @@ instance.web.ViewManager = instance.web.Widget.extend({ controller.do_switch_view.add_last(_.bind(this.switch_view, this)); controller.do_prev_view.add_last(this.on_prev_view); - var container = this.$element.find(".oe_view_manager_view_" + view_type); + var container = this.$el.find(".oe_view_manager_view_" + view_type); var view_promise = controller.appendTo(container); this.views[view_type].controller = controller; this.views[view_type].deferred.resolve(view_type); @@ -505,7 +505,7 @@ instance.web.ViewManager = instance.web.Widget.extend({ }); }, set_title: function(title) { - this.$element.find('.oe_view_title_text:first').text(title); + this.$el.find('.oe_view_title_text:first').text(title); }, add_breadcrumb: function() { var self = this; @@ -524,7 +524,7 @@ instance.web.ViewManager = instance.web.Widget.extend({ action: this.action, show: function(index) { var view_to_select = views[index]; - self.$element.show(); + self.$el.show(); if (self.active_view !== view_to_select) { self.on_mode_switch(view_to_select); } @@ -600,7 +600,7 @@ instance.web.ViewManager = instance.web.Widget.extend({ this.searchview = new instance.web.SearchView(this, this.dataset, view_id, search_defaults, this.flags.search_view === false); this.searchview.on_search.add(this.do_searchview_search); - return this.searchview.appendTo(this.$element.find(".oe_view_manager_view_search")); + return this.searchview.appendTo(this.$el.find(".oe_view_manager_view_search")); }, do_searchview_search: function(domains, contexts, groupbys) { var self = this, @@ -717,8 +717,8 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({ var manager_ready = $.when(searchview_loaded, main_view_loaded); - this.$element.find('.oe_debug_view').change(this.on_debug_changed); - this.$element.addClass("oe_view_manager_" + (this.action.target || 'current')); + this.$el.find('.oe_debug_view').change(this.on_debug_changed); + this.$el.addClass("oe_view_manager_" + (this.action.target || 'current')); return manager_ready; }, on_debug_changed: function (evt) { @@ -730,7 +730,7 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({ switch (val) { case 'fvg': var dialog = new instance.web.Dialog(this, { title: _t("Fields View Get"), width: '95%' }).open(); - $('<pre>').text(instance.web.json_node_to_xml(current_view.fields_view.arch, true)).appendTo(dialog.$element); + $('<pre>').text(instance.web.json_node_to_xml(current_view.fields_view.arch, true)).appendTo(dialog.$el); break; case 'perm_read': var ids = current_view.get_selected_ids(); @@ -749,6 +749,17 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({ case 'toggle_layout_outline': current_view.rendering_engine.toggle_layout_debugging(); break; + case 'translate': + this.do_action({ + name: "Technical Translation", + res_model : 'ir.translation', + domain : [['type', '!=', 'object'], '|', ['name', '=', this.dataset.model], ['name', 'ilike', this.dataset.model + ',']], + views: [[false, 'list'], [false, 'form']], + type : 'ir.actions.act_window', + view_type : "list", + view_mode : "list" + }); + break; case 'fields': this.dataset.call_and_eval( 'fields_get', [false, {}], null, 1).then(function (fields) { @@ -828,7 +839,7 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({ var controller = self.views[self.active_view].controller, fvg = controller.fields_view, view_id = (fvg && fvg.view_id) || '--'; - self.$element.find('.oe_debug_view').html(QWeb.render('ViewManagerDebug', { + self.$el.find('.oe_debug_view').html(QWeb.render('ViewManagerDebug', { view: controller, view_manager: self })); @@ -842,7 +853,7 @@ instance.web.ViewManagerAction = instance.web.ViewManager.extend({ return r; }, set_title: function(title) { - this.$element.find('.oe_breadcrumb_title:first').html(this.getParent().get_title()); + this.$el.find('.oe_breadcrumb_title:first').html(this.getParent().get_title()); }, do_push_state: function(state) { if (this.getParent() && this.getParent().do_push_state) { @@ -874,7 +885,7 @@ instance.web.Sidebar = instance.web.Widget.extend({ var view = this.getParent(); this.sections = [ { 'name' : 'print', 'label' : _t('Print'), }, - { 'name' : 'files', 'label' : _t('Attachment'), }, + { 'name' : 'files', 'label' : _t('Attachment(s)'), }, { 'name' : 'other', 'label' : _t('More'), } ]; this.items = { @@ -882,10 +893,6 @@ instance.web.Sidebar = instance.web.Widget.extend({ 'files' : [], 'other' : [] }; - if (this.session.uid === 1) { - var item = { label: _t("Translate"), callback: view.on_sidebar_translate, title: _t("Technical translation") }; - this.items.other.push(item); - } this.fileupload_id = _.uniqueId('oe_fileupload'); $(window).on(this.fileupload_id, function() { var args = [].slice.call(arguments).slice(1); @@ -901,7 +908,7 @@ instance.web.Sidebar = instance.web.Widget.extend({ var self = this; this._super(this); this.redraw(); - this.$element.on('click','.oe_dropdown_menu li a', function(event) { + this.$el.on('click','.oe_dropdown_menu li a', function(event) { var section = $(this).data('section'); var index = $(this).data('index'); var item = self.items[section][index]; @@ -917,7 +924,7 @@ instance.web.Sidebar = instance.web.Widget.extend({ }, redraw: function() { var self = this; - self.$element.html(QWeb.render('Sidebar', {widget: self})); + self.$el.html(QWeb.render('Sidebar', {widget: self})); // Hides Sidebar sections when item list is empty this.$('.oe_form_dropdown_section').each(function() { @@ -1024,12 +1031,12 @@ instance.web.Sidebar = instance.web.Widget.extend({ self.items['files'] = attachments; self.redraw(); 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); + this.$el.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_form_binary_form').submit(); + this.$el.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...')); @@ -1050,119 +1057,6 @@ instance.web.Sidebar = instance.web.Widget.extend({ } }); -instance.web.TranslateDialog = instance.web.Dialog.extend({ - dialog_title: {toString: function () { return _t("Translations"); }}, - init: function(view) { - // TODO fme: should add the language to fields_view_get because between the fields view get - // and the moment the user opens the translation dialog, the user language could have been changed - this.view_language = view.session.user_context.lang; - this['on_button_' + _t("Save")] = this.on_btn_save; - this['on_button_' + _t("Close")] = this.on_btn_close; - this._super(view, { - width: '80%', - height: '80%', - destroy_on_close: false, - }); - this.view = view; - this.view_type = view.fields_view.type || ''; - this.$fields_form = null; - this.$view_form = null; - this.$sidebar_form = null; - this.translatable_fields_keys = _.map(this.view.translatable_fields || [], function(i) { return i.name; }); - this.languages = null; - this.languages_loaded = $.Deferred(); - (new instance.web.DataSetSearch(this, 'res.lang', this.view.dataset.get_context(), - [['translatable', '=', '1']])).read_slice(['code', 'name'], { sort: 'id' }).then(this.on_languages_loaded); - }, - start: function() { - var self = this; - this._super(); - $.when(this.languages_loaded).then(function() { - self.$element.html(instance.web.qweb.render('TranslateDialog', { widget: self })); - self.$fields_form = self.$element.find('.oe_translation_form'); - self.$fields_form.find('.oe_trad_field').change(function() { - $(this).toggleClass('touched', ($(this).val() != $(this).attr('data-value'))); - }); - }); - return this; - }, - on_languages_loaded: function(langs) { - this.languages = langs; - this.languages_loaded.resolve(); - }, - do_load_fields_values: function(callback) { - var self = this, - deffered = []; - this.$fields_form.find('.oe_trad_field').val('').removeClass('touched'); - _.each(self.languages, function(lg) { - var deff = $.Deferred(); - deffered.push(deff); - var callback = function(values) { - _.each(self.translatable_fields_keys, function(f) { - var value = values[0][f] || ''; - self.$fields_form.find('.oe_trad_field[name="' + lg.code + '-' + f + '"]').val(value).attr('data-value', value); - }); - deff.resolve(); - }; - if (lg.code === self.view_language) { - var values = {}; - _.each(self.translatable_fields_keys, function(field) { - values[field] = self.view.fields[field].get_value(); - }); - callback([values]); - } else { - self.view.dataset.read_ids([self.view.datarecord.id], self.translatable_fields_keys, { - context: { 'lang': lg.code } - }).then(callback); - } - }); - $.when.apply(null, deffered).then(callback); - }, - open: function(field) { - var self = this; - this._super(); - $.when(this.languages_loaded).then(function() { - if (self.view.translatable_fields && self.view.translatable_fields.length) { - self.do_load_fields_values(function() { - if (field) { - var $field_input = self.$element.find('tr[data-field="' + field.name + '"] td:nth-child(2) *:first-child'); - self.$element.scrollTo($field_input); - $field_input.focus(); - } - }); - } else { - sup.call(self); - } - }); - }, - on_btn_save: function() { - var trads = {}, - self = this, - trads_mutex = new $.Mutex(); - self.$fields_form.find('.oe_trad_field.touched').each(function() { - var field = $(this).attr('name').split('-'); - if (!trads[field[0]]) { - trads[field[0]] = {}; - } - trads[field[0]][field[1]] = $(this).val(); - }); - _.each(trads, function(data, code) { - if (code === self.view_language) { - _.each(data, function(value, field) { - self.view.fields[field].set_value(value); - }); - } - trads_mutex.exec(function() { - return self.view.dataset.write(self.view.datarecord.id, data, { context : { 'lang': code } }); - }); - }); - this.close(); - }, - on_btn_close: function() { - this.close(); - } -}); - instance.web.View = instance.web.Widget.extend({ // name displayed in view switchers display_name: '', @@ -1214,12 +1108,6 @@ instance.web.View = instance.web.Widget.extend({ action_views_ids: {} }); }, - open_translate_dialog: function(field) { - if (!this.translate_dialog) { - this.translate_dialog = new instance.web.TranslateDialog(this); - } - this.translate_dialog.open(field); - }, /** * Fetches and executes the action identified by ``action_data``. * @@ -1302,10 +1190,10 @@ instance.web.View = instance.web.Widget.extend({ this.embedded_view = embedded_view; }, do_show: function () { - this.$element.show(); + this.$el.show(); }, do_hide: function () { - this.$element.hide(); + this.$el.hide(); }, do_push_state: function(state) { if (this.getParent() && this.getParent().do_push_state) { @@ -1338,16 +1226,6 @@ instance.web.View = instance.web.Widget.extend({ on_sidebar_export: function() { new instance.web.DataExport(this, this.dataset).open(); }, - on_sidebar_translate: function() { - return this.do_action({ - res_model : 'ir.translation', - domain : [['type', '!=', 'object'], '|', ['name', '=', this.dataset.model], ['name', 'ilike', this.dataset.model + ',']], - views: [[false, 'list'], [false, 'form']], - type : 'ir.actions.act_window', - view_type : "list", - view_mode : "list" - }); - }, sidebar_context: function () { return $.when(); }, @@ -1357,6 +1235,15 @@ instance.web.View = instance.web.Widget.extend({ */ reload: function () { return $.when(); + }, + /** + * Return whether the user can perform the action ('create', 'edit', 'delete') in this view. + * An action is disabled by setting the corresponding attribute in the view's main element, + * like: <form string="" create="false" edit="false" delete="false"> + */ + is_action_enabled: function(action) { + var attrs = this.fields_view.arch.attrs; + return (action in attrs) ? JSON.parse(attrs[action]) : true; } }); diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 61c717618dc..d206c538e1c 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -51,29 +51,6 @@ </table> </t> <t t-name="CrashManager.error"> - <t t-if="!session.openerp_entreprise"> - <span>Your version of OpenERP is unsupported. Support & maintenance services are available here: <a href="http://www.openerp.com/support-or-publisher-warranty-contract" target="_blank">OpenERP Entreprise</a>.</span> - </t> - <t t-if="session.openerp_entreprise"> - <div class="oe_error_send"> - <div> - <div class="oe_centeralign"><b>OpenERP Enterprise Contract.</b></div> - <div><br/>Your report will be sent to the OpenERP Enterprise team.<br/></div><br/> - <div> - <label>Summary:</label><br/> - <input id="issuename" type="text" class="oe_fielddiv"/> - </div><br/><br/> - <div> - <label>Description:</label><br/> - <textarea id="explanation" rows="6"></textarea> - </div><br/><br/> - <div> - <label>What you did:</label><br/> - <textarea id="remark" rows="6" ></textarea> - </div> - </div> - </div><br/> - </t> <div class="oe_error_detail"> <pre><t t-esc="error.message"/></pre> <hr/> @@ -143,7 +120,7 @@ </tr> <tr> <td><label for="db_name">New database name:</label></td> - <td><input type="text" name="db_name" class="required" matches="^[a-zA-Z][a-zA-Z0-9_]+$" autofocus="true"/></td> + <td><input type="text" name="db_name" class="required" matches="^[a-zA-Z][a-zA-Z0-9_-]+$" autofocus="true"/></td> </tr> <tr> <td><label for="demo_data">Load Demonstration data:</label></td> @@ -506,6 +483,7 @@ <option value="fvg">Fields View Get</option> <option value="manage_filters">Manage Filters</option> <t t-if="view_manager.session.uid === 1"> + <option value="translate">Technical translation</option> <option value="manage_views">Manage Views</option> <option value="edit" data-model="ir.ui.view" t-att-data-id="view.fields_view.view_id">Edit <t t-esc="_.str.capitalize(view.fields_view.type)"/>View</option> <option t-if="view_manager.searchview" value="edit" data-model="ir.ui.view" t-att-data-id="view_manager.searchview.view_id">Edit SearchView</option> @@ -563,6 +541,7 @@ <t t-foreach="widget.sections" t-as="section"> <div class="oe_form_dropdown_section"> <button class="oe_dropdown_toggle oe_dropdown_arrow"> + <t t-if="section.name == 'files'" t-raw="widget.items[section.name].length || ''"/> <t t-esc="section.label"/> </button> <ul class="oe_dropdown_menu"> @@ -657,7 +636,7 @@ <t t-if="column.tag !== 'button'"><t t-esc="column.string"/></t> </th> </t> - <th t-if="options.deletable" width="13px"/> + <th t-if="options.deletable" class="oe_list_record_delete" width="13px"/> </tr> </thead> <tfoot> @@ -671,7 +650,7 @@ </tfoot> </table> <div t-name="ListView.buttons" class="oe_list_buttons"> - <t t-if="!widget.no_leaf and widget.options.action_buttons !== false and widget.options.addable"> + <t t-if="!widget.no_leaf and widget.options.action_buttons !== false and widget.options.addable and widget.is_action_enabled('create')"> <button type="button" class="oe_button oe_list_add oe_highlight"> <t t-esc="widget.options.addable"/> </button> @@ -723,7 +702,7 @@ type="button">Save</button> </t> <t t-jquery="a.oe_list_button_import" t-operation="after"> - <a href="#" class="oe_bold oe_list_discard">discard</a> + <a href="#" class="oe_bold oe_list_discard">Discard</a> </t> </t> <t t-extend="ListView.row"> @@ -747,13 +726,17 @@ <div t-name="FormView.buttons" class="oe_form_buttons"> <t t-if="widget.options.action_buttons !== false"> <span class="oe_form_buttons_view"> - <div style="display: inline-block;"> <!-- required for the bounce effect on button --> - <button type="button" class="oe_button oe_form_button_edit">Edit</button> + <!-- required for the bounce effect on button --> + <div t-if="widget.is_action_enabled('edit')" style="display: inline-block;"> + <button type="button" class="oe_button oe_form_button_edit" accesskey="E">Edit</button> </div> - <button type="button" class="oe_button oe_form_button_create">Create</button> + <button t-if="widget.is_action_enabled('create')" + type="button" class="oe_button oe_form_button_create" accesskey="C">Create</button> </span> <span class="oe_form_buttons_edit"> - <button type="button" class="oe_button oe_form_button_save oe_highlight">Save</button> <span class="oe_fade">or</span> <a href="#" class="oe_bold oe_form_button_cancel">Discard</a> + <button type="button" class="oe_button oe_form_button_save oe_highlight" accesskey="S">Save</button> + <span class="oe_fade">or</span> + <a href="#" class="oe_bold oe_form_button_cancel" accesskey="D">Discard</a> </span> </t> </div> @@ -839,7 +822,7 @@ <div class="oe_clear"> <ul t-attf-class="oe_notebook #{classnames}"> <li t-foreach="pages" t-as="page" t-att-modifiers="page.modifiers"> - <a t-attf-href="##{page.id}"> + <a t-attf-href="##{page.id}" t-att-accesskey="page.accesskey"> <t t-esc="page.string"/> </a> </li> @@ -1187,7 +1170,8 @@ <button type="button" class="oe_button oe_form_button" t-att-style="widget.node.attrs.style" t-att-tabindex="widget.node.attrs.tabindex" - t-att-autofocus="widget.node.attrs.autofocus"> + t-att-autofocus="widget.node.attrs.autofocus" + t-att-accesskey="widget.node.attrs.accesskey"> <img t-if="widget.node.attrs.icon" t-att-src="_s + widget.node.attrs.icon" width="16" height="16"/> <span t-if="widget.string"><t t-esc="widget.string"/></span> </button> @@ -1224,28 +1208,6 @@ </t> </t> -<t t-name="TranslateDialog"> - <table t-if="widget.view.translatable_fields" class="oe_form oe_translation_form" border="0" cellpadding="0" cellspacing="0" width="100%"> - <tr> - <td class="oe_form_separator" width="1%" nowrap="nowrap"> - <div class="oe_horizontal_separator">Field</div> - </td> - <th t-foreach="widget.languages" align="left"> - <div class="oe_horizontal_separator"><t t-esc="name"/></div> - </th> - </tr> - <tr t-foreach="widget.view.translatable_fields" t-as="field" t-att-data-field="field.name"> - <td class="oe_form_group_cell" width="1%" nowrap="nowrap"> - <label class="oe_label"><t t-esc="field.string"/>:</label> - </td> - <td t-foreach="widget.languages" t-as="lg" class="oe_form_group_cell"> - <input t-if="field.field.type == 'char'" type="text" t-attf-name="#{lg.code}-#{field.name}" value="" data-value="" class="oe_trad_field" style="width: 100%"/> - <textarea t-if="field.field.type == 'text'" t-attf-name="#{lg.code}-#{field.name}" data-value="" class="oe_trad_field" style="width: 100%"></textarea> - </td> - </tr> - </table> -</t> - <t t-name="AbstractFormPopup.render"> <div> <table style="width:100%"> |
