v1.2 has these changes:
Fixed bug where the string representing the “tile” in the org chart exceeds 255 characters and thus halting the script. This is fixes by using a multiline text field in stead of the Title field in the list “SPJS-SiteMap”.
You find the updated code below.
Updating from a previous version?
Please note that you must delete the existing list and rerun the script to recreate it with the new fields. When the script has recreated the list, you must enter setup of your chart to reselect the list and fields for your SiteMap chart. See image below for changes in the chart setup (new field used in stead of the Title field).
@SPJavaScripts do you have something that makes a site map? Using the logged in perms instead of having to be a site col admin would be nice
Unfortunately I do not know of a method of doing this without Site collection Administrator (SCA) rights, but thought I should post a solution anyways. This solution iterates trough all sites in the site collection and writes to a custom list in a format that can be rendered as a clickable organization chart using SPJS Charts for SharePoint.
The map must be created or updates by a SCA, but can be read by all users.
- Set up SPJS Charts for SharePoint v4 as described here. Please note that you need v4.03 or later.
- Download spjs-utility.js from here and save it in a document library or a folder created in SPD.
- Create a Web Part Page and add a HTML Form Web part to it. Add the code from the code block below in the source editor.
You can also use a CEWP if you use the content link option to link to the code. Do not add the code directly in the source editor of the CEWP.
- Download jQuery from here.
When you reload the page, you will see a button named “Add or update site map”. Click this to set up the list. You should get a confirmation message when the list has been created. You need appropriate permissions to add a list. If you are a SCA, go ahead and populate the list with information about all sites in the site collection. This is done by clicking the same button again.
You will get a confirmation message with the count of items added, updated and removed. The information in the list SPJS-SiteMap is now static and will not reflect changes in the site structure live. To update the site map when a site has been added / updated or removed, an SCA must click the button “Add or update site map” again.
You must update the script src to point to your local files.
<div id="siteMapBtn"></div> <script type="text/javascript" src="/Scripts/jquery-1.10.2.min.js"></script> <script type="text/javascript" src="/Scripts/spjs-utility/spjs-utility.js"></script> <script type="text/javascript"> var spjs = spjs || {}; spjs.siteMap = { "version":"1.2", "data":{ "listName":"SPJS-SiteMap", "listBaseUrl":typeof _spPageContextInfo !== "undefined" ? _spPageContextInfo.siteServerRelativeUrl !== "/" ? _spPageContextInfo.siteServerRelativeUrl : "" : L_Menu_BaseUrl, "listDescription":"SPJS-SiteMap for SharePoint by Alexander Bautz / SharePoint JavaScripts: https://spjsblog.com. This list is used as datasource for SPJS Charts for SharePoint." }, "showButton":function(){ $("#siteMapBtn").html("<input type='button' onclick='spjs.siteMap.update()' value='Add or update site map' />"); }, "update":function(){ if(!confirm("You must be Site Collection Administrator to add or update the site map. Click OK to continue.")){ return; } var b, webs, thisBaseUrl, p, currItems, currItemsObj, newList, uList, data, res, noChangeCount, uCount, nCount, dCount, error; b = '<GetAllSubWebCollection xmlns="http://schemas.microsoft.com/sharepoint/soap/" />'; webs = {}; spjs_wrapSoapRequest(spjs.siteMap.data.listBaseUrl+'/_vti_bin/webs.asmx', 'http://schemas.microsoft.com/sharepoint/soap/GetAllSubWebCollection', b, function(data){ $('Web', data).each(function(i,o){ thisBaseUrl = $(o).attr("Url").replace(location.protocol+"//"+location.host,""); if(thisBaseUrl === ""){ thisBaseUrl = "/"; } p = $(o).attr("Url").replace(location.protocol+"//"+location.host,""); p = p.substring(0,p.lastIndexOf("/")); if(p === ""){ p = "/"; } webs[thisBaseUrl] = {"title":$(o).attr("Title"),"parent":p}; }); }); // Get current items currItems = spjs_QueryItems({"listName":spjs.siteMap.data.listName,"listBaseUrl":spjs.siteMap.data.listBaseUrl,"query":"<Where><IsNotNull><FieldRef Name='ID' /></IsNotNull></Where>","viewFields":["ID","CurrentSite","Parent","URL"]}); if(currItems.count === -1){ if(confirm("It looks like the list named "+spjs.siteMap.data.listName+" does not exist.\n\nCreate it now?")){ newList = spjs_AddList(spjs.siteMap.data.listName,spjs.siteMap.data.listBaseUrl,spjs.siteMap.data.listDescription); if(newList.success){ uList = spjs_UpdateList(newList.id,L_Menu_BaseUrl,[{'Type':'Note','DisplayName':'CurrentSite'},{'Type':'Note','DisplayName':'Parent'},{'Type':'Note','DisplayName':'URL'}],[]); if(!uList.success){ alert(uList.errorText); return; }else{ if(confirm("The list was created successfully. Click OK to populate the list.")){ spjs.siteMap.update(); } } }else{ alert("[spjs_AddList]\n\n"+newList.errorText); return; } return; }else{ return; } } currItemsObj = {}; noChangeCount = 0; uCount = 0; nCount = 0; dCount = 0; $.each(currItems.items,function(i,item){ currItemsObj[item.URL === null ? "" : item.URL] = {"ID":item.ID,"CurrentSite":item.CurrentSite,"Parent":item.Parent,"URL":item.URL}; }); error = false; $.each(webs,function(url,o){ data = {"Title":"[...]","CurrentSite":"{\"v\":\""+url+"\",\"f\":\"<a href='"+url+"' target='_blank'>"+o.title+"</a>\"}","URL":url,"Parent":o.parent} if(currItemsObj[url] !== undefined){ if(currItemsObj[url].CurrentSite === data.CurrentSite && currItemsObj[url].Parent === o.parent && currItemsObj[url].URL === url){ delete currItemsObj[url]; noChangeCount += 1; return; } res = spjs_updateItem({"listName":spjs.siteMap.data.listName,"listBaseUrl":spjs.siteMap.data.listBaseUrl,"id":currItemsObj[url].ID,"data":data}); delete currItemsObj[url]; if(!res.success){ error = {"errorText":res.errorText,"code":res.errorCode}; return false; }else{ uCount += 1; } }else{ res = spjs_addItem({"listName":spjs.siteMap.data.listName,"listBaseUrl":spjs.siteMap.data.listBaseUrl,"data":data}); if(!res.success){ error = {"errorText":res.errorText,"code":res.errorCode}; return false; }else{ nCount += 1; } } }); if(error !== false){ alert("SPJS-SiteMap: An error occurred\n---------------------------------------\nAre you updating from a previous version? If the below error message tells you that one or more field types are not installed correctly, please delete the list \"SPJS-SiteMap\" and rerun this script. The list will be recreated with the missing fields.\n\nPlease note that you must edit the SiteMap chart to reselect the list and fields.\n\nError message\n---------------------------------------\n"+error.errorText); } $.each(currItemsObj,function(url,obj){ res = spjs_deleteItem({"listName":spjs.siteMap.data.listName,"listBaseUrl":spjs.siteMap.data.listBaseUrl,"id":obj.ID}); if(!res.success){ alert("[spjs.siteMap]\n\n"+res.errorText); return false; }else{ dCount += 1; } }); alert("SPJS-SiteMap\n\nUpdated: "+uCount+"\nAdded: "+nCount+"\nRemoved: "+dCount); location.href = location.href; } }; spjs.siteMap.showButton(); </script>
Refer the SPJS Charts for SharePoint v4 article for setup instructions, and select the list “SPJS-SiteMap” as data source. Add an option “allowHtml = true” to render the links as HTML. Here is a screenshot of the Edit Chart GUI:
Let me know what you think of this solution in the comments section below.
Alexander