Metro SharePoint Directory–Reading from Lists

As yet another follow-up to the various posts I made on building a Metro-style directory of sorts in SharePoint here and here, one thing that’s been asked a few times already is reading from a list.

In the original post we called the getSubWebsForCurrentUser method to fetch a list of sites. What if you wanted something more generic? Here’s a solution that will let you read from a list instead.

First we’re going to need a list. This part is easy. Create a new custom list through the Site Actions (Site Actions > More Options > List > Custom List, intuitive I know).

image

The custom list gives you a blank list with one column, Title. That will be our text to display. Next add a new column to the list of type Hyperlink. It can be called Url, Link, or Ganondorf if you’re feeling particularily Zelda-ish. This will be the link that will transport your users to magical places.

image

Now that we have our list we can use a modified version of the original script to iterate through the list items and build up our menu. I won’t get into the details of how everything works here (go back and read the first article in this series) but here’s the part that will create the menus. Replace your loadSites method with this one:

1 function loadSites() 2 { 3 var context = new SP.ClientContext.get_current(); 4 5 if(context != undefined && context != null) 6 { 7 var web = context.get_web(); 8 var list = web.get_lists().getByTitle('Zelda'); 9 10 var query = SP.CamlQuery.createAllItemsQuery(); 11 this.sites = list.getItems(query, 'Include(Title, Link)'); 12 13 context.load(this.sites); 14 15 context.executeQueryAsync( 16 Function.createDelegate(this, this.onSuccess), 17 Function.createDelegate(this, this.onFailed)); 18 } 19 } 20

Line 8 is where things get different from the original implementation. Instead of getting the sites for the user, we get our custom list. Then we create a new CAML query. The SP.CamlQuery object has a method to get all items so we’ll use that (we could construct a custom query here but we want everything for now).

Line 11 we get all the list items based on the query and specify the fields we want to load.

Line 13 is the same as line 18 in the original code and submits our job to the server for execution.

Our onSuccess method is a little different now that we have to enumerate over list items instead of sites. Here’s the modified version:

1 function onSuccess() 2 { 3 var listItems = this.sites.getEnumerator(); 4 var menuNavContent = ''; 5 var contentNavContent = ''; 6 7 menuNavContent += '<div id="applist">'; 8 menuNavContent += '<h1>Apps</h1>'; 9 menuNavContent += '<ul class="apps">'; 10 11 contentNavContent += '<div id="appbox">'; 12 contentNavContent += '<ul class="apps">'; 13 14 while(listItems.moveNext()) 15 { 16 var item = listItems.get_current(); 17 var itemId = item.get_id(); 18 var itemUrl = item.get_item('Link').get_url(); 19 var title = item.get_item('Title'); 20 21 menuNavContent += '<li>'; 22 menuNavContent += "<a href='" + itemUrl + "'>" + title + "</a>"; 23 menuNavContent += '</li>'; 24 25 contentNavContent += "<div style=\"cursor:pointer;\" onclick='location.href=" + itemUrl + "');\">"; 26 contentNavContent += '<li class="theme_blue">'; 27 contentNavContent += '<div>'; 28 contentNavContent += '<div class="tileTitle"><a href="' + itemUrl + '">' + title + '</a></div>'; 29 30 contentNavContent += '</div>'; 31 contentNavContent += '</li>'; 32 contentNavContent += '</div>'; 33 } 34 35 menuNavContent += '</ul>'; 36 menuNavContent += '</div>'; 37 38 // replace our left hand menu navigation 39 $('#menuNav').html(menuNavContent); 40 41 contentNavContent += '</ul>'; 42 43 // replace our right hand tile navigation 44 $('#contentNav').html(contentNavContent); 45 } 46

A few things to note here on what happening.

Line 3 we fetch the list item enumerator.

Line 14 we step over each item in the list.

Line 16-19 we grab the individual item and fields we want.

Line 21-23 we setup the left hand menu navigation with the title and link to the site (from the custom list data)

Line 25-32 we populate the Metro tiles with the same information.

Finally we add it to our markup on the page using jQuery to replace our Loading tags.

That’s it. Now you have your custom menu driven from a SharePoint list. Go ahead and add items to the list and magic will happen.

Look for a more lengthy article on this entire series shortly where I pull it all together as well as adding a few more cool things like tracking and sorting the list based on popularity of clicks. I’m also going to present this whole thing at next weeks Calgary SharePoint User Group meeting if you’re in town so you can join us then.

Enjoy.

Published Tuesday, June 12, 2012 7:44 AM by Bil Simser

Comments

# re: Metro SharePoint Directory–Reading from Lists

Tuesday, June 12, 2012 10:59 AM by Stonecold

Great post!! - exactly what I was looking for works a treat, Thanks.

# re: Metro SharePoint Directory–Reading from Lists

Tuesday, June 12, 2012 11:47 AM by Michael Gannotti

Again Bill, this is awesome. Cant wait to get some free time to implement on our site here. :-)

# re: Metro SharePoint Directory–Reading from Lists

Thursday, June 21, 2012 11:51 PM by Stephan Dekker

Awesome, found one bug:

Line 25 of "OnSuccess". I had to replace it with:

contentNavContent += "<div style=\"cursor:pointer;\" onclick=\"location.href='" + itemUrl + "';\">";

Works like a charm!

# re: Metro SharePoint Directory–Reading from Lists

Friday, June 22, 2012 9:38 AM by Nick

Great post,  however do you know how I could change this to show a tile per list with a count for each or multiple on one list based on record status (e.g. Approved, Pending etc.)?

# re: Metro SharePoint Directory–Reading from Lists

Tuesday, June 26, 2012 3:26 AM by Myrko

Great. We use that since a couple of weeks... But on Firefox the tiles are all vertically? can you confirm that?

Leave a Comment

(required) 
(required) 
(optional)
(required)