jQuery – .SPServices – Google.OrgChart API Mashup – Part 4

By , August 24, 2011 4:33 pm

Part 4 – Add content

Now that we have the basic chart, it’s now time to add content to each box from the Site Map Content List. I could get all of the content of the list and then iterate through them for each node in the Site Map list, or I could write a short function that queried the Site Map Content list at the time I was drawing the node. Since my site map was small and I knew it wouldn’t get much larger, i chose the second option. It would not be hard to code the first option either.

I called this function GetContent and I place it outside of my $(document).ready() block.

function GetContent(LookupValue)
{
    var out='';
    var content, url;
    // use SPServices to query the Site Map Content list for all nodes that match the
    // LookupValue.  Grab the Title, Url, Position and SiteMapNode fields.
    $().SPServices({
        operation: 'GetListItems',
        listName: 'Site Map Content',
        async: false,
        CAMLViewFields: '<ViewFields><FieldRef Name="Title" /><FieldRef Name="Url" /><FieldRef Name="Position" /><FieldRef Name="SiteMapNode" /></ViewFields>',
        CAMLQuery: '<Query><OrderBy><FieldRef Name="Position" /></OrderBy><Where><Eq><FieldRef Name="SiteMapNode" /><Value Type="Lookup">'+LookupValue+'</Value></Eq></Where></Query>',
        completefunc: function(xData,Status){
            // When the response is received from the server,
            // create our content string by iterating
            // through each row returned in the response.
            $(xData.responseXML).find('[nodeName="z:row"]').each(function(){
                url='';
                content='';
                // if our string has already been started, add a new row to the response.
                if(out.length>0)
                    out+='<br/>';
                content=$(this).attr('ows_Title');
                if($(this).attr('ows_Url')!=null)
                    content='<a href="' + $(this).attr('ows_Url') + '" title="' + content + '">' + content + '</a>';
                // add the content string to the output.
                out += content;
            });
            // one requirement I had was to put the Node name at the bottom of the box.
            // The easiest way to do this is to add an empty paragraph and then the Lookup Value.
            // This is specific to my requirement so you don't have to do this.
            out+='<br/><p>&nbsp;</p>';
            out+= LookupValue.wrap('<p>(',')</p>');
        }
    });
    return out;
}

Now that we have the content string built, we can plug that function call into our existing code where we are drawing the boxes.

If you go back to the original function that drew the boxes, locate the lines that say:

boxContent=curTitle;

and replace the line with the following code snippet:

boxContent = GetContent(curTitle);

Your site map should now look like the following illustration.

IE Site Map

As displayed in IE

Chrome Site Map

As displayed in Chrome

As you can see, it looks quite different in IE than it does in Chrome. The reason behind this is the CSS that is used by Google to draw the boxes. In the last post, we’ll make some CSS changes to make it look better in IE.
 


Other posts in this series:

  1. Introduction
  2. Setting up the coding environment
  3. Create the chart
  4. Add content
  5. Conclusion

jQuery – .SPServices – Google.OrgChart API Mashup – Part 3

By , August 23, 2011 10:07 am

Part 3 – Create the chart

In the first two posts, we created our lists and set up our development environment. In this part, we will use jQuery to query the Site Map list and create the Site Map hierarchy. If you haven’t completed the steps outlined in the first two parts, you should do that now. Links to the other posts in the series can be found at the end of this article.

Drawing Boxes

The first thing we are going to do is query our Site Map list and grab all of the list items. We will put all of the code in the document.ready block that we already prepared.

Copy and paste the following snippet of code into the page.

$().SPServices(
{
    operation: 'GetListItems',
    listName: 'Site Map',
    async: false,
    CAMLViewFields: '<ViewFields Properties="True"><FieldRef Name="Title"/><FieldRef Name="Parent"/><FieldRef Name="ID"/></ViewFields>',
    CAMLQuery: '<Query><OrderBy><FieldRef Name="Parent" Ascending="TRUE" /></OrderBy></Query>',
    completefunc: function(xData,Status){}
});

