SPServices and jQuery: pull items from multiple lists in SharePoint 2010

Let’s say you want to display all of the titles of every page library in your site collection. Using jQuery and SPServices, it’s a breeze it’s definitely possible.

What we have here are three calls of the SPServices function. First, we call the GetAllSubWebCollection operation. This will bring us all sites (webs) within a certain site collection. Once we have that, we’ll then iterate through each web to find all lists (2nd SPServices call) using the GetListCollection function. Once we have all lists, we’ll iterate through each list to look for any lists with the title “Pages”. This will give us every page library of every site in our site collection. Then we we will call our 3rd and final SPServices function, GetListItems to bring us all of the titles of all the items (in every list, in every site of this site collection). Finally, for our last act, we’ll then link each title of each item of each list of each subsite of the site collection to it’s specific URL.

But then we have to do something with that chunk of data. The last line in our code is a simple jQuery function that appends an LI with each title inside an empty UL tag with the ID of #sitelist (somewhere in your page).

Phew!

…ok, here’s the code (I just tested it, it works!):

$().SPServices({
	operation: "GetAllSubWebCollection",
	webURL: "/",
	async:false,
	completefunc: function(xData, Status) {
		$(xData.responseXML).find("Web").each(function(){
$().SPServices({
 operation: "GetListCollection",
 webURL: $(this).attr("WebFullUrl"),
 async:false,
 completefunc: function(xData, Status) {
  $(xData.responseXML).find("List").each(function(){
  //function to get all items inside every list called "Pages"
  if($(this).attr("Title") == "Pages") {
   $().SPServices({
    operation: "GetListItems",
    webURL: $(this).attr("WebFullUrl"),
    async: false,
    listName: $(this).attr("Title"),
    CAMLViewFields: "<ViewFields><FieldRef Name='EncodedAbsUrl' /><FieldRef Name='Title' /></ViewFields>",
     completefunc: function (xData, Status) {
      $(xData.responseXML).SPFilterNode("z:row").each(function() {
       var url = $(this).attr("ows_EncodedAbsUrl") + "";
       var liHtml = "<li><a href='" + url + "'>" + $(this).attr("ows_Title") + "</a></li>";
       $("#sitelist").append(liHtml);
      });
     }
    });
   }
  })
 }
});
		})
	}
})

As usual, thanks to Marc Anderson and his SPServices library

Our responsibility as designers: write

(This goes for other professions as well I’m sure). As designers I think it is important we regularly publish online. Blogs, articles, editorials, whatever. The web is developing faster than anyone can grasp, and the only way to make the most of it is to share, share, share. I’ve been actively “blogging” since May 2011 about what I know and discover, and have actually managed to keep it up. The reason is because this isn’t a website dedicated to shouting at the world and hoping people are reading about what I had for dinner or why I think blue is better than red. In fact, one of the main reasons I started this site was to have a repository of everything I learn so I can reference it myself! I often forget what I’ve done in the past, and this helps tremendously when that happens.

So, start writing. Don’t just write, write well. Don’t just share, share useful info. And hopefully you’ve found some of this useful over the past year.

-Ben

Create your first jQuery Mobile “App”

Update: I’ve since released 2 screencasts on this issue.

  1. Screencast: Create a Basic jQuery Mobile application
  2. jQuery Mobile – List Views (Screencast)

Let’s setup our first jQuery Mobile site/app (whatever you want to call it). This tutorial just covers basic setup and a first page. No links or buttons, we’ll cover that soon. But it’s a lot more straightforward than you might think. You need three things:

  1. jQuery Mobile CSS (default theme, or roll your own at jquerymobile.com)
  2. jQuery.js (download from jquery.com)
  3. jQuery-mobile.js (download from jquerymobile.com)

Let’s create our basic html structure:

<!DOCTYPE html>
<html>
<head>
 <title>My First jQuery Mobile "App"</title>
 <link rel="stylesheet" href="jquery.mobile-1.0.css"/>
 <script src="jquery.js"></script>
 <script src="jquery.mobile-1.0.js"></script>
</head>
<body>
 …
</body>
</html>

Next we’ll create our first “page”. Note that we’ll be using HTML5 markup. Put the following inside the body tag:

<section id="page1">
<header><h1>This is my first page!</h1></header>
  <div class="main">
   And here's my content!
  </div>
<footer><h1>And here's my footer</h1></footer>
</section>

You should wind up with something boring like this:

