Aidan Garnish

Collaboration Not Competition

Twitter SharePoint web part

** Update June 2010 - new Twitter web part using OAuth rather than Basic Auth **

I thought I would have a go at creating a web part to display a Twitter public timeline within SharePoint. The reason for creating this web part is so that it can be used by project teams that are spread over several offices/countries to stay in touch and feel more connected without having to invest a lot of time emailing each other or talking on the phone. Twitter is ideal for this kind of light weight communication as it restricts the user to sending short, to the point messages.

Before starting I had a quick look on the web to see if I was reinventing the wheel. Michael Gannotti suggests this solution using javascript and the CEWP but I wanted something that we would have a little more control over in terms of html markup and branding and that wasn't limited to the CEWP being available. I also wanted to have the possibility of extending the web part to include other functionality in the future such as not just being able to display tweets but to also send them.

The web part is configurable using two custom attributes - username and password. This allows you to display any users public timeline assuming you have the password. To set it up for use with a project team public timeline you should create a Twitter account for the project and then follow the members of the team to see a timeline that displays tweets from each of the members. 

At the bottom of this post there are links to the .wsp file which can be deployed to SharePoint using stsadm.exe and a .css file so that you can see how I chose to style the web part but obviously you could brand it any way you want.

**Update by request - more detail on deploying solutions

My solution uses Twitterlib.dll which is an open source .Net wrapper for the Twitter API and was created by the developers at Witty. This is a link to the Witty project on Google code. 

Download the wsp for the Twitter web part: TwitterPublicTimeline.wsp (24 kb)

For a styling suggestion try this css: twitter.css (302.00 bytes)

Was Gaudi an early adopter of Agile Scrum?

I have just got back from a weekend in Barcelona where I visited La Sagrada Familia and spotted the following quote that suggests Gaudi may have been an early adopter of Agile Scrum:

When I arrived at Sagrada Familia, I was able to live together with a few of Gaudi's co-operators. The Master enjoyed rousing his co-workers, inciting in them amazement for beauty. He would show them the model in which he expressed his ideas and waited until he saw their eyes shining in admiration. Affection for the project was borne from discovering its beauty. He would then ask: "What would you like to do?" Some would answer: "I want to do this, but don't know how to" "Well then we'll do it together?" Gaudi did not submit orders: he was the worker who was followed. This is the reason he was addressed as Master. - Etsuro Sotoo

One of the key components of Agile Scrum is that the team is self organising and is able to choose their own tasks from the product backlog rather than having them assigned by a project manager. It seems that Gaudi was ahead of his time in more than just architecture even going so far as being addressed as (Scrum) Master.

Another quote from La Sagrada Familia that I am sure is relevant to most IT projects and may give some New Year inspiration to those of us wrestling with them:

All I have ever achieved has depended on circumstances: if helpful, it was to adjust to the circumstances, and, if as obstacle, in order to struggle; they are always useful as they manifest the true revelation of Providence. - Antoni Gaudi

Happy New Year everyone!

Creating a custom save function for InfoPath 2007 browser based forms

I recently had an issue where it was necessary to only save some of the fields on an InfoPath form back to the form library. To do this required a combination of custom code and submission to a form library using a data connection.

The steps to do this were as follows:

1. Add a Save button to the form

2. Right click the save button and select button properties, change Action dropdown to Submit and click Submit Options...

3. In the submit options select Send form data to a single destination and choose SharePoint document library from the dropdown

4. Click Add to add a new data connection and follow the wizard to set this up to submit your form to the required library

5. Now that the data connection has been set up, select Perform custom action using Code and click the Edit Code button - this will create a submit method in the code behind file

6. In the submit method place the code to do the custom "stuff" and then submit the form to the data connection. The code will look something like:

public void FormEvents_Submit(object sender, SubmitEventArgs e)
{

           //remove values from the form that you don't want to be saved
           XPathNavigator xPnName = MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:Name", NamespaceManager);
           xPnName.SetValue("");

           //submit the form using the data connection

           DataConnections["Main submit"].Execute();

           //set e.CancalableArgs to be false once form has successfully saved

           e.CancelableArgs.Cancel = false;           
}

To give the form a unique filename and allow updates to saved forms do the following:

1. Create a new xml node called dtNow, give it a default value of now() and uncheck the Update this value when the result of the formula is recalculated box.

2. Go to Data and Data Connections and Modify the submit data connection created above.

3. In the Filename field add concat(userName(), dtNow) and check the Allow overwrite if the file exists checkbox.

Finally, convert the data connection used to submit the form to be centrally managed as described here

Using centrally managed SharePoint data connection files with InfoPath 2007

When deploying InfoPath forms with data connections between environments it is possible to use centrally managed data connection files to make the process a bit smoother.

