
Site maps or site directory is a road map that lets you travel through your site and locate the contents very easy.
In this article today we will create a dynamic Site map using Jquery and Rest which can be used in any SharePoint environment either on premise or SharePoint online. The solutions will be a complete client side based application which doesn’t require server side access at all.
Features of the SiteMap
- Site hierarchy starts from the site where you place the code
-
- If your code is linked to site collection level then the hierarchy starts from site collection and it drills down all the way until the last sub-site present.
- It displays the sub-site and lists title of the site with a link to the site and list location
- Expand and collapse in each site to show and hide contents, sub-sites and lists
- Works for SharePoint online and On premise
Code
Add an HTML file and save it to a safe location. This html file should be at least read only to all the users inside the site collection.
We use Jquery,Rest api and CSS to write the whole application and save it in the html file.
Put all these code into your html file
Javascript
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" type="text/javascript"> </script><script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" type="text/javascript"></script> <script type="text/javascript" src="https://code.jquery.com/ui/1.11.1/jquery-ui.min.js"></script> <script type="text/javascript"> var url = _spPageContextInfo.webServerRelativeUrl; var webapplicationurl=window.location.protocol + "//" + window.location.host; var cur_url= webapplicationurl+url;var title= _spPageContextInfo.webTitle; $(document).ready(function () { $("#parent_site").attr('href',cur_url); $("#parent_site").text(title); /*opens up the site contents that displays links to subsites and lists*/ $(document).on('click', '.expand', function(){ var web_url=$(this).next('.texts').find('a').attr('href'); var randomno= web_url.replace(/[_\W]+/g,""); $(this).attr("id",randomno); $(this).removeClass("expand"); $(this).addClass("collapse"); $(this).parent().find('.site_contents').show(); $(this).attr('title','Hide site contents'); $.ajax({ url:web_url+"/_api/web/webinfos?$select=ServerRelativeUrl,Title,LastItemModifiedDate", method: "GET", headers: { "Accept": "application/json; odata=verbose" }, success: function (data) { if (data.d.results.length<1) { var html=" <div class='site_contents'>No Subsite Present <div class='lists_cont' weburl="+web_url+"> <div title='Display Lists' class='lists_expand'></div> <label class='Title'>Lists</label> <ul class='ul_lists'></ul> </div> </div> "; $('#'+randomno).parent().append(html); } else{ var html=" <div class='site_contents'> <div class='subsite_cont'> <div title='Display Subsites' class='subsite_expand'></div> <label class='Title'>Subsites("+data.d.results.length+")</label> <ul class='ul_subsite'></ul> </div> <div class='lists_cont'> <div title='Display Lists' class='lists_expand'></div> <label class='Title'>Lists</label> <ul class='ul_lists'></ul> </div> </div> "; $('#'+randomno).parent().append(html); $('#'+randomno).parent().find('.site_contents:first').find('.subsite_cont:first').attr('weburl',web_url); $('#'+randomno).parent().find('.site_contents:first').find('.lists_cont:first').attr('weburl',web_url); } } }); }); /*add subsites*/ $(document).on('click', '.subsite_expand', function() { var web_url=$(this).parent().attr('weburl'); var randomno= web_url.replace(/[_\W]+/g,"")+"site"; $(this).attr("id",randomno); $(this).removeClass("subsite_expand"); $(this).addClass("subsite_collapse"); $(this).attr('title','Hide Subsites'); $.ajax({ url:web_url+"/_api/web/webinfos?$select=ServerRelativeUrl,Title,LastItemModifiedDate", method: "GET", headers: { "Accept": "application/json; odata=verbose" }, success: function (data) { $.each(data.d.results, function() { var html=" <li> <div class='container' weburl="+this.ServerRelativeUrl+"> <div title='Show site contents' class='expand'></div> <div class='texts'><a href="+webapplicationurl+this.ServerRelativeUrl+">"+this.Title+"</a>" +"</div> </div></li> "; $('#'+randomno).parent().find('ul').append(html); }); } }); }); /*add lists*/ $(document).on('click', '.lists_expand', function(){ var web_url=$(this).parent().attr('weburl'); var randomno= web_url.replace(/[_\W]+/g,"")+"lists"; $(this).attr("id",randomno); $(this).removeClass("lists_expand"); $(this).addClass("lists_collapse"); $(this).attr('title','Hide Lists'); $.ajax({ url:web_url+"/_api/Web/lists?$filter=Hidden eq false", method: "GET", headers: { "Accept": "application/json; odata=verbose" }, success: function (data) { $.each(data.d.results,function(){ /* You can use a following approach here as well, this link takes you to the list settings page for all lists. $('#'+randomno).parent().find('ul').append(" <li><a target='_blank' title='Go to list page' href="+web_url+"_layouts/15/listedit.aspx?List==%7B"+this.Id+"=%7D>"+this.Title +"</a></li> "); */ if(this.BaseType==0) {$('#'+randomno).parent().find('ul').append(" <li><a target='_blank' title='Go to list page' href="+web_url+"/lists/"+this.EntityTypeName.replace("List","").replace(new RegExp("_x0020_", "g")," ").replace(new RegExp("_x005f_", "g"),"_") +">"+this.Title +"</a></li> "); } else{ $('#'+randomno).parent().find('ul').append(" <li><a target='_blank' title='Go to list page' href=" + web_url+ "/"+this.EntityTypeName.replace(new RegExp("_x0020_", "g")," ").replace(new RegExp("_x005f_", "g"),"_") +">"+this.Title + "</a></li> "); } }); } }); }); /*site contents collapse to hide site contents*/ $(document).on('click', '.collapse', function(){ $(this).removeClass("collapse"); $(this).addClass("expand"); $(this).parent().find('.site_contents').remove(); $(this).attr('title','Show site contents'); }); /*subsite contents hide*/ $(document).on('click', '.subsite_collapse', function(){ $(this).removeClass("subsite_collapse"); $(this).addClass("subsite_expand"); $(this).parent().find('.ul_subsite').empty(); $(this).attr('title','Show Subsites'); }); /*site lists hide*/ $(document).on('click', '.lists_collapse', function(){ $(this).removeClass("lists_collapse"); $(this).addClass("lists_expand"); $(this).parent().find('.ul_lists').empty(); $(this).attr('title','Show Lists'); }); }); </script>
CSS
<style type="text/css"> .subsite_expand{ background-image:URL('/Style%20Library/SiteImages/Plus.jpg'); background-repeat:no-repeat; height:14px; width:14px; padding-right:10px; float:left; } .subsite_collapse{ background-image:URL('/Style%20Library/SiteImages/minus.jpg'); background-repeat:no-repeat; height:14px; width:14px; padding-right:12px; float:left; } .lists_expand{ background-image:URL('/Style%20Library/SiteImages/Plus.jpg'); background-repeat:no-repeat; height:14px; width:14px; padding-right:10px; float:left; } .lists_collapse{ background-image:URL('/Style%20Library/SiteImages/minus.jpg'); background-repeat:no-repeat; height:14px; width:14px; padding-right:12px; float:left; } .expand{ background-image:URL('/Style%20Library/SiteImages/Plus.jpg'); background-repeat:no-repeat; height:14px; width:14px; padding-right:10px; float:left; margin-top:5px; } .collapse{ background-image:URL('/Style%20Library/SiteImages/minus.jpg'); background-repeat:no-repeat; height:14px; width:14px; padding-right:12px; float:left; margin-top:5px; } li.parentsitcol{ display: flex; background-color:#0072C6; padding:5PX; margin-bottom:4px; } .texts{ min-width:350px; text-align: center; font-size: 18px; padding: 2px; } .texts a{ text-decoration:none; color:white; } ul.ul_subsite { padding-left: 0px; margin-top: 20px; margin-left: -40px; background-color:#ebeff3; } .ul_subsite li{ display: inline; float: left; border: medium; background-color: #5cabf1; margin: 5px; padding: 5px; } .subsite_cont { padding: 10px; display:flex; } .site_contents { background-color: #9ccaf3; padding: 10px; } label.Title { height: 25px; padding-left: 10px; font-weight: 600; font-size: 16px; } .lists_cont { display: flex; margin:10px; } .ul_lists li { display: inline-flex; margin: 5px; background-color: #0072c6; padding: 5px; } ul.ul_lists { list-style: none; padding-left: 0px; margin-top: 20px; background-color: #f1f1f1; } .ul_lists li a { color: white; font-style: italic; text-decoration: underline; color: #fff; } .poc { font-size: 14px; color: #cbf10b; font-weight: bold; padding:4px; } .poc>a { color: #0dfba5; font-weight: normal; text-decoration: underline; } </style>
Html
<body> <ul class="sitecol"> <li id="oone" class="parentsitcol"> <div class="container"> <div class="expand" title="Show site contents"></div> <div class="texts"><a id="parent_site"></a></div> </div></li> </ul> </body>
add this code to your html file and save,
Add a web part page

Edit the Web Part page and add Content Editor Web-part

Once the file is saved then your site map should be ready as shown in below image.

As shown in above image the site map will start with the current site and it can go down all way to the last sub-site present. As the map expands it also has the ability to display the lists of the site. You can hide or display any section as you want.
This application can be used for SharePoint online or SharePoint on premises. It has been tested in Office 365 and SharePoint 2013.
I hope it helps you to create a dynamic and intuitive Site map for your users.
This is exactly what I am looking for! Unfortunately, all I get is a blue header after following the steps. Any clues? Thanks for sharing!
LikeLike
Do F12 and see in console if there is any error. The code is very sensitive try it chunk by chunk. Start with one site only then go for rest. First try to get the first one working and do the rest. Good Luck
LikeLike
Expands beyond the page in IE 11 but is ok in Chrome. i really need to get working in IE11 due to other environment issues.
LikeLike
David, i recommend you use F12 to debug in IE11. Flex might not work well in IE11 but table-cell might work. I did have similar problem but the CSS i included should work. Try debugging in IE 11 and change the class or value for the div that expands out of the screen. You should see the difference..
LikeLike