Now we’ll add in the “data-role” attributes that tell jQuery Mobile what styles and actions to apply. We’ll use the following attributes:

  • data-role=”page” (for each page of the app)
  • data-role=”header” (for the styled header toolbar)
  • data-role=”content” (to contain the main page content)
  • data-role=”footer” (for the styled footer toolbar)

So now let’s add it into our code:

<section id="page1" data-role="page">
<header data-role="header"><h1>This is my first page!</h1></header>
  <div class="main" data-role="content">
   And here's my content!
  </div>
<footer data-role="footer"><h1>And here's my footer</h1></footer>
</section>

And you should end up with something like this: (much better!)

It’s that simple. Keep watching for more in-depth tutorials on working with jQuery Mobile.

Rollup articles across a site collection (using jQuery) in SharePoint 2010

The situation: you have a great blog article you would like to rollup to a page on your site, but it is in a different site collection. What do you do? Content Query Webparts won’t do it! Well, you could create a custom webpart. You could pay a consultant and some developers to create one for you. You could find something prebuilt.

Or you could insert a few lines of jQuery and call it a day!

We’re looking to create something like this (the link would be dynamically rolled up from across a site collection):

Latest Blog Article: Rollup articles across a site collection (using jQuery) in SharePoint 2010

Skip ahead:
Download/link to SPServices
The Code
Final Result

Step 1: Download/link to SPServices

(This assumes you have already loaded jQuery itself…do that first!). SPServices is a jQuery library created by Marc D Anderson that helps you hook into SharePoints services. It does a freaking lot of stuff, but for this article we’re going to use it for rolling up some content from across a site collection. So download it from codeplex and let’s get started!

We’re going to do everything in the page using SharePoint Designer. You could load this script in your master page, or page layouts, or wherever you want. But for now, we’re going to do a one-page example. So copy this script onto your page:

<script type="text/javascript" src="/Style%20Library/scripts/jquery.SPServices-0.7.0.min.js"></script>

Step 2: the Code

First, let’s setup our placeholder for this article’s title. We will set up a span (or p, div, whatever) with and ID so we can use jQuery to find it and append the dynamically created link.

<span id="sitecollectionlink">Latest Blog Article:</span>

Next, we’ll start writing our code. I’ll break it down and then paste everything at the end. I’ve created this solution by trial and error, but there were a few discussions and examples by much smarter people on the codeplex forums that helped me with a few of the hard bits.

First let’s create a new script and call a new jQuery function on $(document).ready:

<script type="text/javascript">
$(document).ready(function() {

//code will go here

});
</script>

Let’s get into it! Our call to SPServices comes next. We’ll set the operation to “GetListItems”, set our webURL to where our blog is residing (in a separate site collection), and we pass it the list “name”. For default SharePoint blogs the list name is “Posts.” Next, we call in the fields using CAML. You’ll need two for this example, the Title field and the EncodedAbsUrl field. And finally, I’ve limited the results to just 1 because I want only one blog post showing up on my home page. Default I believe is 30 or so…

$().SPServices({
 operation: "GetListItems",
 async: false,
 webURL: "/YOUR-SITE/CHANGETHIS",
 listName: "Posts",
 CAMLViewFields: "<ViewFields><FieldRef Name='EncodedAbsUrl' /><FieldRef Name='Title' /></ViewFields>",
 CAMLRowLimit:1,
  
// we're not finished...more coming!

  });

Next we call a function that runs when everything is complete. (Be sure to read the documentation on the codeplex for an explanation of why the code should be SPFilterNode instead of find). Ok, the code below first sets a variable called “url”. We set this from the EncodedAbsUrl variable. Don’t forget to include ows_ before the variables when you call them here. Next we have an if statement that tests whether or not the returned item is a document. This is not very relevant for this tutorial, but it’s good to see what happens. Because this is not a document, it’s a list item, the code inside the if statement will run. SharePoint URLs are stored really horribly, so this takes out all the junk and formats it nicely. It cuts off everything after the last forward slash and replaces it with “/Post.aspx?ID=” (this is the default viewing page for a SharePoint post). Then it brings in the ID to append to the URL. Finally, we set a variable called “link”, using the newly formatted URL as the href tag and putting our Title as the anchor text. And to wrap it all up we locate the span we created earlier using jQuery and append the new link we’ve created. The link will be put in dynamically after the page has loaded!