To set up a centrally managed data connection do the following:

  • From your InfoPath form select Data Connections... from the Data menu
  • Select the data connection you want to make centrally managed and click the Convert button
  • A .udcx file will be created in a site collection data connections library you select so it may be necessary to set up a data connections library first
  • Navigate to the site collection data connections library and save the .udcx file locally
  • Go to SharePoint Central Administration - Application Management - Manage Data Connection Files
  • Upload the .udcx file to the central data connection files library
  • Go back to the InfoPath form and remove the existing data connections.
  • Recreate the data connections using Search for connections on a Microsoft Office SharePoint Server
  • Create the connection using the .udcx file that was saved to the site collection data connection library but make sure that you click on Connection Options... and select Centrally Managed
  • Configure the controls on the form to use the data connection as normal

The form will now use the centrally managed data connection. To deploy to another environment (eg. UAT, Production) you will need to upload the .udcx file to the relevant SharePoint Central Administraion after altering it to use the connection properties relevant to the new environment. To update the .udcx file open it in a text editor and alter the following parameters (example is for a connection to a SharePoint list):

   <udc:ListId>{175EC1CF-BF41-4848-B775-40277642B99F}</udc:ListId>
   <udc:WebUrl>https://productionurl.co.uk/</udc:WebUrl>

Where ListId is the SharePoint list id and WebUrl is the url of the site collection that holds the SharePoint list.

When you deploy your InfoPath form it will reference the centrally managed .udcx file allowing it to seamlessly connect with data in the new environment.

Generic CSV or SQL data importer for SharePoint list

UPDATE (09/10/09) - NEW AND IMPROVED VERSION HERE

I finally got bored of rewriting the same console application to move data from a csv or a sql table into a SharePoint list! The result is a generic console application that is capable of importing either a CSV file or some SQL data from a stored procedure. The app uses the object model so it needs to be run on the SharePoint server farm. I may get round to rewriting it using web services at some point. The CSV import parses the file so that things like line breaks and commas within fields are handled nicely. Any blank fields in the CSV do need to be filled using find and replace on blank space otherwise data ends up in the wrong columns.

To import a CSV the first row of the of the CSV file is used to define which columns the data will import to. Eg. A CSV that has one column with a header of Title will import the data into the Title column of the specified list. Modify the App.Config file to include the URL of your site collection, the list name, the path to the CSV and whether or not you want to delete all items in the list before importing.

To import SQL data create a stored procedure that returns the data as the names of the site columns

Eg. Select Name AS Title from tblPerson - will return one column of data that will import into the Title column of a list. Modify the App.Config to include the name of the stored procedure and the SQL connection string and run the app.

You can download the project from the following link:

AG.GenericSharePointListImporter.zip

This application is supplied as is and offers no guarantees feel free to use as you wish all I ask is that if you make any improvements then you share them in the comments or by email.

Change class on an HTML element using javascript

A basic javascript function to toggle an elements class property.

<script language="javascript">
 function ToggleClass(id, class1, class2)
 {
  try
  {
   if(document.getElementById(id).className == class1)
   {
    document.getElementById(id).className = class2;
   }
   else
   {
    document.getElementById(id).className = class1;
   }
  }

  catch(e)
  {
     window.alert(e.description);
   }
 }

</script>

An example of how this can be used to hide and show sections in a page:

<html>
<style>
.Row
{
   float:left;
   clear:left;
}

.AddressRow
{
   float:left;
   clear:left;
   padding:0px 0px 5px 0px;
}

.AddressRowNoDisplay
{
   float:left;
   clear:left;
   padding:0px 0px 5px 0px;
   Display:None;
}

.Field
{
   float:left;
   padding-right:10px;
}

</style>

<head>

<script language="javascript">


 function ToggleClass(id, class1, class2)
 {
  try
  {
   if(document.getElementById(id).className == class1)
   {
    document.getElementById(id).className = class2;
   }
   else
   {
    document.getElementById(id).className = class1;
   }
  }

  catch(e)
  {
     window.alert(e.description);
   }
 }

</script></head>
<body>

<div class="Row">
<div class="Field">Aidan Garnish </div>
<div class="Field">0191 4562736</div>
<div class="Field"><a href="javascript:ToggleClass('Address1', 'AddressRow', 'AddressRowNoDisplay')">Show/Hide detail</a>
</div>
<div id="Address1" class="AddressRowNoDisplay">
55 Jumble Avenue, Googenheim, GH1 5SD
</div>

<div class="Row">
<div class="Field">Brian Cosby </div>
<div class="Field">0192 3568736</div>
<div class="Field"><a href="javascript:ToggleClass('Address2', 'AddressRow', 'AddressRowNoDisplay')">Show/Hide detail</a>
</div>
<div id="Address2" class="AddressRowNoDisplay">
37 Ungerton Road, Googenheim, GH1 7WS
</div>

