Changes for page Tabs macro

Last modified by Helge Dahl on 2018/01/22 10:41
From empty
To version 1.1
edited by Helge Dahl
on 2018/01/22 10:41
Change comment: Install extension [org.xwiki.contrib:xwiki-macro-tabs/1.0.2]

Summary

Details

Page properties
Title
... ... @@ -1,0 +1,1 @@
1 +Tabs macro
Parent
... ... @@ -1,0 +1,1 @@
1 +Macro.WebHome
Author
... ... @@ -1,1 +1,1 @@
1 -XWiki.XWikiGuest
1 +xwiki:XWiki.hde
Syntax
... ... @@ -1,1 +1,1 @@
1 -XWiki 2.1
1 +XWiki 2.0
Content
... ... @@ -1,0 +1,125 @@
1 +{{box cssClass="floatinginfobox" title="**Contents**"}}{{toc start="2" depth="6" numbered="false" scope="page" /}}{{/box}}
2 +
3 +{{velocity}}
4 +#macro(tabs $tabsKeyNames)
5 + ## for debugging, please
6 + ## 1) copy/paste the macro code from macro object into here
7 + ## 2) replace #set ($tabsSortedMapString = $context.macro.params.tabsKeyNames) with #set ($tabsSortedMapString = $tabsKeyNames)
8 +#end
9 +{{/velocity}}
10 +
11 +{{info}}This is home and test page for the "tabs" macro.{{/info}}
12 +Creates tabbed view for specified content areas wrapped in <div/>s with unique ids
13 +
14 +== Usage ==
15 +
16 +{{box}}
17 +1. Define where tabs should be rendered {{{{{tabs idsToLabels='tabId1=Tab One, tabId2=Tab Two, ..., tabIdN=Tab N' /}}}}}
18 +2. Define tabs content in {{{(%id="<unique tab id>"%)(((<tab content here>)))}}}:
19 + {{{(%id="tabId1"%)(((Tab 1 Content)))}}}
20 + {{{(%id="tabId2"%)(((Tab 2 Content)))}}}
21 + ...
22 + {{{(%id="tabIdN"%)(((Tab N Content)))}}}
23 +{{/box}}
24 +
25 +== Parameters definition ==
26 +
27 +|=Name |=Optional |=Allowed values |=Default value |=Description
28 +|idsToLabels |no |String | - |This parameter required a comma-separated tab id to tab label values sting formatted like idsToLabels='tabId1=Tab One, tabId2=Tab Two, tabId3=TabThree'.
29 +
30 +== Known issues ==
31 +* Tab size is fixed (toucan skin), labels that do not fit will get trimmed (see [[Tab name too long>>#HTabnametoolong?skin=toucan]])
32 +* Layout consistency is dependent on white-spaces (see [[Interesting layout bugs>>#HInterestinglayoutbugs]])
33 +
34 +== Examples ==
35 +
36 +=== Content generated by XWiki-wide macro ===
37 +{{tabs idsToLabels='tabId11=My xwiki-wide tabs, tabId12=My working tabs :)' /}}
38 +(%id="tabId11"%)((({{box cssClass="tabId11div"}}
39 +First tab!
40 +{{/box}}
41 +I can post any content here
42 +)))
43 +
44 +(%id="tabId12"%)((({{box cssClass="tabId12div"}}
45 +Second tab!
46 +{{/box}}
47 +And here too
48 +)))
49 +
50 +
51 +=== Known bugs example ===
52 +==== Tab name too long ====
53 +You should view this issue in [[Toucan>>#HTabnametoolong?skin=toucan]] skin.
54 +Content is generated from this code: ##~{~{tabs idsToLabels='sql2key1=Small tab, sql2key2=**Second large tab with large label**' /~}~}##
55 +{{tabs idsToLabels='sql2key1=Small tab, sql2key2=Second large tab with large label' /}}
56 +(%id="sql2key1"%)((({{code language="sql" }}
57 +SELECT COUNT(ctg_id) AS col_0_0_ FROM categories
58 +-- some text
59 +-- several lines
60 +-- of comments
61 +-- describing this sql query
62 +{{/code}})))
63 +
64 +(%id="sql2key2"%)((({{code language="sql"}}
65 +SELECT COUNT(ctg_id) AS col_0_0_ FROM categories2
66 +-- another tab with text
67 +
68 +-- Testing content overflow
69 +-- Text below this box ...
70 +-- ... should not get covered with it
71 +
72 +-- just check this!!!
73 +
74 +-- btw: no extra-paragraph has been added before the macro
75 +{{/code}})))
76 +
77 +==== Interesting layout bugs ====
78 +===== White spaces before ~(~%id =====
79 +{{tabs idsToLabels='sql3key1=Tab 1, sql3key2=Tab 2' /}}
80 + (%id="sql2key1"%)((({{code language="sql" }}
81 +SELECT COUNT(ctg_id) AS col_0_0_ FROM categories
82 +-- some text
83 +-- of comments
84 +-- describing this sql query
85 +{{/code}})))
86 +
87 +(%id="sql3key2"%)((({{code language="sql"}}
88 +SELECT COUNT(ctg_id) AS col_0_0_ FROM categories2
89 +-- another tab with text
90 +-- some text
91 +-- more lines in comments
92 +-- describing this sql query
93 +{{/code}})))
94 +
95 +===== White spaces before ~{~{code =====
96 +Check this bug in both [[Colibri>>#HWhitespacesbeforecode?skin=colibri]] and [[Toucan>>#HWhitespacesbeforecode?skin=toucan]] skins.
97 +{{tabs idsToLabels='sql4key1=Tab 1, sql4key2=Tab 2' /}}
98 +(%id="sql4key1"%)(((
99 + {{code language="sql" }}
100 +SELECT COUNT(ctg_id) AS col_0_0_ FROM categories
101 +-- some text
102 +-- of comments
103 +-- describing this sql query
104 +{{/code}})))
105 +
106 +(%id="sql4key2"%)(((
107 + {{code language="sql"}}
108 +SELECT COUNT(ctg_id) AS col_0_0_ FROM categories2
109 +-- another tab with text
110 +-- some text
111 +-- more lines in comments
112 +-- describing this sql query
113 +{{/code}})))
114 +
115 +=== Example for debugging ===
116 +Content generated by in-page macro (used for quick macro debugging).
117 +See instructions for debugging at the top of the page
118 +{{velocity}}#tabs('tabId31=Tab one, tabId32=Tab 2'){{/velocity}}
119 +(%id="tabId31"%)((({{box }}
120 +First tab content
121 +{{/box}})))
122 +
123 +(%id="tabId32"%)((({{box }}
124 +Second tab content
125 +{{/box}})))
XWiki.JavaScriptExtension[0]
Caching policy
... ... @@ -1,0 +1,1 @@
1 +long
Code
... ... @@ -1,0 +1,35 @@
1 +var TAB_LIST_ITEM_ID_PREFIX = "ListItem";
2 +
3 +function activateTab(activatedTabId) {
4 + // mark the tab itself as Active
5 + document.getElementById(activatedTabId + TAB_LIST_ITEM_ID_PREFIX).className = 'active';
6 + // show content pane
7 + var activatedTabContentDiv = document.getElementById(activatedTabId);
8 + if (activatedTabContentDiv) {
9 + activatedTabContentDiv.style.display = 'block';
10 + activatedTabContentDiv.style.margin = 0;
11 + }
12 +}
13 +
14 +function deactivateTabs(tabsIdsArray, activatedTabId) {
15 + var deactivatedTabContentDiv = null;
16 + for (var i = 0; i < tabsIdsArray.length; i++) {
17 + var deactivatedTabId = tabsIdsArray[i];
18 + if (activatedTabId == deactivatedTabId) {
19 + // skip this same tab
20 + continue;
21 + }
22 + // mark the tab itself as Inactive
23 + document.getElementById(deactivatedTabId + TAB_LIST_ITEM_ID_PREFIX).className = '';
24 + // hide div
25 + deactivatedTabContentDiv = document.getElementById(deactivatedTabId);
26 + if (deactivatedTabContentDiv) {
27 + deactivatedTabContentDiv.style.display = 'none';
28 + }
29 + }
30 +}
31 +
32 +function switchTab(activatedTabId, tabsIdsArray) {
33 + deactivateTabs(tabsIdsArray, activatedTabId);
34 + activateTab(activatedTabId);
35 +}
Name
... ... @@ -1,0 +1,1 @@
1 +TabHelper
Parse content
... ... @@ -1,0 +1,1 @@
1 +Yes
Use this extension
... ... @@ -1,0 +1,1 @@
1 +onDemand
XWiki.WikiMacroClass[0]
Macro code
... ... @@ -1,0 +1,64 @@
1 +{{velocity}}
2 + $xwiki.jsx.use("Macro.TabsMacro")
3 + #set ($tabsSortedMapString = $context.macro.params.idsToLabels)
4 + ## split incoming string into 2 velocity arrays
5 + #set ($tabMapEntriesStringArray = $tabsSortedMapString.split(','))
6 + #set( $tabIdsArray = [])
7 + #set( $tabNamesArray = [])
8 + #foreach($tabEntryString in $tabMapEntriesStringArray )
9 + #if ("$!tabEntryString" == "" )
10 + ## ignore null or empty (see http://wiki.apache.org/velocity/CheckingForNull)
11 + #else
12 + #set ($tabEntryArray = $tabEntryString.trim().split('='))
13 + #if ($tabEntryArray.size()!=2)
14 + {{error}}Parameter $tabEntryString is not a valid key=value pair in the provided map: $tabsSortedMapString{{/error}}
15 + #else
16 + #set ($addResult = $tabIdsArray.add($tabEntryArray.get(0).trim()))
17 + #set ($addResult = $tabNamesArray.add($tabEntryArray.get(1).trim()))
18 + #end
19 + #end
20 + #end
21 +## generate tabs
22 +
23 +
24 +{{html}}
25 +<div class="floatcontainer">
26 + <ul class="xwikitabbar">
27 + #set ($firstIteration=true)
28 + #foreach($tabId in $tabIdsArray)
29 + #set($count = $velocityCount - 1)
30 + #set ($tabName = $tabNamesArray.get($count))
31 + #if ($firstIteration) #set ($firstIteration=false)
32 + <li id="${tabId}ListItem" onclick="switchTab('${tabId}', #constructJsStringArray($tabIdsArray));" class="active"><a href="#" onclick="return false;">${tabName}</a></li>
33 + #else
34 + <li id="${tabId}ListItem" onclick="switchTab('${tabId}', #constructJsStringArray($tabIdsArray));"><a href="#" onclick="return false;">${tabName}</a></li>
35 + #end
36 + #end
37 + </ul>
38 +</div>
39 +## this script is responsible for initial content re-positioning
40 +<script language="JavaScript">
41 + ## set convenience variable
42 + #set ($firstTabId = $tabIdsArray.get(0))
43 + // approach borrowed from http://www.daniweb.com/forums/thread20256.html#
44 + var oldFunction${firstTabId} = null;
45 + function appendedOnLoadFunction() {
46 + if (oldFunction${firstTabId}) {
47 + oldFunction${firstTabId}();
48 + }
49 + switchTab('${firstTabId}', #constructJsStringArray($tabIdsArray));
50 + }
51 + function loadBody() {
52 + oldFunction${firstTabId} = window.onload;
53 + window.onload = appendedOnLoadFunction;
54 + }
55 + loadBody();
56 +</script>
57 +{{/html}}
58 +## give the array of strings constructs comma-separated list of
59 +## string values taken into single quotes and square brackets
60 +## e.g. ['item 1', 'item 2' , 'item 3']
61 +#macro(constructJsStringArray $stringArray)
62 +[#foreach($stringElement in $stringArray)'${stringElement}'#if( $velocityHasNext ), #end#end]
63 +#end
64 +{{/velocity}}
Macro content type
... ... @@ -1,0 +1,1 @@
1 +No content
Default category
... ... @@ -1,0 +1,1 @@
1 +Content
Macro description
... ... @@ -1,0 +1,1 @@
1 +Creates tabbed view for content areas wrapped into <div /> with unique id (see macro home for details)
Macro id
... ... @@ -1,0 +1,1 @@
1 +tabs
Macro name
... ... @@ -1,0 +1,1 @@
1 +Tabbed view renderer
Supports inline mode
... ... @@ -1,0 +1,1 @@
1 +Yes
Macro visibility
... ... @@ -1,0 +1,1 @@
1 +Current Wiki
XWiki.WikiMacroParameterClass[0]
Parameter description
... ... @@ -1,0 +1,2 @@
1 +Comma-separated list of name=value pairs e.g.
2 +'sql1key1=Original SQL, sql1key2=Substituted SQL, sql1key3=Resulting SQL'
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +Yes
Parameter name
... ... @@ -1,0 +1,1 @@
1 +idsToLabels