Real Life Example with SPServices: Telephone List Gadget
Author: Marc D. Anderson
http://mdasblog.wordpress.com
Kevin Carbonaro posted a neat little gadget example to the SPServices Discussions today, and I thought it was slick enough that it deserved a blog post. The pundits out there may look at this and say “Well, he should have done it with…” or “That’s not best practice because…”. Hey, even I wrote back to Kevin and said that I would probably have done this with a Data View Web Part (DVWP) instead. But it works for Kevin and his business users, so it’s a winner no matter how you look at it. If you’ve got SharePoint hosted in the cloud with Microsoft’s BPOS or one of the great other hosting companies out there like FPWeb or Rackspace, then this type of approach may well be optimal for you. Kevin was able to build this gadget with jQuery and SPServices and it meets *his* organization’s governance goals. Score.
Let me let Kevin explain it from his Discussions post:
Hi All,
Have been working on a telephone list gadget to put on our intranet and finally it is working, however I am still not sure about the correct way to get z:row ( see related post). [Note: The post now contains the answer for the best way to access the z:row namespace and I've updated the code below accordingly.]
The telephone list gadget consists of a dropdown list being populated from a SP list called Telephone List.
When an dropdown item is selected an ajax call is sent to the server to get just the columns for that item.
They are then displayed underneath the dropdown.
jQuery and SPServices are stored in a SP list as attachments and referenced using their SP url. The code is placed in a Content Editor Web Part. All functions and variables have a prefix of sda_ so that they do not conflict with any other similarly named ones. It is important not to load the referenced libraries more than once from other code on the same page.
P.S. This code will not work as is – i.e. you need to create your own SP list with columns and modify the code accordingly ( urls,column names, etc ), but it will surely help by giving examples and ideas for your own project.
and from the email exchange Kevin and I had separately, after I suggested that I would probably have used a DVWP:
Actually I did not know of any easier method to create such a functionality until you mentioned DVWP but as I am not a proficient SP designer user, it was really not an option for me. As well as proving to my boss that it can be done, it paves the way for more complex interactive gadgets. Internally, this gadget has been a number one hit. Employees (incl. the receptionist) are now using it instead of printing the list. So I guess I am contributing to the ‘Save a Tree’ campaign :)
Here’s the code:
// Reference jquery and spservices libraries stored as attachments in a SP list <script src="/Lists/Site%20Code/Attachments/20/jquery-1.4.2.min.js" type="text/javascript"></script> <script src="/Lists/Site%20Code/Attachments/27/jquery.SPServices-0.5.6.min.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function() { sda_initialize(); }); // ready function sda_initialize() { sda_unpopulateDropdown(); sda_filterquery = ""; sda_viewfields = "<ViewFields><FieldRef Name='Title' /><FieldRef Name='Last_x0020_Name' /></ViewFields>"; sda_thenwhat = 'populatedropdown'; sda_getmyitems(sda_filterquery,sda_viewfields,sda_thenwhat); } // sda_initialize function sda_populateDropdown(sda_currentrow) { sda_firstname = sda_currentrow.attr("ows_Title"); sda_lastname = sda_currentrow.attr("ows_Last_x0020_Name"); if (sda_lastname == null) { sda_lastname = ""; } // if sda_selectHtml = '<option value="' + sda_firstname + '*SPLIT*' + sda_lastname + '">' + sda_firstname + ' ' + sda_lastname + '</option>'; $("#sda_Select").append(sda_selectHtml); } // populatedropdown function sda_unpopulateDropdown(sda_currentrow) { $("select[id$=sda_Select] > option").remove(); sda_selectHtml = '<Option value="Select...">Select...</Option>'; $("#sda_Select").append(sda_selectHtml); } // sda_unpopulateDropdown function sda_showDetails(sda_currentrow) { var sda_role = '', sda_dept = '', sda_deptraw = '', sda_extension = '', sda_mobile = '', sda_email = ''; sda_role = sda_currentrow.attr("ows_Role"); sda_deptraw = sda_currentrow.attr("ows_Unit"); sda_extension = sda_currentrow.attr("ows_Extension"); sda_mobile = sda_currentrow.attr("ows_Mobile"); sda_email = sda_currentrow.attr("ows_Email"); if (sda_role == null) { sda_role = '' }; if (sda_deptraw == null) { sda_deptraw = ''; } // if else { sda_dept = sda_deptraw.substring(2,sda_deptraw.length-2); } // else if (sda_extension == null) { sda_extension = '' }; if (sda_mobile == null) { sda_mobile = '' }; if (sda_email == null) { sda_email = '' }; sda_detailsHtml = 'Role: ' + sda_role + '<br />' + 'Group: ' + sda_dept + '<br />' + 'Ext: ' + sda_extension + '<br />' + 'Mob: ' + sda_mobile + '<br />' + 'Email: <a href="<a href="mailto:'">mailto:'</a> + sda_email + '">' + sda_email + '</a>'; $("#sda_Details").append(sda_detailsHtml); } // showdetails function sda_clearDetails(sda_currentrow) { $("#sda_Details").empty(); } // cleardetails function sda_getmyitems(sda_filterquery,sda_viewfields,sda_thenwhat) { $().SPServices({ operation: "GetListItems", webURL: "/Units/CorporateServices", listName: "Telephone List", CAMLQuery: sda_filterquery, CAMLViewFields: sda_viewfields, completefunc: function (sda_xData, sda_Status) { switch(sda_thenwhat) { case 'populatedropdown': sda_unpopulateDropdown(); $(sda_xData.responseXML).find("[nodeName=z:row]").each(function() { sda_populateDropdown($(this)); }); // each break; case 'getdetails': sda_clearDetails(); $(sda_xData.responseXML).find("[nodeName=z:row]").each(function() { sda_showDetails($(this)); }); // each break; default: } // switch } // completefunc }); // spservices } function sda_getSelectedInfo(sda_getfullname) { var sda_fullname = (sda_getfullname.options[sda_getfullname.selectedIndex].value); if (sda_fullname != "Select...") { var sda_splitResult = sda_fullname.split("*SPLIT*"); sda_getfirstname = sda_splitResult[0]; sda_getlastname = sda_splitResult[1]; sda_filterquery = '<Query><Where><And><Eq><FieldRef Name="Title" /><Value Type="Text">' + sda_getfirstname + '</Value></Eq><Eq><FieldRef Name="Last_x0020_Name" /><Value Type="Text">' + sda_getlastname + '</Value></Eq></And></Where></Query>'; sda_viewfields = '<ViewFields><FieldRef Name="Title" /><FieldRef Name="Last_x0020_Name" /><FieldRef Name="Role" /><FieldRef Name="Unit" /><FieldRef Name="Extension" /><FieldRef Name="Mobile" /><FieldRef Name="Email" /></ViewFields>'; sda_thenwhat = 'getdetails'; sda_getmyitems(sda_filterquery,sda_viewfields,sda_thenwhat); } // if } // getselectedinfo </script> <div id="sda_Header" style="text-align: center;"> <b>Telephone List</b> </div> <div id="sda_Pre" style="margin: 5px;"> <select id="sda_Select" onChange="sda_getSelectedInfo(this);"> <Option value="Select...">Select...</Option> </select> </div> <div id="sda_Details" style="margin: 5px; text-align: left;"></div> <div id="sda_Footer" style="text-align: right; margin-right: 8px;"> <a href="/Units/CorporateServices/Lists/Telephone%20List/AllItems.aspx" target="_blank">View Full Staff Directory</a> </div> </script>
I’m sure that Kevin would be interested in your ideas and comments. I’m happy to share such a nice use of SPServices!
Author: Marc D. Anderson
http://mdasblog.wordpress.com
Marc D. Anderson is a Co-Founder and the President of Sympraxis Consulting LLC, based in Newton, MA. He has over 25 years of experience as a technology consultant and line manager across a wide spectrum of industries and organizational sizes. Marc has done extensive consulting on knowledge management and collaboration and what makes them actually work in practice. Read More.
I’ve been writing an article about ASP.net controls and have been wondering how to call a javascript function within it. Looking over your code makes perfect sense as to how to do this. Thanks for the tip!
One thing that I noticed is that your select control has a hard-coded value in it (Option value=”Select…”, but it’s erased and re-written using jQuery on page load. Is that hard-coded value necessary?
I like it how the guy says he’s not a proficient SPD user but is proficient with spservices and JQuery.
Brilliant :)
Matt
I’m trying to access an OOTB contacts list.. I assumed that I would set
webURL:” /<>/Level2Site/Level3Site”
listName: “Contacts”
I’m references jquery-1.3.2.min.js and SPServices-0.5.7.js
Any guess as to why it isn’t working?
Walter:
I generally recommend jQuery 1.4.2 these days (though 1.4.3 just was released). If you have problems, post to either the forum here at Stump the Panel or on the SPServices Codeplex site in the Discussions. We’ll get it sorted.
Note that Kevin’s list was not a standard Contacts list, so you may need to make some adjustments.
M.