This snippet directs SPServices to use the GetListItems web service and query the list named, Site Map. It specifies that we want to see the following fields: Title, Parent and ID. It also says that we want to Order our data by Parent in ascending order. When we receive the return data, we want to pass that data, xData, to a function for further processing.

For more information on CAML and its syntax, you can find a great reference at http://msdn.microsoft.com/en-us/library/ms462365.aspx.

So far, our code doesn’t really do anything except fetch the data from our list. We need to parse the results and then format it so that the Google charting API can understand it. We will do this in the function(xData, Status){} block. Copy and paste the following snippet.

	//initialize variables
    var curParent='0';
    var testParent;
    var curTitle='';
    var curId='0';
    var parentId;
    var boxContent='';
    // create a new DataTable object that we will pass to the Google API
    var	data = new google.visualization.DataTable();
    // add the following columns to the DataTable to store the chart values.
    data.addColumn('string','Name');
    data.addColumn('string','Parent');
    data.addColumn('string','Tooltip');
    // SPSServices return the response data in the xData object.  It contains
    // the response in an XML document.  We can then use jQuery to find each
    // row of data in the XML file and act on it.
    $(xData.responseXML).find('[nodeName="z:row"]').each(function(){
        // if this node does not have a parent, then we need to save it to the DataTable
        // differently than the nodes with parents.
        if($(this).attr('ows_Parent')==null)
        {
	    curParent = $(this).attr('ows_ID');
	    curTitle = $(this).attr('ows_Title');
	    boxContent=curTitle;

            //   note the first field in the DataTable. the v:curParent and the
            //   f:boxContent are in the Name field.  The v: represents the Value
            //   while the f: represents the display field.  It may look like we're
            //   saving 4 values to a 3 field table but the first field has a
            //   value and display name part to it.

	    data.addRow([{v:curParent, f:boxContent},'',curTitle]);
        }
        else
        {
	    testParent = $(this).attr('ows_Parent');
	    curTitle = $(this).attr('ows_Title');
	    parentId = testParent.split(';#')[0];
	    curId = $(this).attr('ows_ID');
	    boxContent=curTitle;
	    if(parentId !=curParent)
	        curParent=parentId ;
	        data.addRow([{v:curId, f:boxContent},curParent,curTitle]);
	 }
    });

    // now send it to the Google Visualization API and store the results in 'chart'
    var chart = new google.visualization.OrgChart(document.getElementById('sitemap'));
    // render the HTML of the chart.
    chart.draw(data,{allowHtml:true});

If everything worked right, you should now have an OrgChart based on the values you placed in the Site Map list resembling Figure 1.

Boxes

Figure 1 : OrgChart

That’s promising! This is where it starts getting fun! In the next post, I’ll show you how to get the content for the individual boxes!


Other posts in this series:

  1. Introduction
  2. Setting up the coding environment
  3. Create the chart
  4. Add content
  5. Conclusion

jQuery – .SPServices – Google.OrgChart API Mashup – Part 2

By , August 20, 2011 9:26 am

Part 2 – Setting up the coding environment

In the last post, we defined the requirement and the solution and then created the lists that will support it.  In this post, we will assemble all of the parts and set up the coding environment.  I will also show you how I organize supporting files when I develop SharePoint solutions.

Note: The structure I use to create client-side solutions using jQuery and the CEWP is the method and structure that I have adopted after trying various ways on various different projects.  I know others create Document Libraries to store their code and that is fine.  Some even put all of the code in the CEWP.  I normally have SharePoint Designer access so I choose to create Folders instead of Libraries.  If you don’t have SharePoint Designer access, you can create a Document Library to store your code or place it in the CEWP.