<body>
</html>

Hiding and showing optional sections in InfoPath 2007

It is possible to add logic to InfoPath forms so that certain fields are displayed based on the value of another field. For example - if a user fills in their age on a form as being 17 or greater then the question - Do you hold a full driving license? - becomes visible. In the UK this question is not relevant if the user is less than 17.

To do this using InfoPath 2007 you will need to create a form with the two questions - How old are you? and - Do you hold a current driving license? Add a two row, two column table to your form. Add the How old are you? question in the top left box. In the top right box add a text box that takes a whole number, call it Age and set it with a default of 0.

Next, merge the two cells in the bottom row and add an optional section control. Insert a table with one row and two columns to the optional control. Add the Do you hold a current driving license? question to the table. In the right hand table cell add a drop down list box that has options of select..., Yes and No.

Set the section properties to display the section by default. You should now have something that looks like this when previewed:

ShowHide1

Next right click on the optional section and select 'Section properties...' Select 'Display' and then 'Conditional Formatting...'

Click Add - set the condition to be Age is less than or equal to 16 and check the 'Hide this control' option.

Preview the form again and you should see:

Enter an age greater than 17 to display the optional question:

Change the age to less than 17 and the question will be hidden again.

Creating an InfoPath installer file with Visual Studio 2008

Having created an InfoPath form project using Visual Studio 2008 and adding some code behind to the form I wanted to deploy it to SharePoint. The easiest way to do this should have been to use the publishing wizard to create an installer file. However, there seems to be a bug in Visual Studio 2008 that prevents you from selecting this option in the wizard. The message displayed is that you need VS 2003 or 2005 installed to create the installer file.

There is a way around this by using the REGFORM.exe tool found in C:\Program Files\Microsoft Office\Office12. The tool allows you to create a .js file that marks the .xsn as fully trusted so that it can be added to the managed forms collection on your MOSS farm.

First you need to go to VS and the Publish option in the Build menu. Instead of selecting the create installer option publish to a network location and create the .xsn on your file system.

Next, open up a command prompt and navigate to C:\Program Files\Microsoft Office\Office12\regform.exe.

Supply the necessary parameters - these are, the /U the URN for the form which can be found in VS, File - Form Properties - ID, /T Yes to mark the form as fully trusted (this is necessary to deploy it to SharePoint) and finally the path to the .xsn file.

You should end up with something like - regform.exe /U urn:schemas-microsoft-com:office:infopath:MyForm:-myXSD-2008-08-07T13-36-16 /T Yes C:\Forms\MyForm

Running the command will create a .bak file and a .js file in the same folder as the .xsn. Run the .js file and then open SharePoint central administration. Go to the Applications tab and under the InfoPath forms services section select Manage Form Templates.

This Microsoft article explains the rest of the process to make the form available in a site collection in detail

If you run the .js in your development environment you will need to unregister the form before you will be able to open it again from Visual Studio. To do this open the .js file in Notepad and change var fInstall = true; to var fInstall = false; - Run the .js file again and this time the message prompts will tell you the form is being unregistered. You can now run the form from Visual Studio again.

Customising the pages approval for MOSS 2007 web content management

When I first looked at MOSS WCM to assess whether it would meet the needs of my previous employers web content approval processes many moons ago I was pleasantly surprised to find out how much you could achieve out of the box. Recently I needed to revisit this topic for a new client and promptly forgot what I had discovered and charged off looking at custom workflows using SharePoint Designer or Visual Studio. Fortunately before I got too far down that road I reigned myself in and went digging through the workflow settings of a pages library. This is what I found out/reminded myself of:

  • Using the set up screens you can change the lists used to store the workflow tasks and workflow history
  • Start options can be changed although the standard settings - 'Start this workflow to approve publishing a major version of an item.' is the most appropriate for approving a page for an Internet or extranet site
  • It is possible to switch between serial and parallel approval - most useful if a web page has to go to more than one person or department for approval or the page needs to be approved by people in a specific order
  • There are options to allow the following - 'Reassign the task to another person' and 'Request a change before completing the task' - these can be turned on or off as appropriate
  • Default approvers can be entered into the workflow

With all these options available it is possible to accomodate the vast majority of scenarios for approving web pages without having to resort to SharePoint Designer or Visual Studio. Even scenarios that involve several people or departments in the process can easily be catered for and using the 'Request change before completing the task' option even allows the page to be sent back for changes before approval is given. 

The moral of the story here is a common one when developing with SharePoint - don't try to reinvent the wheel, the SharePoint development team got there first!