From 5f68c97560deb16f78ab3331e13e692981bc2c1e Mon Sep 17 00:00:00 2001
From: Moritz Bunkus
Date: Tue, 5 Feb 2013 14:35:30 +0100
Subject: [PATCH] Refactoring: DHTML-Tab-Dialog durch Variante aus jQuery-UI
ersetzt
---
SL/Form.pm | 12 +-
SL/Template/Plugin/L.pm | 27 +---
css/kivitendo/jquery-ui.custom.css | 92 ++++++++++++
css/kivitendo/tabcontent.css | 193 -------------------------
css/lx-office-erp/jquery-ui.custom.css | 94 ++++++++++++
css/lx-office-erp/tabcontent.css | 87 -----------
js/common.js | 9 +-
js/tabcontent.js | 159 --------------------
templates/webpages/am/config.html | 45 ++----
templates/webpages/ct/_contact.html | 2 -
templates/webpages/ct/_shipto.html | 1 -
templates/webpages/ct/form_footer.html | 5 -
templates/webpages/ct/form_header.html | 43 +++---
templates/webpages/ic/form_footer.html | 17 +--
templates/webpages/ic/form_header.html | 22 +--
templates/webpages/project/form.html | 45 ++----
16 files changed, 256 insertions(+), 597 deletions(-)
create mode 100644 css/kivitendo/jquery-ui.custom.css
delete mode 100644 css/kivitendo/tabcontent.css
create mode 100644 css/lx-office-erp/jquery-ui.custom.css
delete mode 100644 css/lx-office-erp/tabcontent.css
delete mode 100644 js/tabcontent.js
diff --git a/SL/Form.pm b/SL/Form.pm
index 94d3c566a..23ee18555 100644
--- a/SL/Form.pm
+++ b/SL/Form.pm
@@ -467,9 +467,10 @@ sub header {
# standard css for all
# this should gradually move to the layouts that need it
$layout->use_stylesheet("$_.css") for qw(
- main menu tabcontent list_accounts jquery.autocomplete
+ main menu list_accounts jquery.autocomplete
jquery.multiselect2side frame_header/header
ui-lightness/jquery-ui-1.8.12.custom
+ jquery-ui.custom
js/jscalendar/calendar-win2k-1
);
@@ -515,15 +516,6 @@ EOT
print " $_\n" for @header;
print <
-
diff --git a/SL/Template/Plugin/L.pm b/SL/Template/Plugin/L.pm
index 09eaf7227..189ef2dbe 100644
--- a/SL/Template/Plugin/L.pm
+++ b/SL/Template/Plugin/L.pm
@@ -464,27 +464,15 @@ sub tabbed {
next if $tab eq '';
- my $selected = $params{selected} == $i;
- my $tab_id = "__tab_id_$i";
- push @header, $self->li_tag(
- $self->link('', $tab->{name}, rel => $tab_id),
- ($selected ? (class => 'selected') : ())
- );
- push @blocks, $self->div_tag($tab->{data},
- id => $tab_id, class => 'tabcontent');
+ my $tab_id = "__tab_id_$i";
+ push @header, $self->li_tag($self->link('#' . $tab_id, $tab->{name}));
+ push @blocks, $self->div_tag($tab->{data}, id => $tab_id);
}
return '' unless @header;
- return $self->ul_tag(
- join('', @header), id => $id, class => 'shadetabs'
- ) .
- $self->div_tag(
- join('', @blocks), class => 'tabcontentstyle'
- ) .
- $self->javascript(
- qq|var $id = new ddtabcontent("$id");$id.setpersist(true);| .
- qq|$id.setselectedClassTarget("link");$id.init();|
- );
+
+ my $ul = $self->ul_tag(join('', @header), id => $id);
+ return $self->div_tag(join('', $ul, @blocks), class => 'tabwidget');
}
sub tab {
@@ -890,9 +878,6 @@ C. Example:
L.tab(LxERP.t8('Custom Variables'), 'part/_cvar_tab.html', if => SELF.display_cvar_tab),
]) %]
-An optional attribute is C, which accepts the ordinal of a tab which
-should be selected by default.
-
=item C
Creates a generic input tag or textarea tag, depending on content size. The
diff --git a/css/kivitendo/jquery-ui.custom.css b/css/kivitendo/jquery-ui.custom.css
new file mode 100644
index 000000000..e99327ff1
--- /dev/null
+++ b/css/kivitendo/jquery-ui.custom.css
@@ -0,0 +1,92 @@
+.tabwidget {
+ background: white;
+ position: relative;
+ padding: .2em;
+ zoom: 1;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+ border: 1px solid #dddddd;
+ color: #333333;
+ font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif;
+ font-size: 1.1em;
+}
+
+.tabwidget ul {
+ margin: 0;
+ padding: .2em .2em 0;
+ outline: 0;
+ line-height: 1.3;
+ text-decoration: none;
+ font-size: 100%;
+ font-weight: bold;
+ list-style: none;
+ display: block;
+ background: #dddddd;
+ border: 1px #dddddd;
+ color: #fe5f14;
+ margin: 0;
+ padding: .2em .2em 0;
+}
+
+.tabwidget ul::after {
+ content: ".";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+}
+
+.tabwidget ul li {
+ list-style: none;
+ float: left;
+ position: relative;
+ top: 1px;
+ margin: 0 .2em 1px 0;
+ border-bottom: 0 !important;
+ border-top-right-radius: 4px;
+ padding: 0;
+ white-space: nowrap;
+ border: 1px solid #cccccc;
+ background: #f6f6f6 url(ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x;
+ font-weight: bold;
+ color: #1c94c4;
+}
+
+.tabwidget ul li a { float: left; padding: .5em 1em; text-decoration: none; }
+.tabwidget ul li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
+.tabwidget ul li.ui-tabs-selected a, .tabwidget.ui-tabs-nav li.ui-state-disabled a, .tabwidget.ui-tabs-nav li.ui-state-processing a { cursor: text; }
+.tabwidget ul li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; }
+
+.tabwidget div {
+ display: none;
+}
+
+.tabwidget.ui-state-active {
+}
+
+.tabwidget .ui-widget-header {
+ background: #dddddd;
+ border: 1px #dddddd;
+ color: #fe5f14;
+}
+
+
+.tabwidget .ui-state-active a, .tabwidget .ui-state-active a:link, .tabwidget .ui-state-active a:visited {
+ color: #fe5f14;
+}
+
+.tabwidget .ui-state-active, .tabwidget.ui-widget-content .ui-state-active, .tabwidget .ui-widget-header .ui-state-active {
+ color: #fe5f14;
+}
+
+.tabwidget .ui-state-default a, .tabwidget .ui-state-default a:link {
+ color: #006400;
+}
+
+.tabwidget .ui-state-active a, .tabwidget .ui-state-active a:link {
+ color: #fe5f14;
+}
+
+.tabwidget .ui-state-hover a, .tabwidget .ui-state-hover a:hover {
+ color: #fe5f14;
+}
diff --git a/css/kivitendo/tabcontent.css b/css/kivitendo/tabcontent.css
deleted file mode 100644
index 093dcc5dd..000000000
--- a/css/kivitendo/tabcontent.css
+++ /dev/null
@@ -1,193 +0,0 @@
-/* ######### CSS for Shade Tabs. Remove if not using ######### */
-
-.shadetabs{
-padding: 3px 0;
-margin-left: 0;
-margin-top: 1px;
-margin-bottom: 0;
-font: bold 12px Verdana;
-list-style-type: none;
-text-align: left; /*set to left, center, or right to align the menu as desired*/
-}
-
-.shadetabs li{
-display: inline;
-margin: 0;
-}
-
-.shadetabs li a{
-text-decoration: none;
-position: relative;
-z-index: 1;
-padding: 3px 7px;
-margin-right: 3px;
-background-color:#A1A1A1;
-border-bottom: none ;
-color: #000000;
--moz-border-radius:0.4em 0.4em 0 0; /* Firefox */
--webkit-border-radius:0.4em 0.4em 0 0; /* Safari, Chrome */
--khtml-border-radius:0.4em 0.4em 0 0; /* Konqueror */
-border-radius:0.4em 0.4em 0 0 ; /* CSS3 */
-behavior:url(border-radius.htc);
-border-bottom: thin solid #FE5F14;
-}
-
-.shadetabs li a:visited{
-color: #000000;
-border: none;
-background-color:#A1A1A1;
-border-bottom: none ;
-}
-
-.shadetabs li a:hover{
-color: #FE5F14;
-background-color:#EBEBEB;
-}
-
-.shadetabs li a.selected{ /*selected main tab style */
-position: relative;
-top: 1px;
-background-color: #D1D1D1;
-color:#000000;
-}
-
-.shadetabs li a.selected{ /*selected main tab style */
-border-bottom-color:#EBEBEB;
-}
-
-.shadetabs li a.selected:hover{ /*selected main tab style */
-text-decoration: none;
-}
-
-.tabcontent{
-display:none;
-}
-
-@media print {
-.tabcontent {
-display:block !important;
-}
-}
-
-/* ######### CSS for Inverted Modern Bricks II Tabs. Remove if not using ######### */
-
-.modernbricksmenu2{
-padding: 0;
-width: 362px;
-border-top: 5px solid #D25A0B; /*Brown color theme*/
-background: transparent;
-voice-family: "\"}\"";
-voice-family: inherit;
-}
-
-.modernbricksmenu2 ul{
-margin:0;
-margin-left: 10px; /*margin between first menu item and left browser edge*/
-padding: 0;
-list-style: none;
-}
-
-.modernbricksmenu2 li{
-display: inline;
-margin: 0 2px 0 0;
-padding: 0;
-text-transform:uppercase;
-}
-
-.modernbricksmenu2 a{
-float: left;
-display: block;
-font: bold 11px Arial;
-color: white;
-text-decoration: none;
-margin: 0 1px 0 0; /*Margin between each menu item*/
-padding: 5px 10px;
-background-color: black; /*Brown color theme*/
-border-top: 1px solid white;
-}
-
-.modernbricksmenu2 a:hover{
-background-color: #D25A0B; /*Brown color theme*/
-color: white;
-}
-
-.modernbricksmenu2 a.selected{ /*currently selected tab*/
-background-color: #D25A0B; /*Brown color theme*/
-color: white;
-border-color: #D25A0B; /*Brown color theme*/
-}
-
-.tabcontent{
-display:none;
-}
-
-@media print {
-.tabcontent {
-display:block !important;
-}
-}
-
-/* ######### CSS for Indented CSS Tabs. Remove if not using ######### */
-
-
-.indentmenu{
-font: bold 13px Arial;
-width: 100%; /*leave this value as is in most cases*/
-}
-
-.indentmenu ul{
-margin: 0;
-padding: 0;
-float: left;
-/* width: 80%; width of menu*/
-border-top: 1px solid navy; /*navy border*/
-background: black url(../image/indentbg.gif) center center repeat-x;
-}
-
-.indentmenu ul li{
-display: inline;
-}
-
-.indentmenu ul li a{
-float: left;
-color: white; /*text color*/
-padding: 5px 11px;
-text-decoration: none;
-border-right: 1px solid navy; /*navy divider between menu items*/
-}
-
-.indentmenu ul li a:visited{
-color: white;
-}
-
-.indentmenu ul li a.selected{
-color: white !important;
-padding-top: 6px; /*shift text down 1px*/
-padding-bottom: 4px;
-background: black url(../image/indentbg2.gif) center center repeat-x;
-}
-
-
-.tabcontentstyle{ /*style of tab content oontainer*/
-/* border: 1px solid #D2691E; */
-width: 95%;
-margin-bottom: 1em;
-padding: 10px;
--moz-border-radius:0 0 0.4em 0.4em; /* Firefox */
--webkit-border-radius:0 0 0.4em 0.4em; /* Safari, Chrome */
--khtml-border-radius:0 0 0.4em 0.4em; /* Konqueror */
-border-radius:0 0 0.4em 0.4em; /* CSS3 */
-behavior:url(border-radius.htc);
-border: thin solid #A1A1A1;
-
-}
-
-.tabcontent{
-display:none;
-}
-
-@media print {
-.tabcontent {
-display:block !important;
-}
-}
diff --git a/css/lx-office-erp/jquery-ui.custom.css b/css/lx-office-erp/jquery-ui.custom.css
new file mode 100644
index 000000000..f248f2fb9
--- /dev/null
+++ b/css/lx-office-erp/jquery-ui.custom.css
@@ -0,0 +1,94 @@
+.tabwidget {
+ background: none;
+ position: relative;
+ padding: .2em;
+ zoom: 1;
+ -webkit-border-radius: 0;
+ border-radius: 0;
+ border: 1px solid #000000;
+ color: #000000;
+ font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif;
+ font-size: 1.1em;
+}
+
+.tabwidget ul {
+ margin: 0;
+ padding: .2em .2em 0;
+ outline: 0;
+ line-height: 1.3;
+ text-decoration: none;
+ font-size: 100%;
+ font-weight: bold;
+ list-style: none;
+ display: block;
+ background: url("../../image/fade.png");
+ border: 0;
+ color: #000000;
+ margin: 0;
+ padding: .2em .2em 0;
+}
+
+.tabwidget ul::after {
+ content: ".";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+}
+
+.tabwidget ul li {
+ list-style: none;
+ float: left;
+ position: relative;
+ top: 1px;
+ margin: 0 .2em 1px 0;
+ border-bottom: 0 !important;
+ border-top-right-radius: 0;
+ padding: 0;
+ white-space: nowrap;
+ border: 1px solid #cccccc;
+ background: #f6f6f6 url(ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x;
+ font-weight: bold;
+ color: #000000;
+}
+
+.tabwidget ul li a { float: left; padding: .5em 1em; text-decoration: none; }
+.tabwidget ul li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
+.tabwidget ul li.ui-tabs-selected a, .tabwidget.ui-tabs-nav li.ui-state-disabled a, .tabwidget.ui-tabs-nav li.ui-state-processing a { cursor: text; }
+.tabwidget ul li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; }
+
+.tabwidget div {
+ display: none;
+}
+
+.tabwidget.ui-state-active {
+}
+
+.tabwidget .ui-widget-header {
+ background: url("../../image/fade.png");
+ border: 0;
+ color: #000000;
+}
+
+
+.tabwidget .ui-state-active a, .tabwidget .ui-state-active a:link, .tabwidget .ui-state-active a:visited {
+ color: #000000;
+}
+
+.tabwidget .ui-state-active, .tabwidget.ui-widget-content .ui-state-active, .tabwidget .ui-widget-header .ui-state-active {
+ color: #000000;
+}
+
+.tabwidget .ui-state-default a, .tabwidget .ui-state-default a:link {
+ color: #999999;
+}
+
+.tabwidget .ui-state-active a, .tabwidget .ui-state-active a:link {
+ color: #000000;
+ text-decoration: underline;
+}
+
+.tabwidget .ui-state-hover a, .tabwidget .ui-state-hover a:hover {
+ color: #000000;
+ text-decoration: underline;
+}
diff --git a/css/lx-office-erp/tabcontent.css b/css/lx-office-erp/tabcontent.css
deleted file mode 100644
index bba23b3f3..000000000
--- a/css/lx-office-erp/tabcontent.css
+++ /dev/null
@@ -1,87 +0,0 @@
-/* ######### CSS for Shade Tabs. Remove if not using ######### */
-
-.shadetabs{
-padding: 3px 0;
-margin-left: 0;
-margin-top: 1px;
-margin-bottom: 0;
-font: bold 12px Verdana, sans-serif;
-list-style-type: none;
-text-align: left; /*set to left, center, or right to align the menu as desired*/
-}
-
-.shadetabs li{
-display: inline;
-margin: 0;
-}
-
-.shadetabs li a{
-text-decoration: none;
-position: relative;
-z-index: 1;
-padding: 3px 7px;
-margin-right: 3px;
-border: 1px solid #778;
-color: #2d2b2b;
-background: white url(../../image/shade.gif) top left repeat-x;
-}
-
-.shadetabs li a:visited{
-color: #2d2b2b;
-}
-
-.shadetabs li a:hover{
-text-decoration: underline;
-color: #2d2b2b;
-}
-
-.shadetabs li a.selected{ /*selected main tab style */
-position: relative;
-top: 1px;
-}
-
-.shadetabs li a.selected{ /*selected main tab style */
-background-image: url(../../image/shadeactive.gif);
-border-bottom-color: white;
-}
-
-.shadetabs li a.selected:hover{ /*selected main tab style */
-text-decoration: none;
-}
-
-.tabcontent{
-display:none;
-}
-
-@media print {
-.tabcontent {
-display:block !important;
-}
-}
-
-.tabcontent{
-display:none;
-}
-
-@media print {
-.tabcontent {
-display:block !important;
-}
-}
-
-.tabcontentstyle{ /*style of tab content oontainer*/
-border: 1px solid gray;
-width: 95%;
-margin-bottom: 1em;
-padding: 10px;
-}
-
-.tabcontent{
-display:none;
-}
-
-@media print {
-.tabcontent {
-display:block !important;
-}
-}
diff --git a/js/common.js b/js/common.js
index cabc6507e..e40b9abfe 100644
--- a/js/common.js
+++ b/js/common.js
@@ -61,13 +61,13 @@ function check_right_number_format(input_name) {
var forbidden = test_val.match(/[^\s\d\(\)\-\+\*\/\.]/g);
if (forbidden && forbidden.length > 0 ){
return show_alert_and_focus(input_name, wrongNumberFormat);
- }
+ }
- try{
+ try{
eval(test_val);
}catch(err){
return show_alert_and_focus(input_name, wrongNumberFormat);
- }
+ }
}
@@ -161,6 +161,9 @@ function focus_by_name(name){
}
$(document).ready(function () {
+ // initialize all jQuery UI tab elements:
+ $(".tabwidget").each(function(idx, element) { $(element).tabs(); });
+
$('input').focus(function(){
if (focussable(this)) window.focused_element = this;
});
diff --git a/js/tabcontent.js b/js/tabcontent.js
deleted file mode 100644
index 62f842d07..000000000
--- a/js/tabcontent.js
+++ /dev/null
@@ -1,159 +0,0 @@
-//** Tab Content script v2.0- © Dynamic Drive DHTML code library (http://www.dynamicdrive.com)
-//** Updated Oct 7th, 07 to version 2.0. Contains numerous improvements:
-// -Added Auto Mode: Script auto rotates the tabs based on an interval, until a tab is explicitly selected
-// -Ability to expand/contract arbitrary DIVs on the page as the tabbed content is expanded/ contracted
-// -Ability to dynamically select a tab either based on its position within its peers, or its ID attribute (give the target tab one 1st)
-// -Ability to set where the CSS classname "selected" get assigned- either to the target tab's link ("A"), or its parent container
-//** Updated Feb 18th, 08 to version 2.1: Adds a "tabinstance.cycleit(dir)" method to cycle forward or backward between tabs dynamically
-//** Updated April 8th, 08 to version 2.2: Adds support for expanding a tab using a URL parameter (ie: http://mysite.com/tabcontent.htm?tabinterfaceid=0)
-
-////NO NEED TO EDIT BELOW////////////////////////
-
-function ddtabcontent(tabinterfaceid){
- this.tabinterfaceid=tabinterfaceid //ID of Tab Menu main container
- this.tabs=document.getElementById(tabinterfaceid).getElementsByTagName("a") //Get all tab links within container
- this.enabletabpersistence=true
- this.hottabspositions=[] //Array to store position of tabs that have a "rel" attr defined, relative to all tab links, within container
- this.currentTabIndex=0 //Index of currently selected hot tab (tab with sub content) within hottabspositions[] array
- this.subcontentids=[] //Array to store ids of the sub contents ("rel" attr values)
- this.revcontentids=[] //Array to store ids of arbitrary contents to expand/contact as well ("rev" attr values)
- this.selectedClassTarget="link" //keyword to indicate which target element to assign "selected" CSS class ("linkparent" or "link")
-}
-
-ddtabcontent.getCookie=function(Name){
- var re=new RegExp(Name+"=[^;]+", "i"); //construct RE to search for target name/value pair
- if (document.cookie.match(re)) //if cookie found
- return document.cookie.match(re)[0].split("=")[1] //return its value
- return ""
-}
-
-ddtabcontent.setCookie=function(name, value){
- document.cookie = name+"="+value+";path=/" //cookie value is domain wide (path=/)
-}
-
-ddtabcontent.prototype={
-
- expandit:function(tabid_or_position){ //PUBLIC function to select a tab either by its ID or position(int) within its peers
- this.cancelautorun() //stop auto cycling of tabs (if running)
- var tabref=""
- try{
- if (typeof tabid_or_position=="string" && document.getElementById(tabid_or_position).getAttribute("rel")) //if specified tab contains "rel" attr
- tabref=document.getElementById(tabid_or_position)
- else if (parseInt(tabid_or_position)!=NaN && this.tabs[tabid_or_position].getAttribute("rel")) //if specified tab contains "rel" attr
- tabref=this.tabs[tabid_or_position]
- }
- catch(err){alert("Invalid Tab ID or position entered!")}
- if (tabref!="") //if a valid tab is found based on function parameter
- this.expandtab(tabref) //expand this tab
- },
-
- cycleit:function(dir, autorun){ //PUBLIC function to move foward or backwards through each hot tab (tabinstance.cycleit('foward/back') )
- if (dir=="next"){
- var currentTabIndex=(this.currentTabIndex0)? this.currentTabIndex-1 : this.hottabspositions.length-1
- }
- if (typeof autorun=="undefined") //if cycleit() is being called by user, versus autorun() function
- this.cancelautorun() //stop auto cycling of tabs (if running)
- this.expandtab(this.tabs[this.hottabspositions[currentTabIndex]])
- },
-
- setpersist:function(bool){ //PUBLIC function to toggle persistence feature
- this.enabletabpersistence=bool
- },
-
- setselectedClassTarget:function(objstr){ //PUBLIC function to set which target element to assign "selected" CSS class ("linkparent" or "link")
- this.selectedClassTarget=objstr || "link"
- },
-
- getselectedClassTarget:function(tabref){ //Returns target element to assign "selected" CSS class to
- return (this.selectedClassTarget==("linkparent".toLowerCase()))? tabref.parentNode : tabref
- },
-
- urlparamselect:function(tabinterfaceid){
- var result=window.location.search.match(new RegExp(tabinterfaceid+"=(\\d+)", "i")) //check for "?tabinterfaceid=2" in URL
- return (result==null)? null : parseInt(RegExp.$1) //returns null or index, where index (int) is the selected tab's index
- },
-
- expandtab:function(tabref){
- var subcontentid=tabref.getAttribute("rel") //Get id of subcontent to expand
- //Get "rev" attr as a string of IDs in the format ",john,george,trey,etc," to easily search through
- var associatedrevids=(tabref.getAttribute("rev"))? ","+tabref.getAttribute("rev").replace(/\s+/, "")+"," : ""
- this.expandsubcontent(subcontentid)
- this.expandrevcontent(associatedrevids)
- for (var i=0; i500 && this.hottabspositions.length>1){
- this.autoruntimer=setInterval(function(){tabinstance.autorun()}, this.automodeperiod)
- }
- } //END int() function
-
-} //END Prototype assignment
\ No newline at end of file
diff --git a/templates/webpages/am/config.html b/templates/webpages/am/config.html
index 5921dd2b2..18af43224 100644
--- a/templates/webpages/am/config.html
+++ b/templates/webpages/am/config.html
@@ -1,24 +1,20 @@
[%- USE T8 %]
[%- USE LxERP %]
[%- USE HTML %][%- USE L %]
-
-
[% title %]
-
+ [% title %]