jQuery to the Rescue: Requesting a review only once per user
Author: Jim Bob Howard
It seems like every time I turn around, I have a project that reaches just beyond what SharePoint will do with out-of-the-box (OOB) functionality. And just about every time that happens, jQuery comes to the rescue to make the job easy, elegant, and robust. Hence the name of this series of articles: "jQuery to the Rescue."
As I continue to document how I have been able to use jQuery for some great, easy-to-use functionality, here’s a look at what we’ve covered so far:
- jQuery to the Rescue — Automate All Day Event
When you want all of your Calendar entries to be an All Day Event, this little lesson shows you how to check the box automatically and then hide it so the user can’t change it. (The example here is a Mileage Report submission calendar.)
- jQuery to the Rescue — Default Text Based on Radio Button Click
How to automatically fill in data based on the actions of the user. For an HR application, wherein a list of candidates is considered for a position, only one (at most) of them will be hired. For all the rest, a reason for NOT hiring is required. For the one happy candidate, jQuery helps us put "N/A" in the box.
- jQuery to the Rescue — Writing a Survey ID to a List on Response Creation (w/o Workflow)
Wow! That title was a mouthful, but I was hoping it would be found by folks having the same problem I was having: namely, workflows don’t fire from surveys. So, what do you do when you want something to happen when a survey response is created? As usual, jQuery to the rescue.
Today, I want to consider another situation for which jQuery solved the puzzle easily.
"Was this helpful?"
Soliciting user-generated content (UGC) is all the rage these days. And one easy way to start collecting some of that is through a simply survey asking if the content was helpful, if it solved the problem, and if the person has any additional questions or comments. But, for any given piece of content, you want each person to only answer the "usefulness" survey once.
I recently had a project where the users are doctors who are working toward earning continuing education credits. The docs were asked to read through a case study and diagnose a fictional patient. When they finished the diagnosis, they can check their answer. To get credit, they need to answer a short three question survey.
Easy enough, a list was created to hold the case studies. In the appropriate place on the DispForm, a link is provided to "Take the Survey," which also sends along a querystring to prefill some column data.


Take the Survey link uses data from Case Study in the querystring as shown:
http://site/Lists/Case%20Survey/NewForm.aspx?CaseName=Pancreas%20Lipoma&CaseNum=Case%2052
The tricky part comes in when we want to keep the doctors from taking the survey if they’ve already taken it. We want to give them a message telling them they can’t take it again. (In our case, we also want to provide a link to let them see what they answered before.)

jQuery to the Rescue
(…again, with the help of Marc Anderson’s jQuery Library for SharePoint Web Services on Codeplex)
If you’ve been using jQuery very long, you know that most solutions begin with, "Add a CEWP to the bottom of the page and hide it," and this one is no different. (If you don’t know what that is, go back to my first posts in this series, as they include all of the steps.)
Here are the basics of what we want jQuery to do for us:
- Look in the survey list and find any records for the current user that match the Case Number (will be the same as the CaseNum parameter in the querystring) of the case study we’re currently on.
- If it doesn’t find anything, leave the "Take the Survey" list as-is.
- If it does find anything, change the message next to Quiz and provide a link to view the existing survey.
Step 1. First we’ll add the jQuery library and the SPServices library to source so that we have access to them on load.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script> <script src="/js/jquery.SPServices-0.4.6.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function() { // Here's where we're going to do stuff! }); </script>
Step 2. We need find out the Case Number for this case study. Right-click your page and click View Source. Search for "Case 52" (in my case) and build a selector to choose that text. Mine looks like this:
<span id="ctl00_m_g_73269c19_39a3_4cb6_8989_cb7155f6c0f1_ff2_1" style="font-weight:bold;">Case 52</span>
I noticed the ff2 in the ID and performed another search to see if it showed up again on the page. Since it didn’t, I knew I could always get the Case Number by using the following selector:
var CaseNum = $(’span[id*=ff2]‘).text();
This is saying, "Find a span element which has an id that contains (*) the string ff2. Then, get the text inside that element." (For details on selectors, go to the documentation on jQuery.com.)
Step 3. Now that we have the Case Number, we can use ().SPServices.SPGetLastItemId to get the ID of the last survey item (if any) that the current user created and has the current Case Number.
lastID = $().SPServices.SPGetLastItemId({ listName: "Case Survey", CAMLQuery: "<Contains><FieldRef Name='Case_x0020_Number'/><Value Type='Text'>" + CaseNum + "</Value></Contains>" });
listName – Use the Display Name of the list you’re searching
FieldRef – Use the Static Name of the column you want to search
CaseNum – This is the name of the variable we created to look up the Case Number
lastID will now contain zero (’0′) if the user hasn’t created a survey for this case study or, if a survey does exist, it will contain the ID of the last survey for this case study (if there are multiple entries before this is implemented—like in our case, it will only return the last one).
* Note: At this writing, the SPGetLastItemId doesn’t include the functionality for including the CAMLQuery, which this solution relies on. Marc Anderson assures me that it will be included in version 0.4.8. If you’re reading this before that version comes out, you can modify your library by following this discussion at Codeplex. Be sure to read all the way to the end; especially my entry beginning with FOUND IT!
Step 4. We’ll only manipulate the "Take the Survey" link if lastID does not equal (!=) 0.
if (lastID != '0') { var svyLink = $('td[id^=surveylink]'); svyHREF = "/site/Lists/Case%20Survey/DispForm.aspx?ID=" + lastID; svyLink.html("<a href='" + svyHREF + "'>" + "<img alt='' src='/images/quiz.jpg' border='0'/></a>" + "<strong>Survey completed</strong>" + "(<a href='" + svyHREF + "'>View answers</a>)"); };

