21 July 2015

Display Templates: Accordion

In this blogpost I will explain how to create an Accordion in SharePoint using Display Templates. I will use the Accordion in Unify to do this. It is a nice looking, space saving solution and its perfecty responsive for mobile devices without any extra effort. Unify is based on Bootstrap, which is a widely used, responsive platform. I would definitely recommend it.

We will base the Accordion on the Search Results Web Part. It will eventually look like this:



Start

The first step is downloading the Starter Display Templates, which you can find in my other blogpost. Save the files and give them a representative name. In case of our Accordion it could be something like 'AccordionControl' and 'AccordionItem'.

Upload the Display Templates (via the browser) to Display Templates -> Search, inside the Masterpage Gallery (Site Settings -> Web Designer Galleries -> Master pages and page layouts). When you uploaded the files, you will see JS files being generated with the same name. If not, something went wrong.

You could also use the 'New' button in the Display Templates folder to create new Display Templates. You should see the options 'Control Display Template' and 'Item Display Template' in the dropdown menu.

Now is a good time to map the Masterpage Library (if you have not done that already, read here how to do that). You can now use Explorer to open the Display Templates and directly edit them in Notepad++ or any other editor.

Content

We will get the Accordions content out of a Custom List. We don't need much more than what SharePoint already generates for us when creating a Custom List, but we do need one more input field, the one for the content of the Accordion items. In this content we should be able to add elements like images, tables and stuff like that, so what we need is a rich text field. There is no default input field in SharePoint that exactly fits our purpose, so we create our own. We don't create the field inside our Custom List, but instead we create it as a Site Column. Why? 1. Because it will have the Site-scope en therefore will be usable through our entire site instead of just the Custom List and 2. because a Site Column will automatically be mapped to a (new) Managed Property, which is exactly what we need to be able to call the value of the input field inside our Display Template.

  1. Navigate to the Site Columns pagina (Site Settings -> Web Designer Galleries -> Site Columns).
  2. Click Create.
  3. Give your Site Column a representative name (I chose 'Content' because of reusability), select Multiple lines of text, choose a generous amount of lines (25 for instance) at the option Number of lines for editing and check whether the option Enhanced rich text (Rich text with pictures, tables, and hyperlinks) is selected.
  4. Click OK.
  5. Your Site Column should now appear in the Site Columns list, default in 'Custom Columns', unless you filled in something different. Now navigate to the Managed Properties page (https://[JouwDomein].sharepoint.com/_layouts/15/listmanagedproperties.aspx?level=sitecol) and fill in your Site Column name in the searchbar. take a screenshot of what you see now (You will need this later, it is the easiest way). If you have an On Premise environment, now is the time to start a full crawl. If you work with SharePoint Online, you will have to wait for a crawl (usually that will take somewhere between 15 minutes and 24 hours to complete). After the crawl has finished, the Site Column should be mapped to a new Managed Property. SharePoint made up its own names for this Managed Property and personally I think it is a bit difficult to find it. The quickest way is to grab your screenshot, go back to the Managed Properties page, search for your Site Column name again and compare it to your screenshot to see which Managed Property is added. Write down the name of that new Managed Property, you will need it later in your Display Template.


  6. Now, create a Custom List and give it a representative name
  7. Go to the List Settings (Ribbon -> List -> List Settings).
  8. Scroll down to the Columns section and click Add from existing site columns, look for your Site Column and add it.
  9. Create a few list items and fill it up with some content.

Web Part

To be able to see the results of the changes we will make in de the Display Templates, we will first have to create the Web Part itself. As I previously mentioned, we will use the Search Results Web Part.

  1. Navigate to the page where you want to place the Accordion.
  2. >
  3. Add a Web Part to the desired Web Part zone.
  4. Choose the Search Results Web Part and click Add.
  5. The next step is to build a query to load the right data into the Web Part.
  6. Navigate to the Edit Web Part menu (see the arrow on the top right of the web part).
  7. Click the Change Query button.
  8. In the Basics tab (make sure Quick mode is activated, you can verify by the link on the top right of the tab-page Switch to Advanced Mode/Switch to Quick Mode) you see Select a query, choose Items matching a Tag (System).
  9. Next, you see Restrict by app, choose Specify a URL and provide the url to the Pictures library you created earlier.
  10. Restrict by tag should remain to Don't restrict by any tag.
  11. Click OK.
  12. Click Apply in the Web Part menu (do not click OK yet!).
  13. What you see now, probably does not impress you very much yet, but you should be able to see some content of the Pictures library now. Do not close the Web Part edit menu yet, because we are going to set the right Display Templates now.
  14. Click the + next to Display Templates.
  15. First, you will see a dropdown menu Results Control Display Template. In the dropdown menu you should find your own Control Display Template now, which you created earlier. Select it. (Don't see it? Did you publish?)
  16. Next are two radiobuttons. Select the second one which says: Use a single template to display items.
  17. Below this radiobutton there is another dropdown menu. You should find your own Item Display Template here. Select it.
  18. Close the + next to Display Templates.
  19. The Display Templates are now set, but we have to change a few other settings as well. These settings display some settings for users (like sorting and other stuff like that) in the Web Part which we don't want to see in an Accordion. So, we will disable them.
  20. Click the + next to Settings.
  21. Uncheck all checkboxes, accept Show ranked results (if we'd turn that one off as well, there will be no data in the Web Part at all).
  22. The number you see below Number of results per page doesn't matter, jQuery is going to take care of that, so you can leave it as it is.
  23. Close the + next to Settings.
  24. Default, SharePoint creates its own design around the web parts. In case of the Accordion, we want to limit this to just a Title, so we will adjust that.


  25. Click the + next to Appearance.
  26. Fill in a name for your Accordion inside the title input field.
  27. At the bottom you can see the Chrome Type setting, with a dropdown menu. Select Title Only in the dropdown.
  28. Click OK and save the page.

Well, that's all concerning the Web Part itself and its settings. It still does not look like an Accordion at all, so let's quickly start working on the Display Templates.

Display Templates

Like I mentioned in my previous blogpost, Display Templates work in sets, one as a wrapper for the whole thing (Control Display Template) and the second as a wrapper for individual items (Item Display Template). Let's start with the first one.

Control Display Template

The Control Display Template doesn't only hold the markup (HTML) for the Web Part, it also holds the references to all necessary CSS and JavaScript files. The latter is what we start with. You can download the necessary files below (upload them to the desired place in SharePoint):

Open your Control Display Template in Notepad++ (or any other editor) en replace everything in between the <script> tags by the code below:
$includeScript(this.url, "~sitecollection/[Path to file]/jquery.min.js");
$includeCSS(this.url, "~sitecollection/[Path to file]/bootstrap.css");
$includeCSS(this.url, "~sitecollection/[Path to file]/style.css");

The next step is loading and using the Javascript for Bootstrap. You should add the code below in between the <!--#_ and _#--> tags and after the line var siteURL = SP.PageContextInfo.get_siteAbsoluteUrl();. Furthermore we create an array, which will add the number-names to the Accordion items by a for-loop. This is needed to determine which item is 'expanded' and the rest will be 'collapsed'.
AddPostRenderCallback(ctx, function() {
$.getScript(siteURL + "/[path to file]/bootstrap.min.js");

var itemNumbers = ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight"];

for (var i = 0; i < ctx["CurrentItems"].length; i++) {
$("a.accordion-toggle").eq(i).attr("href", "#collapse-" + itemNumbers[i]);
$(".panel-collapse").eq(i).attr("id", "collapse-" + itemNumbers[i]);
}
});

Now we've loaded and developed everything we need in order to make the Accordion work. Now we have to build the Accordion itself, the markup (HTML) that is. First, add a class 'Accordion' to the first <div> (it is right above the code with which we just loaded the external files). Next, replace all HTML from the <div> with CSS class 'container' by the code below:
<div class="panel-group acc-v1" id="accordion-1">

</div>

Note: Don not remove the most outer div! It will no longer work if you do.

The final step is a small line of code which tells the Control Display Template where to render the Item Display Template. Add this line of code in between the <ul> tags:
_#= ctx.RenderItems(ctx) =#_

To top it all off you should give the Control Display Template a name, add it inside the <title> tag. That's all for the Control Display Template. Let's now move on to the Item Display Template.

Item Display Template

The first thing to do in the Item Display Template is to tell it which SharePoint columns we want to get. That's what the <mso:ManagedPropertyMapping msdt:dt="string"> tag does. You can see that it already contains some values, but we need to add one more: the custom Content we created earlier. We created the input field as a Site Column, which means it automatically got mapped to a Managed Property. This is where you need that Managed Property. In my case the Managed Property was named 'Content1OWSMTXT'. You should add your Managed Property to to the ManagedPropertyMapping tag like this:
'Content1OWSMTXT':'Content1OWSMTXT' Make sure that each set is separated by a comma.

Vervolgens moeten we het 'Content1OWSMTXT' veld aan een Javascript variabele koppelen. Dat doe je binnen de <!--#_ en _#--> tags, onder de regel var siteURL = SP.PageContextInfo.get_siteAbsoluteUrl();:

Next we have to connect the 'Content1OWSMTXT' column to a JavaScript variable. You can do that by adding the code below in between the <!--#_ and _#--> tags and after the line 'var siteURL = SP.PageContextInfo.get_siteAbsoluteUrl();':
var content = $getItemValue(ctx, "Content1OWSMTXT");

Finally we have to add the HTML that we want to render in every item. Replace all HTML from the <div> with CSS class 'item' with the code below:

<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a class="accordion-toggle" data-toggle="collapse" data-parent="collapse-One" href="#collapse-One">
_#= $htmlEncode(title) =#_
</a>
</h4>
</div>

<div id="collapse-One" class="panel-collapse collapse">
<div class="panel-body">
_#= STSHtmlDecode(content.value) =#_
</div>
</div>
</div>

Note: Don not remove the most outer div! It will no longer work if you do.

Notice here again all pieces of code starting with '_#='. These sentences use the JavaScript variables to call the SharePoint columns.

That's it! If you refresh the page on which you've placed the Accordion, you should be able to see it in all its glory ☺

To make it easy, you can download the examples of the finished files right here: