SPServices and jQuery templates: Upcoming birthday’s overview

9 Jan

The use of jQuery templates is very neat. It easily displays content in a structured way according to a defined template. Microsoft created the jQuery template plugin (https://github.com/nje/jquery-tmpl) which can be used by referencing the template script file. 

In this article both SPServices and the jQuery template will be used to show the strength of combining these libraries. 

Purpose

All employees are highly appreciated at the company there are working (of course). The company decides to send all employees flowers on their birthday. The employee data is stored in a standard SharePoint Contacts list extended with a column to register the birth days. Employees of the HR department are responsible for sending the flowers on time, but they it’s difficult for them to get the upcoming birthdays from the Contact list.
It is desirable to provide the HR department with an overview of upcoming birthdays.    

Set up the Contacts list

To create the overview of upcoming birthdays a standard SharePoint Contacts list is used extended with a column with the name ‘Date of birth’ of type Date and Time. To display some additional information in the overview the column ‘Department’, type single line of text, is added to the list.
The list is filled with some data:

Create the overview    

The SPServices operation GetListItems is used to get the data from the Contacts list:    


$().SPServices({
    operation: "GetListItems",
    async: false,
    debug: true,
    listName: "Contacts",
    CAMLViewFields: "<ViewFields></ViewFields>",
    completefunc: function (xData, Status) {
        $(xData.responseXML).find("[nodeName=z:row]").each(function () {
            daysleft = CalculateDaysLeft($(this).attr("ows_Date_x0020_of_x0020_birth"));
            contacts.push({ FirstName: $(this).attr("ows_FirstName"), LastName: $(this).attr("ows_Title"), Department: $(this).attr("ows_Department"), DaysLeft: daysleft });
        });
        SortByDaysLeft(contacts);
        $("#showContacts").html("");
        $("#contactTemplate").tmpl(contacts)
                        .appendTo("#showContacts");
    }
});

The callback function gets the response of the web service. The function CalculateDaysLeft calculates the days left until the date stored in ‘Date of birth’ will occur in the current year. Since this is a helper method it is not showed here.
The firstname, lastname, department and the daysleft are stored in an array of objects named contacts. To display the birthdays in upcoming order the function SortByDaysLeft is called. This is also a helper function and for readability not displayed here.
A jQuery template, contactTemplate, is used to show the results on the page. The template is rendered with the data and appended to a div with the id showContacts.  The div functions as the template container.
The template uses the objects in the array: 

<script id="contactTemplate" type="text/x-jquery-tmpl">
 <div>
    ${FirstName} ${LastName}
    <ul style="list-style-type:none;">
    <li>${Department}</li>
    <li>${DaysLeft} days left until birthday!!</li>
    </ul>
 </div>
</script>

The first thing you’ll probably notice is the script tags. Because of these tags the template is embedded in the body of the page. In the template html can be used to format the data to be displayed. The ${FirstName}, ${LastName}, ${Departement} and ${DaysLeft} expressions are used in the template as placeholders for the data present in the array of objects ‘contacts’. ${..} tells the parser the fields have to be replaced with the values passed in the template by the array of objects.    

The template is rendered once for each item in the array named contacts.
The upcoming birthdays are displayed with the contactTemplate as shown in the figure below:

This template is quite simple and fulfills the purpose of displaying upcoming birthdays from the Contacts list.

The template displays ‘.. days left until birthday!’ for all items. It’s much nicer to display a message based on the number of days left to provide the HR department with some additional information.
This can be accomplished with code in the template itself with an ‘if ..else..’ statement as shown in the code below. 

<script id="contactTemplateInlineCode" type="text/x-jquery-tmpl">
 <div>
    ${FirstName} ${LastName}
    <ul style="list-style-type:none;">
        <li><a href="#" id=${Department} title="Show all employees of ${Department}">${Department}</a></li>
        <li>
            {{if (DaysLeft < 10)}} Did you order flowers already? It's almost his birthday, only ${DaysLeft} days!
            {{else DaysLeft < 150}} It takes a little while until his birthday: ${DaysLeft} days!
            {{else (DaysLeft < 360 )}} A long time until his birthday: ${DaysLeft} days!
            {{else (DaysLeft > 359 )}} If you didn't sent any flowers, you're too late now...{{/if}}
        </li>
    </ul>
 </div>
</script>

Besides adjusting the text based of the number of days left, the Department is adjusted to be a link. When selecting the link the function GetAllContactsFromDepartment is called with the ID of the link. The ID of the link is set with the Department value. The values of the array used by the template can be used everywhere in the template. The function GetAllContactsFromDepartment will display the firstname, lastname and day and month of the birthdate of the specified Department with the help of the SPServices library operation GetListItems.
The results of this operation are stored in an array of objects and another template is rendered with this array.

 $().SPServices({
    operation: "GetListItems",
    async: false,
    debug: true,
    listName: "Contacts",
    CAMLViewFields: "<ViewFields></ViewFields>",
    CAMLQuery: "<Query><Where><Eq><FieldRef Name='Department'/><Value Type='Text'>" + Department + "</Value></Eq></Where></Query>",
    completefunc: function (xData, Status) {
        $(xData.responseXML).find("[nodeName=z:row]").each(function () {
            var temp = $(this).attr("ows_Date_x0020_of_x0020_birth");
            var formattedDate = "";
            if (temp.length > 0) {
                var month = temp.substring(5, 7);
                var day = temp.substring(8, 10);
                formattedDate = day + " " + month;
                daysLeft = CalculateDaysLeft(temp);
            }
            contactsOfDepartment.push({ FirstName: $(this).attr("ows_FirstName"), LastName: $(this).attr("ows_Title"), BirthDate: formattedDate, DaysLeft: daysLeft });
        });

        SortByDaysLeft(contactsOfDepartment);
        $("#showContactsFromDepartment").html("<h4>" + Department + "</h4>");
        $("#DepartmentTemplate").tmpl(contactsOfDepartment)
                        .appendTo("#showContactsFromDepartment");
    }
});

The DepartmentTemplate used in the code above:

<script id="DepartmentTemplate" type="text/x-jquery-tmpl">
<div style="float:left;width:100%">
    <div style="float:left;width:15%">
     ${FirstName} ${LastName}
    </div>
    <div style="float:right;width:85%">
     ${BirthDate}
    </div>
</div>
</script>

So within a template a call to fill another template with data can be made.    

The upcoming birthdays are now displayed as in the figure below:�

When selecting the Marketing department another template will be filled with data:

All the code displayed in this post is based on jQuery. With references to jQuery, the SPServices library and the jQuery template plugin all the code can be pasted in a Content Editor web part on a SharePoint page.    

<script src="/jQueryLibrary/jquery-1.4.4.min.js" type="text/javascript"></script>
<script src="/jQueryLibrary/jquery.SPServices-0.5.6.min.js" type="text/javascript"></script>
<script src="/jQueryLibrary/jquery.tmpl.js" type="text/javascript"></script>

Summary    

By combining libraries like SPServices and jQuery templates it is quite straightforward to display a list of upcoming birthdays from a standard SharePoint Contacts list.    

The strength of the use of SPServices here is to get the necessary data in a straightforward way; the strength of the use of jQuery templates is to display the data in a nicely formatted way. Using a combination of both libraries I think the best of both worlds are used the appropriate way.

3 Replies to “SPServices and jQuery templates: Upcoming birthday’s overview

  1. Can you post the code for CalculateDaysLeft?

    Specifically I am looking for ability to convert ‘2011-06-15 10:27:09’ into a javascript Date object. The ability to determine days left would be a bonus. Thanks!

  2. Hi Mike,

    I searched for that code, but I can’t find it. Two weeks ago a VM died on me and I think it was still in there.

    To convert a datetime string to a date you can get substrings out of the whole datetime string and format that to a Date object, or use regex or use the string.split() function.
    With the result you can format a new string and use Date.Parse() on that one.

    Regards, Anita

  3. Can you please post the code for sorting the associate array? sortbydaysleft method..

Comments are closed.