To host the org chart, we are going to use a Content Editor Web Part (CEWP).  Using this web part,  we can use HTML or JavaScript to create rich content.

  1. Place a Content Editor Web Part (CEWP) into one of the web part zones.  Don’t worry about configuring it right now.
  2. Open up your site in SharePoint Designer (SPD).
  3. Create a new folder in the root of the site and name it Resources.
  4. Create four new folders in the Resources folder named content, css, images, js.
  5. For this exercise, we are going to use jQuery 1.6.2 and SPServices-0.6.2.
  6. If you haven’t already done so, download the jQuery and SPServices libraries.
  7. Place jquery-1.6.2.min.js and jquery.SPServices-0.6.2.min.js into the Resources/js folder you created on your site.
  8. In the Resources/content folder, create a new file called SiteMap.js.
  9. Open the SiteMap.js file for editing in SharePoint Designer (or any other text editor).
  10. Use the following code block to set up your code page.
<!-- Load the jQuery and SPServices libraries.
     Make sure you verify the path   -->
<script language="javascript" type="text/javascript" src="resources/js/jquery-1.6.2.min.js"></script>
<script language="javascript" type="text/javascript" src="resources/js/jquery.SPServices-0.6.2.min.js"></script>

<!-- Load the Google Charting visualization library.  -->
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">google.load('visualization', '1', {packages:['orgchart']});</script>

<!-- Create a script area for our custom code.   -->
<script type="text/javascript" language="javascript">
String.prototype.wrap = function(pre,post) {
	return pre + this + post;
}
var out="";
var data;
$(document).ready(function(){

    // this is where we will write our code

});

</script>

<!--  This is the container for the site map. -->
<div id="sitemap"></div>
  1. Go back to the page in your browser where you placed your CEWP.  Open the web part for modification and in the Content Link box, type the path of the SiteMap.js file.  The path to the file is relative to the site so normally, it would be resources/content/sitemap.js. Test your path to make sure.
  2. Save your changes.
Your environment is now set up.  I showed you how I prefer to set up my solution and explained how others have accomplished the same task.  The point to remember is that creating these types of solutions are simple and flexible. In the next post, we will start coding our solution.

Other posts in this series:

  1. Introduction
  2. Setting up the coding environment
  3. Create the chart
  4. Add content
  5. Conclusion

jQuery – .SPServices – Google.OrgChart API Mashup – Part 1

By , August 18, 2011 11:14 am

Part 1 – Introduction

A client had a requirement to modify an Org Chart that they had on their SharePoint (WSS3) site. When looking at it, I realized that it was an image with the links mapped. The image itself was sliced up pretty good and it was impossible to make the requested modifications because I didn’t have original image to edit.

I looked at different commercial Org Charts but the ones I looked at only displayed contact data either from Active Directory or a custom Contact List in SharePoint.

I knew that Google had a charting API and when I looked, that included an Org Chart. This API would work perfectly for me since my client wanted more of a Site Map that would illustrate their different department sites with links to each site, I needed to include HTML in the content of the ‘Nodes’ of the Org Chart. I quickly fired up SharePoint Designer and coded some jQuery and HTML to create the chart in a Content Editor Web Part (CEWP). It worked but my client would always need a web developer to make any modifications to the chart. What I wanted to do was to provide them with a solution that would allow them to make modifications to the chart without any developer resources.

I have been working with the wonderful SPServices jQuery library that Marc Anderson has written for sometime. I love the ability to query the SharePoint Web Services with jQuery. It provides some great possibilities. So, I noodled about and came up with the following solution, which I will cover in 5 parts. Please see the end of this post for links to the other parts.

The Pieces

The Requirement

The client wants to display a visual representation of their organization and provide links to their individual team site. The client wants to be able to modify the content and structure of the Organizational Chart without using developer resources. The end result should look like Figure 1.

Figure 1 - Org Chart Result

The Solution

