Posted by on April 21, 2014

This blog post covers how to implement a simple, yet devilishly effective mutiple-list query redirect page using SPServices. If you have not yet explored how SPServices spservices_logocan expand your current SharePoint solutions, you should definitely check the project out on CodePlex!

A client recently required a single landing page (a “loading” page, if you will) from which a list item will open based an a URL parameter, where the parameter matches a column value in the list item. The caveat though, is that the list item could exist across any of six individual (and very large) custom lists, which do not necessarily have the same structure. The lists are all closely related and represent the movement of work items through a tightly-controlled business process… so the item could change locations throughout the day.

For the sake of clarity, let’s call the work items “documents” to represent the business use-case. Documents have a unique identifying number that generates when an initial request arrives in one department. This DocID then represents the easiest way for an end-user to check on the status of the the request, the resulting document, or both, at any point in the business process.

List AList B
Initial RequestsArchived Requests
DocID (Internal list item ID)DocID (Number column)
UniqueUnique
List CList DList EList F
Submitted DocumentsIn Review DocumentsApproved DocumentsObsolete Documents
DocID (Number column)DocID (Number column)DocID (Number column)DocID (Number column)
UniqueUniqueUniqueDuplicates Possible

This “landing” page needs to query these lists in a particular order, taking into account the current user’s permissions (skipping over lists to which he/she does not have read rights), and loading the document or request as soon as the query finds a match.

So, how best to approach the issue of querying for the location of the document based on this DocID?

Out-of-the-box, SharePoint offers the standard list view web part that can be connected to URL filter parameters, but I needed to display the list item’s view form directly (cutting out that extra click). Theoretically, you could connect a view form web part to the URL parameter, but in this case it would be very sloppy to repeat this six times on the same page to cover all the lists.

Third-party, the challenge reduces to a trivial implementation using SPServices JQuery library for SharePoint 2010; fortunately; this was already in use elsewhere in the site collection.

The .aspx loading page itself contains a call to the SPServices SPGetQueryString function, to parse the URL parameter named “doc“…

var queryStringValues = $() .SPServices.SPGetQueryString();
var strDocId = queryStringValues["DOC"];
//double-check for lowercase parameter name:
if(!strDocId) strDocId = queryStringValues["doc"]

