Disclaimer: This extension depends on client-side javascript and attaches JQuery, JQuery JSON and jStorage to documents that use it. |
Parameter Name | Description |
---|---|
Input Parameters (set with the macro call) | |
"tabbed-panel" | Enables this extension and sets a regular expression matching the section titles that should be transformed into a tabs.
Note: Setting this property has no effect in case of "source" or "source-class" were
specified with the macro call. This behaviour ensures that the parameter "tabbed-panel" can still be used
with ordinary macro calls where a source or source-class was set.
This parameter expects a regular expression that is used to select what sections turn into tabs and what not by matching
the given titles (headlines). By default the javascript looks for the first section that follows the include position and continues with all siblings (sections of the same level). Neither parent nor child sections are processed, therefore it's mostly safe to use the match all expression .* if all sub-sequent sections of the same nesting level should turn into tabs. Examples:
|
"hide-titles" | Toggles whether section titles are hidden once they were transformed into a tab (defaults to 'true'). |
"min-height" | Optional Parameter: Specifies a minimum tab height to improve scrolling behaviour when switching tabs. |
Implementation "org.tinyjee.maven.dim.extensions.TabbedPanelParameterTransformer": ApiDoc | Source |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | ------ Bundled Templates :: Tabbed Panel ------ Juergen Kellerer ------ 2011-11-06 ------ Bundled Templates :: Tabbed Panel %{include|source=disclaimers.xdoc.vm|clientSideJavaScript=JQuery, JQuery JSON and jStorage} * Reference %{include|source=addon-interface-table.xdoc.vm|source-java=org.tinyjee.maven.dim.extensions.TabbedPanelParameterTransformer} * Usage & Template Source ---------------- %{include|tabbed-panel=.*} ---------------- %{include|tabbed-panel=.*} * Example Some section content, above another nested panel: %{include|tabbed-panel=.*|hide-titles=false|min-height=200px} ** Sub Section 1 SubSection content A. ** Sub Section 2 SubSection content B. ** Sub Section 3 SubSection content C. * Page Source %{include|source=apt/templatesTabbedPanel.apt|source-content-type=text} * Template Sources %{include|tabbed-panel=.*} ** Velocity Template %{include|source=classpath:/templates/dim/tabbed-panel.html.vm|source-is-template=false} ** JS %{include|tabbed-panel=.*} *** tabbed-panel.js %{include|source=classpath:/templates/dim/js/tabbed-panel.js} *** section-finder.js %{include|source=classpath:/templates/dim/js/section-finder.js} ** CSS %{include|source=classpath:/templates/dim/css/tabbed-panel.css} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #* Implements a tabbed panel using JQuery and bundled style-sheets and images. When used, the javascript code looks after section titles that match the given regular expression and transforms them to tabs. The lookup strategy for the first section title is: - Find a div of class "section" below the DOM tree whose section title matches the regular expression. - If no title matched, traverse up the DOM tree and find a section title that matches the regular expression. Once the first title is found, all matching siblings are transformed to tabs as well. Notes: - When printing the document, the tabbed panel is hidden and all tags are shown. - The tabbed panel is not created at all when used with a non HTML sink. User suppliable parameters: "tabs" RegExp A regular expression that is used to select the section titles to include. "hide-titles" Boolean Toggles whether section titles are hidden when transformed into tabs. *# #dim_attachJs([ "jquery" , "jquery.json.min" , "jstorage.min" , "dim/js/section-finder" , "dim/js/tabbed-panel" ], $jsSuccess ) #dim_attachCss([ "dim/css/tabbed-panel" ], $cssSuccess ) #if ( $jsSuccess && $cssSuccess ) #dim_attachBinary( "dim/images/tabbed-panel-top-border.png" , $topBorderImage ) #dim_attachBinary( "dim/images/tabbed-panel-background.png" , $backgroundImage ) #dim_attachBinary( "dim/images/tabbed-panel-tab-background.png" , $tabBackgroundImage ) #dim_attachBinary( "dim/images/tabbed-panel-tab-left-corner.png" , $leftCornerImage ) #dim_attachBinary( "dim/images/tabbed-panel-tab-right-corner.png" , $rightCornerImage ) #if (! $tabs || $tabs == "*" ) #set($tabs = ".*") #end #if (! $hide -titles || $hide -titles == "false" ) #set ( $hide -titles = "false" ) #else #set ( $hide -titles = "true" ) #end #if (! $min -height) #set($min-height = "") #end #set ( $panelId = "tabbed-panel-" + $globals .nextLocalId()) < div class = "tabbed-panel" id = "$panelId" > < div class = "tabbed-panel-top-border" ></ div > < div class = "tabbed-panel-table" > < table border = "0" cellpadding = "0" cellspacing = "0" > < tr valign = "middle" ></ tr > </ table > </ div > < script type = "text/javascript" language = "javascript" > $(function () { jsDim.newTabbedPanel( $( "#$panelId" ), function(tabTitle) { return / ${tabs} /gi.test(tabTitle); }, { leftCornerImage: "$leftCornerImage", rightCornerImage: "$rightCornerImage", hideTitles: $hide-titles, minHeight: "$min-height" }); }); </ script > </ div > #end |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | /* * Copyright 2011 - Doxia :: Include Macro - Juergen Kellerer * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Creates the method "window.jsDim.newTabbedPanel(panelId, selectTitleCallback, configuration)" */ ( function (window) { /** * Creates a new tabbed panel. * * @param panelContainer The panel div to create the tabbed panel in. * @param selectTitleCallback A callback of the format <code>function(title) { return true/false; }</code> * @param config A object of the format: <code>{leftCornerImage: "", * rightCornetImage: "", minHeight: "", hideTitles: true/false}</code> */ function newTabbedPanel(panelContainer, selectTitleCallback, config) { var tabbedPanel = $(panelContainer); var tableRow = tabbedPanel.find( "tr" ).first(); var tabIndexStorageKey = createTabIndexStorageKey(tabbedPanel.attr( "id" )); var indexedTabs = [], indexedTabContents = jsDim.protectSections(jsDim.findSections(tabbedPanel, selectTitleCallback)); $.each(indexedTabContents, function (index, section) { var tabTitleElement = $(section).find( "h1,h2,h3,h4,h5,h6" ).first(); var tabTitle = tabTitleElement.text(); if (config.hideTitles) tabTitleElement.addClass( "inactive" ); if (config.minHeight != "" ) $(section).css( "minHeight" , /^[0-9]+$/.test(config.minHeight) ? config.minHeight + "px" : config.minHeight); indexedTabs[index] = $( "<td class='inactive'></td>" ).text(tabTitle).data( "index" , index).click( function () { $( "td.active" , tableRow).addClass( "inactive" ).removeClass( "active" ); $( "td.corner" , tableRow).hide(); $( this ).addClass( "active" ).removeClass( "inactive" ); $( this ).prev( "td" ).show(); $( this ).next( "td" ).show(); var selectedTabIndex = $( this ).data( "index" ); tabbedPanel.data( "selectedTabIndex" , selectedTabIndex); $.jStorage.set(tabIndexStorageKey, {index: selectedTabIndex, time: new Date().getTime()}); for ( var i = 0; i < indexedTabContents.length; i++) { var active = i == selectedTabIndex; indexedTabContents[i].addClass(active ? "active" : "inactive" ).removeClass(active ? "inactive" : "active" ); } }); $(section).addClass( "inactive" ); function cornerImageBuilder(src) { return "<td class='corner' style='display:none;'><img src='" + src + "' width='15' height='28'/></td>" ; } tableRow.append(cornerImageBuilder(config.leftCornerImage)); tableRow.append(indexedTabs[index]); tableRow.append(cornerImageBuilder(config.rightCornerImage)); }); // Add data to the tabbed-panel (div) to allow interaction via javascript. tabbedPanel.data( "selectedTabIndex" , -1); tabbedPanel.data( "indexedTabs" , indexedTabs); tabbedPanel.data( "indexedTabContents" , indexedTabContents); // Select one tab if (indexedTabs.length > 0) { clearOutdatedTabIndexStorageKeys(); var selectedTabIndex = Math.min($.jStorage.get(tabIndexStorageKey, {index: 0}).index, indexedTabs.length); indexedTabs[isNaN(selectedTabIndex) ? 0 : selectedTabIndex].click(); } } // Max age of a stored tab index key var maxStoredTabIndexAge = 60 * 60 * 1000; function createTabIndexStorageKey(panelId) { return "tab-index-" + document.location.href + "#" + panelId; } function clearOutdatedTabIndexStorageKeys() { var referenceTime = new Date().getTime(); $.each($.jStorage.index(), function (index, key) { if (/^tab-index-.*/.test(key)) { var value = $.jStorage.get(key); if (value && value.time && referenceTime - value.time > maxStoredTabIndexAge) $.jStorage.deleteKey(key); } }); } // Register in "window.jsDim" if (!window.jsDim) window.jsDim = {}; window.jsDim.newTabbedPanel = newTabbedPanel; })(window); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | /* * Copyright 2011 - Doxia :: Include Macro - Juergen Kellerer * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Creates the method "window.jsDim.findSections(jQuery, selectSectionTitleCallback)" */ ( function (window) { /** * Creates a new tabbed panel. * * @param startElement An arbitrary element to start with the search for sections. * @param selectSectionTitleCallback A callback of the format <code>function(title) { return true/false; }</code> * @return An array of jQuery objects containing the matching sections. */ function findSections(startElement, selectSectionTitleCallback) { var theSectionWeAreIn = $(startElement).closest( "div.section" ); var indexedSections = [], navigationType = 0, sections; while (indexedSections.length == 0) { switch (navigationType++) { case 0: // Find the first section below this and select siblings. sections = theSectionWeAreIn.find( "div.section" ).not( ".protected" ).first().nextAll( "div.section" ).andSelf(); break ; case 1: // Looking for the section we're currently in and select siblings. sections = theSectionWeAreIn.nextAll( "div.section" ).not( ".protected" ); break ; default : return []; } var index = 0; sections.each( function () { var tabTitle = $( this ).find( "h1,h2,h3,h4,h5,h6" ).first().text(); if (selectSectionTitleCallback(tabTitle)) indexedSections[index++] = $( this ); }); } return indexedSections; } /** * Protects the given sections from being selected again. * @param sections the sections to protect. * @return the given list of sections after protecting them. */ function protectSections(sections) { $.each(sections, function (index, section) { $(section).addClass( "protected" ); }); return sections; } // Register in "window.jsDim" if (!window.jsDim) window.jsDim = {}; window.jsDim.findSections = findSections; window.jsDim.protectSections = protectSections; })(window); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | /* * Copyright 2011 - Doxia :: Include Macro - Juergen Kellerer * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ div.tabbed-panel, .tabbed-panel div, .tabbed-panel img, .tabbed-panel td, .tabbed-panel tr, .tabbed-panel table { border : 0 ; margin : 0 ; padding : 0 ; } div.tabbed-panel { margin-top : 8pt ; margin-bottom : 4pt ; } div.tabbed-panel-top-border { background-image : url ( "../images/tabbed-panel-top-border.png" ); background-repeat : repeat-x ; height : 10px ; } div.tabbed-panel-table, .tabbed-panel-table table { background-image : url ( "../images/tabbed-panel-background.png" ); background-repeat : repeat-x ; height : 28px ; } .tabbed-panel-table table { width : auto ; } .tabbed-panel-table td { font-size : 11px ; line-height : 25px ; text-align : center ; white-space : nowrap ; cursor : pointer ; } .tabbed-panel-table td.active { background-image : url ( "../images/tabbed-panel-tab-background.png" ); background-repeat : repeat-x ; padding-left : 2px ; padding-right : 2px ; font-weight : bold ; } .tabbed-panel-table td.inactive { padding-left : 17px ; padding-right : 17px ; } div.section div.active { display : block ; } div.section div.inactive, h 1 .inactive, h 2 .inactive, h 3 .inactive, h 4 .inactive, h 5 .inactive, h 6 .inactive { display : none ; } /* hide the tabbed panel when printing the page */ @media print { div.tabbed-panel { display : none ; } div.section div.inactive, h 1 .inactive, h 2 .inactive, h 3 .inactive, h 4 .inactive, h 5 .inactive, h 6 .inactive { display : block ; } } |