completefunc: function (xData, Status) {
      $(xData.responseXML).SPFilterNode("z:row").each(function() {
      	var url = $(this).attr("ows_EncodedAbsUrl") + "";
      	if(($(this).attr("ows_EncodedAbsUrl") + "").match(/000$/))
      	{
      		url = url.substring(0, url.lastIndexOf("/", url.length));
      		url = url + "/Post.aspx?ID=" + $(this).attr("ows_ID");
      	}
         var link = "<a href='" + url + "'>" + $(this).attr("ows_Title") + "</a>";
        $("#sitecollectionlink").append(link);
      });
    }

So hopefully this tutorial was fairly straightforward. If you got lost, don’t worry, leave a comment and I’ll help you out. And for your ease, the full code is below. Copy and paste to your heart’s content!

Final Result

Copy and paste this into your page and you should be good to go. Remember to change the path to your javascript and the webUrl to your list.

<script type="text/javascript" src="/Style%20Library/scripts/jquery.SPServices-0.7.0.min.js"></script>

<script type="text/javascript">
$(document).ready(function(){
$().SPServices({
operation: "GetListItems",
async: false,
webURL: "/YOUR-SITE/CHANGETHIS",
listName: "Posts",
CAMLViewFields: "<ViewFields><FieldRef Name='EncodedAbsUrl' /><FieldRef Name='Title' /></ViewFields>",
CAMLRowLimit:1,
completefunc: function (xData, Status) {
$(xData.responseXML).SPFilterNode("z:row").each(function() {
var url = $(this).attr("ows_EncodedAbsUrl") + "";
if(($(this).attr("ows_EncodedAbsUrl") + "").match(/000$/))
{
url = url.substring(0, url.lastIndexOf("/", url.length));
url = url + "/Post.aspx?ID=" + $(this).attr("ows_ID");
}
var link = "<a href='" + url + "'>" + $(this).attr("ows_Title") + "</a>";
$("#sitecollectionlink").append(link);
});
}
});
});
</script>

<span id="sitecollectionlink">Latest Blog Article:</span>

Hot off the press: electscottmanske.com

Last week I wrapped up a project for Scott Manske, who is a candidate for a public office position in Milwaukee, WI this year. He needed a simple site where he could answer questions people had, give contact info, and give a background on himself and why he would be great for the job. As you can see, it was a pretty simple site, but fun to do. I debated on whether or not to do this site in wordpress, or just hand-code the 4 or 5 pages myself. I ended up using wordpress, and it wasn’t that much more work.

So check it out (and if you’re in Milwaukee, vote!): www.electscottmanske.com

Making my website responsive

Try resizing the window, I’ve swallowed the pill and made my website responsive. It’s a sloppy job I’m sure, but it seems to work ok. I accomplished this with a few things:

  • CSS3 Media Queries
  • Modernizr.js
  • Respond.js (don’t think it loaded by default for some reason in modernizr. weird)

I’ve decided on 3 main sizes. They aren’t particularly standard practice, but they work for my site. In my case, I have pretty basic stylistic differences between screen sizes. Here’s my setup:

@media only screen and (min-width: 716px) and (max-width: 970px) {...}

@media only screen and (max-width: 716px) {...}

Because my site runs on wordpress, I’ve also installed a Modernizr and Respond plugin. Yes, I could have put them in myself, but the goal was a quick and dirty implementation of responsive design. I’ve tested in Safari, Firefox, and IE7/8/9. Everything seems to work except my background-size declaration in any version below IE9. Oh well. For another time…

I’ll also be writing soon on the differences on doing responsive design vs using something like jQuery mobile.

A few resources:
Responsive Web Design: What It Is and How To Use It
Modernizr
Taking Advantage of HTML5 and CSS3 with Modernizr

jQuery Mobile 1.1 to include true “fixed” toolbars

According to their blog, jQuery Mobile’s version 1.1 will greatly enhance the “fixed” toolbar issue. If you use it now, you’ll notice that the header and footer toolbars aren’t actually “fixed” as you would expect. Instead, they scroll with the page, and then are dynamically re-positioned.

“the way mobile browsers would freeze the DOM during scroll would result in the toolbars briefly scrolling with the document which was impossible to completely fix” – jQuery Mobile Blog

jQuery Mobile says they have completely re-written the plugin from scratch to fix this issue.

Although, if you notice, form fields show up OVER the toolbars in the demo. Hope they’re fixing that!