After thinking about this requirements a bit, I thought that Google’s Visualization API, specifically their charting API might give me the tools necessary to actually draw an organizational chart. I knew that I could write some javascript code to access the API so that was pretty simple. I quickly set out to create an organizational chart using Goolgles OrgChart visualization and hard-coded all of the content. This provided the visual result I wanted but not the functional result. An end user would need to know HTML to be able to update the chart. What I wanted to do is to create a couple of lists that would drive the content and structure of the list. The perfect solution for this is Marc Anderson’s SPServices jQuery library for SharePoint Web Services. Marc has done a fantastic job with this library and is constantly updating the code to keep up with the changes in both SharePoint and jQuery. The SPServices library will allow us to query a SharePoint list and then parse the XML that is returned and send that data to the Google API to draw the org chart.

So, now that we have an idea of how we are going to create the solution, it’s time to set up the lists.

Setting up the lists

To make this easy to modify by anyone, I have decided to use two custom lists. The first custom list is to control the structure of the org chart. Two fields are necessary, a name for the node and what it’s parent is. Of course, the first node will not have a parent. I created a list with the following fields:

Field Name Type Notes
Title Single line of text
Parent Lookup This lookup field references the Title field in the same list.

Table 1 – Site Map List

Add the following content to the Site Map List

Title Parent
IT
Database IT
Systems IT
Collaboration IT

Table 2 – Site Map list content

To supply content to each node, I chose to use an additional list that I called Site Map Content. In this list, I needed to define the content line, any URL that the content would link to, the position the content should appear in the node and what node to place the content in. Table 2 illustrates how I created the content list.

Field Name Type Notes
Content Single line of text Renamed the Title field
Url Single line of text
Position Number set to zero decimal places, minimum number 1
SiteMapNode Lookup Lookup to the Site Map list and reference the Title field

Table 3 – Site Map Content List

Now add the following content to the Site Map Content List

Content Url Position SiteMapNode
Director: Jim Smith 1 IT
Manager: Bob Blisand 1 Database
Oracle Team Site # 2 Database
MSSQL Team Site # 3 Database
MySQL Team Site # 4 Database
Manager: Chris Cooper 1 Systems
Microsoft Systems Team # 2 Systems
Linux Team # 3 Systems
Manager: Wesley Willingham 1 Collaboration
SharePoint Development # 2 Collaboration
Web Development # 3 Collaboration

Table 4 – Content for the Site Map Content List

Now that we have the two lists created, we can begin coding. In the next part of this series, we will set up the environment we will need to code the solution.

+++++++++++++++++++++++++++++++++++

Other posts in this series:

  1. Introduction.
  2. Setting up the coding environment.
  3. Create the Chart.
  4. Add Content
  5. Conclusion

 

Dealing with corrupt WebConfigModification entries.

By , June 30, 2011 3:38 pm

Recently, I came across a problem.  I had created a new SharePoint Designer Custom Action and I created a feature solution package to deploy it to the production farm.  In testing it in a dev environment, I kept getting errors from the code I was using to make the appropriate web.config entries.  A custom SPD workflow action requires an ‘authorizedType’ entry in the web.config.  I have code in my feature receiver that will create a WebConfigModification entry in the WebConfigModifications collection and then use the SPService to apply the modifications.  (MSDN).  My problem was that someone had created a corrupt entry in the collection and it kept erroring out before executing my change.  It took a little understanding of how this works to find the solution to the problem.

The WebConfigModifications are a persisted object. That means that they remain until they are operated on.  In essence, it is a persisted queue.  Each entry is related to a SPWebApplication and added to the queue.  To remove the offending entry, I had to identify which web application the entry was registered with.  I just started going through every web application in my farm.  You could iterate through each application but in my case, I just hard-coded the URL for each application.  Here is the code that I used to clear the corrupt entries:


string siteUrl = @"http://localhost:44689";
SPSite site = new SPSite(siteUrl);
SPWebApplication webApp = site.WebApplication;
webApp.WebConfigModifications.Clear();
webApp.Update();
SPWebService service = SPWebService.ContentService;
service.WebConfigModifications.Clear();
service.Update();
service.ApplyWebConfigModifications();

