I put in a new feature this week that uses a Kendo Panel bar that binds to my existing table of contents that I incorporate for long posts. Galaxie Blog incorporates the WYSIWYG TinyMce TOC open-source plugin, so as long as I format my posts using headings, ie h2, h3, and h4, adding a table of contents is as easy as clicking on insert table of contents in my post. Using this technique, if you already have pre-existing HTML lists, you can easily incorporate the Kendo PanelBar into your code. 


Introducing the Kendo Panel Bar

The Kendo PanelBar is a hierarchical multi-level accordion-style widget that presents your main ideas while hiding some of the nested details. I have had a lot of positive feedback whenever I use this component and have been told that it invites the user to explore. I have found it to be an excellent widget to use as a table of contents for a blog post. 


Why Use Table of Contents for Your Post?

According to Tony Haile, the CEO of Chartbeat, you have 15 seconds to hold your reader's attention. It's important to allow the user to quickly figure out if your post is going to answer their questions. A table of contents presents an outline of your main ideas and allows users to quickly navigate to certain parts of your blog post. Google and other search engines also will read your table of contents and may feature your relevant content as a rich snippet.


Why should I use a Kendo PanelBar for a Table of Contents?

Even though having a table of contents can help, with long-winded technical blog posts, the table of contents itself can take more than 15 seconds to read! Hiding the sub-details (the nested bullet points in the list) will shorten the table of contents considerably while still allowing the users to expand to the detail that they need. Click on the images below to see the contrast between my original table of contents and my new table of contents presented using a Kendo PanelBar.

 

How to Automatically Generate a Table of Contents with Galaxie Blog

Galaxie Blogs Post Interface will automatically generate a table of contents for you if you format your headings with h2 through h4 HTML tags. This is simple to do using the WYSIWYG edit post interface. Once you have your headings in place, simply click on Insert - TOC. Click on the images below to see this in action.

  

Once you have a table of contents inserted, Galaxie Blog will automatically display your TOC using the Kendo PanelBar. No further action is needed. Continue reading to see how we implemented this technique. 

 

Using jQuery to Bind a Kendo PanelBar to a Table of Contents Generated by TinyMCE

If you're using a different blog engine that inserts a TinyMCE table of contents, you can also bind a KendoPanel bar to your table of contents, or any other properly formatted list, with very little code change, using this technique. 

As many of you already know, jQuery can be used to dynamically manipulate existing code. When the TinyMCE Table of Contents plugin generates a table of contents, it wraps that HTML list with a div element with the mce-toc class. The following div is generated on both the free version included with TinyMCE 5, and the paid TOC plugin that is offered with TinyMCE 6. 


<div class="mce-toc">

To generate the PanelBar on top of the table of contents, we need to use jQuery to append an ID to the first unordered list (<ul>). In my implementation, I am dynamically using jquery to append gtoc as the id (Galaxie Table of Contents) like so: <ul id='gtoc'>

The following JavaScript will find each div element with the class of mce-toc. This is done for every div with this class as the Galaxie Blog landing page contains multiple posts. Here, I am finding the unordered list inside this div element (<ul>) and appending it with the id of gtoc, and the index of the loop to differentiate each ul (gtoc1 on the first element found for example, gtoc2 for the second element, etc).

After generating the new id for the ul, I instantiate the Kendo Panel bar with the string "gtoc" and add the index, which would be "gtoc1" in the first occurrence of the loop. The second loop would have "gtoc2", etc. Finally, I am incrementing my index with tocLoop ++. Note that this needs to be done inside a document-ready loop. The code that performs both of these steps is displayed below.


$(document).ready(function() {
		
	// Create an accordian style panel for all table of contents. 
	// Append a gtoc id to *all* ul elements inside a mce-toc class
	try {
		// Create a loop counter
		var tocLoop = 0;
		// Loop through all classes with mce-toc
		$('.mce-toc').each(function(index,el){
			// Find the ul
			var selectedDiv = $(el).find('ul');
			// Append the ul with a gtoc + loopCounter
			selectedDiv =  selectedDiv.attr('id', 'gtoc' + tocLoop);

			// Create the panel bar
			$("#gtoc" + tocLoop).kendoPanelBar({
				expandMode: "single"
			});
			// Increment the loop
			tocLoop++;
		});
	} catch(err) {
		error = "Error generating Kendo Panel for TOC";
	}

});//..document.ready

You can use any HTML list to bind to the Kendo Panel. If you only have one list or want to bind to the first unordered list, you can simply use the following to construct the KendoPanel:


$( "ul" ).first().attr('id', 'gtoc');

$("#gtoc").kendoPanelBar({
	expandMode: "single"
});

Using scroll-margin-top to Prevent Links from Disappearing at the Top of the Page

When reading posts from Galaxie Blog, you will notice that there is a static div that contains various links (such as Menu, About, Themes, etc) when scrolling down the page. When the user clicks on one of the links in the Table of Contents, to prevent the browser from jumping to the top of the page and hiding the topmost portion of the content, I am using the scroll-margin-top CSS like so:


html {
	/* The scroll position needs to be adjusted due to the floating menu at the top of the page. When clicking on an anchor, without this, the content is behind the nav menu */
	scroll-padding-top: 70px; 
}

This one line of code puts a 70-pixel margin at the top of the page and stops the browser from jumping to the top of the page. The sticky navigation menu is 40 pixels wide and I am stopping 30 pixels short of the menu, which brings the content perfectly in line underneath the horizontal rule. 


Further Reading: