I am putting together a Sharepoint wiki and on each article I have a wikipedia like table of contents from the headings using what I presume is a javascript that I found on the InterWebz.
<style>
#toc {
display: table;
border: 1px solid #aaa;
background-color: #f9f9f9;
font-size: 95%;
padding: 7px;
}
#toc #tocHeader {
font-weight: bold;
text-align: center;
}
#toc a:before { /* content:"• "; */ }
#toc a { line-height: 15px; margin: 10px; }
#toc .toc_Level1 { margin-left: 5px; }
#toc .toc_Level2 { margin-left: 15px; }
#toc .toc_Level3 { margin-left: 25px; }
#toc .toc_Level4 { margin-left: 35px; }
</style>
<div id="toc"></div>
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script type="text/javascript">
function GenerateTOC() {
$("#toc").append('<p id="tocHeader">Contents</p>');
$(".ms-rteElement-H1, .ms-rteElement-H1B, .ms-rteElement-H2, .ms-rteElement-H2B, .ms-rteElement-H3, .ms-rteElement-H3B, .ms-rteElement-H4, .ms-rteElement-H4B").each(function(i) {
var currentNode = $(this);
currentNode.attr("id", "title" + i);
var linkClass = (currentNode.hasClass('ms-rteElement-H1') || currentNode.hasClass('ms-rteElement-H1B'))
? "toc_Level1"
: (currentNode.hasClass('ms-rteElement-H2') || currentNode.hasClass('ms-rteElement-H2B'))
? "toc_Level2"
: (currentNode.hasClass('ms-rteElement-H3') || currentNode.hasClass('ms-rteElement-H3B'))
? "toc_Level3"
: (currentNode.hasClass('ms-rteElement-H4') || currentNode.hasClass('ms-rteElement-H4B'))
? "toc_Level4"
: "";
$("#toc").append("<a id='link'" + i + "' class='" + linkClass + "' href='#title" + i + "' title='" + currentNode.attr("tagName") + "'>" + currentNode.html() + "</a><br>");
currentNode.append(" <a href='#tocHeader'>[top]</a>");
});
}
_spBodyOnLoadFunctionNames.push('GenerateTOC');
</script>
My intention is to make the table of contents numbered separately for each level of indentation, e.g.:
1. Heading 1
1.1. Heading 2
1.2. Heading 2
2. Heading 1
2.1. Heading 2
2.2. Heading 2
Although I more or less understand what is happening in this code I have absolutely no knowledge of javascript (or web development for that matter - I have no idea how I got to what I am currently doing now to be honest), so I have very little idea how to implement it. I can see the function already has a counter to generate the internal link.
My strategy would be to put in two additional variables, say J and K (I have only two levels of indent), where J would increment only when it is level 1 heading (Element-H1, toc_Level1) and K would increment always but would get reset to 0 whenever level 1 heading (Element-H1, toc_Level1) is processed, however I have absolutely no idea how to make that happen.
EDIT:
I added the remaining parts of the javascript, however they only define the formatting of the table of contents, so I did not deem them relevant at first.
The website is structured as follows:
<span class="ms-rteElement-Name">NAME</span>
<hr/>
<span class="ms-rteElement-Section">Section1</span>
<hr/>
<span class="ms-rteStyle-Text">Stuff</span>
<p><span class="ms-rteElement-Section">Section2</span></p>
<hr/>
<p><span class="ms-rteStyle-Text">Fluff</span></p>
<p><span class="ms-rteElement-H1">Heading 1</span></p>
<p><span class="ms-rteStyle-Text">Fluff</span></p>
<p><span class="ms-rteElement-H2">Heading 2</span></p>
<p><span class="ms-rteStyle-Text">Fluff</span></p>
<p><span class="ms-rteElement-H2">Heading 2</span></p>
<p><span class="ms-rteStyle-Text">Fluff</span></p>
<p><span class="ms-rteElement-H1">Heading 1</span></p>
<p><span class="ms-rteStyle-Text">Fluff</span></p>
<p><span class="ms-rteElement-H2">Heading 2</span></p>
<p><span class="ms-rteStyle-Text">Fluff</span></p>
<p><span class="ms-rteElement-H2">Heading 2</span></p>
<p><span class="ms-rteStyle-Text">Fluff</span></p>
<span class="ms-rteElement-Section">Section3</span>
<hr/>
<p><span class="ms-rteStyle-Text">More fluff</span></p>
The script as given above generates the table of contents perfectly, just without the preceeding numbers of course.
So I have finally figured it out. Unfortunately none of the answers gave what was intended (one generated a ToC where the second level bullet missed also the corresponding higher level bullet and the hyperlink function was missing; the other was missing the numbering entirely).
The solution was to add additional variables under the GenerateTOC() function
var j = 0, k = 0;
And then put in conditional counter and counter reset based on the value of the linkClass variable and put them in the single text variable
linkClass == "toc_Level1"
? (j++, k = 0)
: linkClass == "toc_Level2"
? k++
: "";
var l = k == 0
? (String(j) + ". ")
: (String(j) + "." + String(k) + ". ");
The text variable then was added just in front of the "currentNode.html" in the line creating the ToC entry.
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script type="text/javascript">
function GenerateTOC() {
var j = 0, k = 0; // counters
$("#toc").append('<p id="tocHeader">Contents</p>');
$(".ms-rteElement-KD_Heading1, .ms-rteElement-KD_Heading2").each(function(i) {
var currentNode = $(this);
currentNode.attr("id", "title" + i);
var linkClass = (currentNode.hasClass('ms-rteElement-KD_Heading1') || currentNode.hasClass('ms-rteElement-H1B'))
? "toc_Level1"
: (currentNode.hasClass('ms-rteElement-KD_Heading2') || currentNode.hasClass('ms-rteElement-H2B'))
? "toc_Level2"
: "";
linkClass == "toc_Level1" // runs the counters
? (j++, k = 0)
: linkClass == "toc_Level2"
? k++
: "";
var l = k == 0 // concatenates the counters
? (String(j) + ". ")
: (String(j) + "." + String(k) + ". ");
$("#toc").append("<a id='link'" + i + "' class='" + linkClass + "' href='#title" + i + "' title='" + currentNode.attr("tagName") + "'>" + l + currentNode.html() + "</a><br>");
currentNode.append(" <a href='#tocHeader'>[top]</a>");
});
}
_spBodyOnLoadFunctionNames.push('GenerateTOC');
</script>