svyLink – The selector we’re using here helps us find the TD that contains our link to the survey. If you are working with a customized DispForm.aspx, you can add an id="surveylink" to the TD. SharePoint, however, will change it to: surveylink{generate-id()}, so that when the page is actually created it will look more like this:
<td id="surveylinkID0EAAA" width="400px" valign="top" ... >...</td>
That’s why we use ^=, which means "begins with."
svyHREF – Copy and paste the URL for your DispForm.aspx from your browser and paste it (without the number at the end) into the quotes. We’ll supply the ID with our lastID variable.
svyLink.html - We’re replacing everything inside the TD with our new text and link (and old image).
Conclusion
Of course, this doesn’t stop the user from going to the survey list and creating another item. But, without the querystring, it won’t be tied to an actual case study and will be useless anyway. So, within the normal path of giving feedback on a given case study, this will simply restrict users to only create one survey item per case study.
Here’s the final complete code:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script> <script src="/js/jquery.SPServices-0.4.8.min.js" type="text/javascript"></script> // *** See note above, regarding version 0.4.8 *** <script type="text/javascript"> $(document).ready(function() { var CaseNum = $('span[id*=ff2]').text(); lastID = $().SPServices.SPGetLastItemId({ listName: "CME Survey", CAMLQuery: "<Eq><FieldRef Name='Case_x0020_Number'/><Value Type='Text'>" + CaseNum + "</Value></Eq>" }); if (lastID != '0') { var svyLink = $('td[id^=surveylink]'); svyHREF = "/site/Lists/Case%20Survey/DispForm.aspx?ID=" + lastID; svyLink.html("<a href='" + svyHREF + "'>" + "<img alt='' src='/images/quiz.jpg' border='0'/></a>" + "<strong>Survey completed</strong>" + "(<a href='" + svyHREF + "'>View answers</a>)"); }; }); </script>
See you next time I can say: "jQuery to the Rescue!"
Author: Jim Bob Howard
Jim Bob Howard is a web designer / web master in the healthcare industry. He has been working with SharePoint only since March 2009 and enjoys sharing what he has learned. You can email him at [email protected].
- jQuery to the Rescue - Automate All Day Event
- jQuery to the Rescue - Default Text Based on Radio Button Click
- jQuery to the Rescue: Writing a Survey ID to a List on Response Creation (w/o Workflow)
- jQuery to the Rescue: Requesting a review only once per user
- jQuery to the Rescue: Displaying/Hiding Content based on User Permissions or "When Edit Items permissions don't work..."
- jQuery to the Rescue: Labeled Sections on Default Forms
Nice article, Jim Bob. We just love what we can do with jQuery, don’t we? (I’m only smiling a little bit as I type this.)
BTW, for anyone reading this, I released v0.4.8 of the library yesterday, just in time for Jim Bob’s publication of this article, and the CAMLQuery option he discusses above is available in that release.
M.
Excellent! Thanks, Marc!
Blessings,
Jim Bob