The following article applies to SharePoint 2010, SharePoint 2013, SharePoint 2016 and SharePoint Online.
Our team recently ran into an interesting issue where they needed to load multiple similar objects using the SharePoint JavaScript Object Model (JSOM).
They were nervous about the thought of having to load each of them into separate JavaScript variables. This was especially true because the number of objects to be loaded was going to be dynamic.
The scenario was this:
- Must display a list of all the SharePoint libraries and their views within a specific site
- Must be aware of JavaScript caching
- Using the jQuery UI accordion plugin in SharePoint
Typically, the team would put JavaScript code and CSS stylings into either a text file to be referenced by a Content Editor web part or, if just JavaScript, into a .JS file and use a Script Editor web part to load the file.
This will make your life so much easier when it’s time to make updates without having to edit the page > edit the web part > update the code > save the web part > save the page > and so on.
Step 1 – Let’s get JQuery Loaded
First, create a text file in the Site Assets library to store your code. We will need jQuery and jQuery UI so add that.
Just in case someone uses this on a page that has jQuery loaded, let’s check if it is there before loading. We will also need a DIV to stick our HTML in when we are done.
<script type="text/javascript">
if (typeof jQuery == "undefined") {
document.write("<script src='/sites/sharepointdemo/siteassets/js/jquery-2.2.4.min.js' type='text/javascript'><\/script>");
document.write("<script src='/sites/sharepointdemo/siteassets/js/jquery-ui.min.js' type='text/javascript'><\/script>");
document.write("<link rel='stylesheet' href='/sites/sharepointdemo/siteassets/js/jquery-ui.css' type='text/css'>");
}
else if (typeof jQuery.ui == "undefined") {
document.write("<script src='/sites/sharepointdemo/siteassets/js/jquery-ui.min.js' type='text/javascript'><\/script>");
document.write("<link rel='stylesheet' href='/sites/sharepointdemo/siteassets/js/jquery-ui.css' type='text/css'>");
}
</script>
<div id="libraryAccordion"></div>
Step 2 – Get the JavaScript NameSpace In Place
If you are not doing it yet, start. It doesn’t take that long to put in place and will save you from headaches in the future.
script type="text/javascript">
var IncWorx = IncWorx || {};
IncWorx.SP = IncWorx.SP || {};
IncWorx.SP.LibraryViews = {
allViews: [],
init: function () {}
}
</script>
Step 3 – Get SharePoint Client Context and Load Lists
Here we are going to create our client context object and query the site to find all lists/libraries. This code is going in the “init” function above.
// Add any list/library names you want to exclude
// Let's omit some SharePoint internal list/library names
var excludedLists = ["fpdatasources", "Master Page Gallery", "MicroFeed", "Site Assets", "Style Library", "Tasks", "TaxonomyHiddenList", "User Information List", "wfpub", "wfsvc", "Workflow History", "Workflow Tasks", "Workflows"];
// Add any specific view names you want to exclude
var excludedViewNames = [];
var context = new SP.ClientContext();
var web = context.get_web();
// Get all lists and libraries from the site
var lists = web.get_lists();
context.load(lists);
context.executeQueryAsync(
Function.createDelegate(this, function ()
{
// Code in next step
}),
Function.createDelegate(this, function (sender, args)
{
console.log(args.get_message());
})
);
Step 4 – Load an Array of SharePoint Objects
Here is where we will load all the View objects for the Lists/Libraries that we have retrieved. Since we don’t want to create a JavaScript variable for every single view object (realistically we can’t because it will be ever-changing), let’s add those objects into an array to reference later.
Function.createDelegate(this, function ()
{
var enumerator = lists.getEnumerator();
while (enumerator.moveNext())
{
var list = enumerator.get_current();
// If you want to only show document libraries
//if(list.get_baseType() == 1) // If you want to only show lists //if(list.get_baseType() == 0)
// We're going to exclude some OOTB SharePoint lists that we do not want to display
if (excludedLists.indexOf(list.get_title()) < 0)
{
// Create an object to store the views collection for the list/library
var viewObj = {
title: list.get_title(),
views: list.get_views()
};
// Add the object to an array to access later
IncWorx.SP.LibraryViews.allViews.push(viewObj);
context.load(viewObj.views);
}
}
}),
Here, we create a custom object “viewObj” with a property of title and views.
We need the title property so we know what List/Library those views are associated with.
The views property will ultimately contain the collection of SharePoint view objects that will be loaded from the Client Context.
We tell SharePoint to load each of the lists views and then we will run a single executeQueryAsync to get the information.
Step 5 – Process those Views!
Here is where we access those view objects in our array and start building the jQuery Accordion HTML.
IMPORTANT: Replace the red *** located in the code snippet below with a < .
context.executeQueryAsync(
Function.createDelegate(this, function ()
{
var finalContent = "";
// This is where we can access our array of objects loaded by SharePoint.
// We dynamically added the references into an Array
// No need for multiple JavaScript variables or multiple Execute Queries.
// We can just loop through the array.
for (var x = 0; x < IncWorx.SP.LibraryViews.allViews.length; x++)
{
var viewObj = IncWorx.SP.LibraryViews.allViews[x];
var viewsList = [];
finalContent += "<strong>" + viewObj.title + "</strong><div>";
var viewEnum = viewObj.views.getEnumerator();
while (viewEnum.moveNext()) {
var view = viewEnum.get_current();
var viewTitle = view.get_title();
// Skip any view names that we have chosen to ignore
if (viewTitle.length > 0 && excludedViewNames.indexOf(viewTitle) < 0) {
finalContent += "- ***a href='" + view.get_serverRelativeUrl() + "'>" + viewTitle + "</a><br>"
}
}
finalContent += "</div>"; //close the div surrounding the views
}
// Dump the HTML into our DIV and use the jQuery UI Accordion to make it look nice
$("#libraryAccordion").html(finalContent);
$("#libraryAccordion").accordion();
// Let’s put the final values into the Session cache so we don’t have to reload it each time – stays in cache as long as the tab is open
sessionStorage["LibraryViewCache"] = finalContent;
}),
Function.createDelegate(this, function (sender, args)
{
console.log(args.get_message());
})
);
The Final Result
Here we have all of the lists and views from a SharePoint site formatted nicely in a jQuery UI accordion.
Wrap Up and Final Code
What we have done here is load multiple SharePoint objects using a single JavaScript array so there is no need to create specific variables for each object.
Additionally, loading all of the objects using a single executeQueryAsync helps with the performance of the script.
A word of caution – SharePoint does have some limits on how many objects can be loaded with a single executeQueryAsync so be careful!
Our complete code:
<script type="text/javascript">
if (typeof jQuery == "undefined") {
document.write("<script src='/sites/sharepointdemo/siteassets/js/jquery-2.2.4.min.js' type='text/javascript'><\/script>");
document.write("<script src='/sites/sharepointdemo/siteassets/js/jquery-ui.min.js' type='text/javascript'><\/script>");
document.write("<link rel='stylesheet' href='/sites/sharepointdemo/siteassets/js/jquery-ui.css' type='text/css'>");
} else if (typeof jQuery.ui == "undefined") {
document.write("<script src='/sites/sharepointdemo/siteassets/js/jquery-ui.min.js' type='text/javascript'><\/script>");
document.write("<link rel='stylesheet' href='/sites/sharepointdemo/siteassets/js/jquery-ui.css' type='text/css'>");
}
</script>
<script type="text/javascript">
var IncWorx = IncWorx || {};
IncWorx.SP = IncWorx.SP || {};
IncWorx.SP.LibraryViews = {
allViews: [],
init: function() {
// Here we use the sessionStorage to cache the values
// For the duration that the browser tab/window is open
var librariesCache = sessionStorage["LibraryViewCache"] || "";
if (librariesCache && librariesCache.length > 0) {
$("#libraryAccordion").html(librariesCache);
$("#libraryAccordion").accordion();
return;
// No need to load the views since it has been loaded once already
}
// Add any list/library names you want to exclude
// Let's ommit some SharePoint internal list/library names
var excludedLists = ["appdata", "appfiles", "Cache Profiles", "Composed Looks", "fpdatasources", "Master Page Gallery", "MicroFeed", "Site Assets", "Style Library", "Tasks", "TaxonomyHiddenList", "User Information List", "wfpub", "wfsvc", "Workflow History", "Workflow Tasks", "Workflows"];
// Add any specific view names you want to exclude
var excludedViewNames = [];
var context = new SP.ClientContext();
var web = context.get_web();
// Get all of the lists from the site
var lists = web.get_lists();
context.load(lists);
context.executeQueryAsync(
function success() {
var enumerator = lists.getEnumerator();
while (enumerator.moveNext()) {
var list = enumerator.get_current();
// If you want to only show document libraries
//if(list.get_baseType() == 1)
// If you want to only show lists
//if(list.get_baseType() == 0)
// We're going to exclude some OOTB SharePoint lists that we do not want to display
if (excludedLists.indexOf(list.get_title()) < 0) {
// Create an object to store the views collection for the list/library
var viewObj = {
libraryTitle: list.get_title(),
views: list.get_views()
};
// Add the object to an array to access later
// We do this instead of creating variables for each view collection
IncWorx.SP.LibraryViews.allViews.push(viewObj);
// Tell SharePoint to load the view collection for this list
context.load(viewObj.views);
}
}
// Retrieve all of the view collection objects using a single executeQueryAsync
context.executeQueryAsync(
Function.createDelegate(this, function() {
var finalContent = "";
// This is where we can access our array of objects loaded by SharePoint.
// We dynamically added the references into an Array
// No need for multiple JavaScript variables or multiple Execute Queries.
// We can just loop through the array.
for (var x = 0; x < IncWorx.SP.LibraryViews.allViews.length; x++) {
var viewObj = IncWorx.SP.LibraryViews.allViews[x];
finalContent += "<h3>" + viewObj.libraryTitle + "</h3><div>";
var viewEnum = viewObj.views.getEnumerator();
while (viewEnum.moveNext()) {
var view = viewEnum.get_current();
var viewTitle = view.get_title();
// Skip any view names that we have chosen to ignore
if (viewTitle.length > 0 && excludedViewNames.indexOf(viewTitle) < 0) {
finalContent += "- <a href='" + view.get_serverRelativeUrl() + "'>" + viewTitle + "</a><br>"
}
}
finalContent += "</div>"; //close the div surrounding the views
}
// Dump the HTML into our DIV use the jQuery UI Accordion to make it look nice
$("#libraryAccordion").html(finalContent);
$("#libraryAccordion").accordion();
// Let’s put the final values into the Session cache
sessionStorage["LibraryViewCache"] = finalContent;
}),
Function.createDelegate(this, function(sender, args) {
console.log(args.get_message());
})
);
},
function onFail(sender, args) {
console.log(args.get_message());
});
}
}
// Tell SharePoint to execute the function after the ClientContext is available
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', IncWorx.SP.LibraryViews.init);
</script>
<div id="libraryAccordion"></div>