I created a console app and put the code above in the Main() method. I kept executing the code using different web application URL’s until it executed without any error. Once I didn’t get an error, I was pretty sure that I had cleared the bogus entry. The next time I ran my feature code, it executed flawlessly!

A couple of notes. Obviously, this code is meant to be executed on the server and not a client. My dev machine has a single WFE. I would think that the best place to execute this would be on the same machine where Central Admin resides. Also – this was for a problem on a MOSS (WSS3) install. I am sure that it works the same in SharePoint 2010.

You can find the correct URL’s in IIS for each web application on your server. In my case, it was a shared development machine so there were many web applications executing under many different ports.

I love my Drobo!

By , May 26, 2011 10:24 am

What is a Drobo? Click Here to Find Out I have been a Drobo owner now for a couple of years.  It gives me the peace of mind knowing that my data is backed up in a safe, data-robot!  If a drive fails, no problem!  I can also put larger sizes in it anytime I want.  It is so easy.  Well, Drobo is having a sale and if you want one, you can click on the link below to take advantage of some great prices!  Here’s the skinny on the PROMO and remember t0 click the link below to go to Drobo!

+++++++++++

A. From now through the end of Memorial Day (5 days only, through midnight 5/30/11), we’re dramatically lowering prices on our most popular Drobo models.

Lowest price ever on these Drobos (after promo code):

  • Drobo (4-bay USB / Firewire): $298
  • Drobo FS (5-bay Gigabit Ethernet File Sharing): $598
  • Drobo S (5-bay eSATA / USB / Firewire): $698
  • Drobo Pro (8-bay iSCSI / USB / Firewire): $1398

B. We’re also giving you a chance to win double Drobos.

Just visit our online store and enter the promo code DOUBLEDROBO when you buy. You’ll receive the prices above, and you’ll also be entered for about a one-in-four chance to win a second Drobo for every one you ordered.

What is a Drobo? Click Here to Find Out

What Do You Want to Learn at Conferences?

By , March 24, 2011 11:50 am

I love speaking at SharePoint Conferences but I never know what to speak about. I’m an Architect/Developer so those would be the tracks I would cover. Mostly, I have been speaking about Planning a SharePoint deployment. I’d like to present  something development related but the topics aren’t popping out.

So, I’m soliciting ideas. I will do all the work – I just need some ideas on what is you want to hear!

Should I continue with my “planning” sessions?

How about some MOSS 2007 stuff?  Still interested in that?

Stuff you used to do in 2007 that you can’t figure out how to do in 2010?

Creating applications using only jQuery and javascript?

There’s a SharePoint Saturday coming up in St. Louis.  Maybe I can get one together for that!

 

It Happens To Everyone

By , February 22, 2011 4:32 pm

Unexpected Error at SharePoint.Microsoft.com

 

 A co-worker pointed this out to me.  Seems like someone was making a change to SharePoint.Microsft.com without testing and got the Unexpected Error!  I’m sure it was unexpected! 

The site was down for only a little while but it gave both of us a chuckle. 

Thanks Matt!

Problem POSTING a SharePoint form multiple times

By , December 6, 2010 11:59 am

I created a web part that displays data in an HTML table. On this web part, there is also a button that says, Export to Excel. When the button is clicked, the form posts to the server and my server-side code responds with an Excel file. The problem is that it only works once. To get it to work again, I have to refresh my page. Is SharePoint preventing me from posting more than once?

I wrote this same functionality using the jQuery library SPServices along with jQuery to create the table. I then use jQuery to post the form to a custom handler that returns an Excel file. Same problem. The form will only POST once.

Any ideas?

Confirmed for SharePoint Saturday – KC

By , November 18, 2010 4:12 pm

I just confirmed that I will be presenting at SharePoint Saturday – Kansas City on December, 11, 2010. Come join us. It is a lot of fun and there will be loads of SharePoint information.

Panorama Theme by Themocracy