…the SPServices getListItems calls and logic to query the six lists…

	var cQueryOptions = "<QueryOptions><ExpandUserField>FALSE</ExpandUserField></QueryOptions>" ;
	var url;
	var foundFlag = false;

	function queryListA() {
		//call GetListItems
		//set url=<URL OF LIST A> + "/DispForm.aspx?ID=" + MATCHING ITEM ID
		//inside completefunc, set foundFlag=true and window.location=url;
	}

	function queryListB() {
		//call GetListItems
		//set url=<URL OF LIST B> + "/DispForm.aspx?ID=" + MATCHING ITEM ID
		//inside completefunc, set foundFlag=true and window.location=url;
	}

	function queryListC() {
		//call GetListItems
		//set url=<URL OF LIST C> + "/DispForm.aspx?ID=" + MATCHING ITEM ID
		//inside completefunc, set foundFlag=true and window.location=url;
	}

	function queryListD() {
		//call GetListItems
		//set url=<URL OF LIST D> + "/DispForm.aspx?ID=" + MATCHING ITEM ID
		//inside completefunc, set foundFlag=true and window.location=url;
	}

	function queryListE() {
		//call GetListItems
		//set url=<URL OF LIST E> + "/DispForm.aspx?ID=" + MATCHING ITEM ID
		//inside completefunc, set foundFlag=true and window.location=url;
	}

	function queryListF() {
		//call GetListItems
		//set url=<URL OF LIST F> + "/DispForm.aspx?ID=" + MATCHING ITEM ID
		//inside completefunc, set foundFlag=true and window.location=url;
	}

	$(document).ready(function() {
		if(strDocId) {
			if(strDocId=='0') {
				alert("The document ID provided (\"0\") is not valid. Please try again."
				foundFlag = true;
				window.location = URL TO HOMEPAGE;
			}

			if(!foundFlag) queryListE();
			if(!foundFlag) queryListD();
			if(!foundFlag) queryListC();
			if(!foundFlag) queryListF();
			if(!foundFlag) queryListA();
			if(!foundFlag) queryListB();
		} else {
			alert("The link is invalid or you have accessed this page in an unsupported manner. Please check the link and try your request again.");
			window.location = URL TO HOMEPAGE;
		}
	});

GEARS_AN

…and a simple “loading” message that displays to the user until the query completes (making clever use of the native SharePoint loading graphic gears_an.gif… which everyday users of SharePoint will readily recognize as a loading signal). I also styled the container divs using CSS3PIE so I could be sure this loading page has a professional finish regardless of the user’s browser version.

<div class="LoadingMsgMain">
<div class="LoadingMsgTitle"> YOUR SITE TITLE HERE</div>
<div style="text-align:center; font-size:large; font-face:Calibri; padding:20px;">Please wait the system prepares your document...
<br /><br />
<img src='/_layouts/images/gears_an.gif' style="border:none;" /></div>
</div>

The page then redirects to the display form of the matching list item, or displays an error message if no match found or an invalid URL parameter is provided.

Full page source below.

<html>
<head>
<title>YOUR PAGE TITLE HERE</title>

<!-- Include the SPServices and Jquery libraries from a local site library (or just reference them from a CDN of your choice) -->
<script language="javascript" type="text/javascript" src="/mySiteCodeLibrary/jquery-1.11.0.min.js"></script>
<script language="javascript" type="text/javascript" src="/mySiteCodeLibrary/jquery.SPServices-2014.01.min.js"></script>

<script type="text/javascript">
	var queryStringValues = $() .SPServices.SPGetQueryString();
	var strDocId = queryStringValues["DOC"];
	//double-check for lowercase parameter name:
	if(!strDocId) strDocId = queryStringValues["doc"]
	var cQueryOptions = "<QueryOptions><ExpandUserField>FALSE</ExpandUserField></QueryOptions>" ;
	var url;
	var foundFlag = false;

	function queryListA() {
		//call GetListItems
		//set url=<URL OF LIST A> + "/DispForm.aspx?ID=" + MATCHING ITEM ID
		//inside completefunc, set foundFlag=true and window.location=url;
	}

	function queryListB() {
		//call GetListItems
		//set url=<URL OF LIST B> + "/DispForm.aspx?ID=" + MATCHING ITEM ID
		//inside completefunc, set foundFlag=true and window.location=url;
	}

	function queryListC() {
		//call GetListItems
		//set url=<URL OF LIST C> + "/DispForm.aspx?ID=" + MATCHING ITEM ID
		//inside completefunc, set foundFlag=true and window.location=url;
	}

	function queryListD() {
		//call GetListItems
		//set url=<URL OF LIST D> + "/DispForm.aspx?ID=" + MATCHING ITEM ID
		//inside completefunc, set foundFlag=true and window.location=url;
	}

	function queryListE() {
		//call GetListItems
		//set url=<URL OF LIST E> + "/DispForm.aspx?ID=" + MATCHING ITEM ID
		//inside completefunc, set foundFlag=true and window.location=url;
	}

	function queryListF() {
		//call GetListItems
		//set url=<URL OF LIST F> + "/DispForm.aspx?ID=" + MATCHING ITEM ID
		//inside completefunc, set foundFlag=true and window.location=url;
	}

	$(document).ready(function() {
		if(strDocId) {
			if(strDocId=='0') {
				alert("The document ID provided (\"0\") is not valid. Please try again."
				foundFlag = true;
				window.location = URL TO HOMEPAGE;
			}

			if(!foundFlag) queryListE();
			if(!foundFlag) queryListD();
			if(!foundFlag) queryListC();
			if(!foundFlag) queryListF();
			if(!foundFlag) queryListA();
			if(!foundFlag) queryListB();
		} else {
			alert("The link is invalid or you have accessed this page in an unsupported manner. Please check the link and try your request again.");
			window.location = URL TO HOMEPAGE;
		}
	});
</script>
</head>

<body>
<div class="LoadingMsgMain">
<div class="LoadingMsgTitle"> YOUR SITE TITLE HERE</div>
<div style="text-align:center; font-size:large; font-face:Calibri; padding:20px;">Please wait the system prepares your document...
<br /><br />
<img src='/_layouts/images/gears_an.gif' style="border:none;" /></div>
</div>
</body>
</html>

Comments

Be the first to comment.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: