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.
A possible solution
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>");
});
// level 1
$(".ms-rteElement-H1, .ms-rteElement-H1B").each(function(index, el) {
$(this).html(index + '. ' + $(this).text());
// level 2
$('.ms-rteElement-H2, .ms-rteElement-H2B', this).each(function(idx, child) {
$(this).html(index + '.' + idx + ' ' + $(this).text());
});
});
}
A solution that generates an ordered list, which should be able to work with deeper documents:
function levelClassName(level) {
if (typeof level !== "number") {
throw new Error("Wrong argument type");
}
return "ms-rteElement-H".concat(level.toString(10));
}
function elementLink(element) {
return $("<li></li>").text($(element).text());
}
function generateTOC() {
var level = 1, // list level
tocList = $("<ol></ol>"), // top level list
lastElement = tocList;
$("#toc").append('<p id="tocHeader">Contents</p>');
$("#toc").append(tocList);
$("span").each(function(index, value) {
// make a jQuery object out of current element once instead of doing it
// every time I want to use it
var element = $(value),
newElement;
if (element.hasClass(levelClassName(level))) { // same level
newElement = elementLink(value);
// append inside list tag or next to last tag if it isn't a list
lastElement[lastElement.prop("tagName") === "OL" ?
"append" :
"after"](newElement);
lastElement = newElement;
} else if (element.hasClass(levelClassName(level + 1))) { // deeper
newElement = elementLink(value);
// make a new list tag for the deeper level
lastElement.append($("<ol></ol>").append(newElement));
lastElement = newElement;
level += 1;
} else if (level - 1 >= 1 && // shallower
element.hasClass(levelClassName(level - 1))) {
newElement = elementLink(value);
lastElement // list element
.parent().parent() // -> list (on same level) -> list element above
.after(newElement);
lastElement = newElement;
level -= 1;
}
});
}
$(document).ready(generateTOC);
#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;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="toc"></div>
<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>
There is no code that makes links clickable. The best way to do that would be to give unique ids to every heading and then link to them in ToC.
Firebase Cloud Functions: PubSub, "res.on is not a function"
TypeError: Cannot read properties of undefined (reading 'createMessageComponentCollector')
I have the need to add checkbuttons to my table and I want use the Bootstrap Button for this
I am trying to scrape this website using scrapyThe page structure looks like this:
I'm not talking about the stuff within the tab, but the tab itselfAside from it looking weird, I'd like to closely emulate Mac's native look
I loaded a SVG image into UIWebView and it works fineBut when I try to render an object from UIWebView I can't get the object