Search This Blog

Showing posts with label development. Show all posts
Showing posts with label development. Show all posts

Tuesday, February 8, 2011

How to Manipulate the People Picker Control Using JavaScript


1. Introduction: While Microsoft provides some clear guidance on how to manipulate SharePoint 2007 controls using JavaScript (see the article here) this guidance does not include the People Picker control. The purpose of this article is to provide some of that missing guidance.

2. The People Picker: The People Picker control is more complex than other SharePoint form controls; while most of the SharePoint form controls provide a simple means to capture direct user input, the People Picker control goes beyond this simple functionality to allow the user to access and browse SharePoint’s security and accounts listings. Because of this added capability the control’s is more difficult to manipulate with JavaScript but, as you will see, there is still a way to use our method successfully.

3. The getTagFromIdentifierAndTitle Method: To locate the SharePoint form fields Microsoft recommends using the “getTagFromIdentifierAndTitle” function. The Microsoft SharePoint Designer Team tells us that “This function finds the HTML element rendered by a given SharePoint FormField control.” The signature of the getTagFromIdentifierAndTitle is as shown below:

getTagFromIdentifierAndTitle(tagName, identifier, title)

The function takes three parameters, tagName, identifier, and title:

• The first parameter, “tagName”, is the name of the field’s tag as it is rendered in HTML

• The second parameter, “identifier”, is the SharePoint field type

• The third parameter, title, is the value of the field’s “title” attribute as it is rendered in HTML and also the field’s display name in SharePoint

So, for example, to find a field named Title, which is a SharePoint Input control of the type Text Field, you would use the JavaScript below:

var titleField = getTagFromIdentifierAndTitle("Input","TextField","Title")

Once the value of the titleField variable is returned from the getTagFromIdentifierAndTitle, you can manipulate the Title field in a variety of ways by setting its properties programmatically. For example, if we wanted to now set the Title field to the value “New Title” we could do it like this:

titleField.value = “New Title”

4. People Picker Differences: So far so good, now let’s try to follow the same logic to find the value of a People Picker control, which for our example will be called “MyPeoplePicker”. Our function call might appear as the one shown below:

var vPeople = getTagFromIdentifierAndTitle("Input","Lookup","MyPeoplePicker")

But when we try to use this function to return the tag values of the People Picker control we get an “object set to null reference” error, or in other words, the getTagFromIdentifierAndTitle function cannot find a control matching the criteria we set. Several vain attempts later we learn that setting the parameters for the People Picker control is not easy or obvious. This is it not working because, as I stated earlier, the People Picker control is more complex.

If we could look inside the People Picker control we would see some surprising things, the first of which is that the People Picker control is actually not a Lookup control at all but actually a Rich Text Area, the same as the multiple lines of text control. Next we would see that the People Picker control type is “UserField_downlevelTextBox” – now who would ever guess that one? Finally, the last surprise is that the title of the People Picker control is not the same as the display title; instead its title will always be “People Picker”.

Armed with this new knowledge we have a new signature for our getTagFromIdentifierAndTitle function, which is shown below:

getTagFromIdentifierAndTitle("Textarea","UserField_downlevelTextBox","People Picker");

Now when we run our code again and this time it returns a value, the “object set to null reference” error is gone. So we are good to go – right?

5. Still More Surprises: Not so fast! We have a way to return the People Picker object but there are still issues, let’s do an example to illustrate this. We want to write some code to return the People Picker object and then set the objects display style to none, or in other words, hide the People Picker control from the user. Here is the code:

var vPeople = getTagFromIdentifierAndTitle("Textarea","UserField_downlevelTextBox","People Picker");

vPeople.style.display = “none”;

While this code will work with the other SharePoint controls it doesn’t work with the People Picker control. Like all things about the People Picker control, it’s a more complex. To make this line of code work for the People Picker we have to modify it as shown below:

vPeople.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.style.display="none";

Now who was expecting that? Here’s what is going on, the People Picker control is actually 12 (yes twelve!) levels below its HTML tag and so we have to use multiple parentNode declarations to navigate from the tag to the People Picker control. So our corrected code would be as it appears below:

var vPeople = getTagFromIdentifierAndTitle("Textarea","UserField_downlevelTextBox","People Picker");

vPeople.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.style.display="none";

Now our code finds and returns the People Picker control as well as manipulates it to hide it from the user. Problem solved!

Here is the entire code block:

//This runs the function when the form first loads
_spBodyOnLoadFunctionNames.push("validatePeoplPicker");

function validatePeoplPicker()
{
var assignedToSubmitter = getSPPeoplePicker("MyPeoplePicker");

//This function finds and returns the proper SharePoint control's HTML
function getTagFromIdentifierAndTitle(tagName, identifier, title) {
var len = identifier.length;
var tags = document.getElementsByTagName(tagName);
for (var i = 0; i < tags.length; i++) {
var tempString = tags[i].id;
if (tags[i].title == title && (identifier == ""
tempString.indexOf(identifier) == tempString.length - len)) {
return tags[i];
}}
return null;
}

//This function finds the People Picker control's Parent element
function getParentElementByTagName(baseNode, tagName) {
var currNode;
if (baseNode !== null) {
currNode = baseNode.parentNode;
while ((currNode !== null) && (currNode.nodeName != tagName)) {
currNode = currNode.parentNode;
}
return currNode;
}
else {
return null;
}}

//This function finds the People Picker control's Cell element
function getPeoplePickerCell(columnName) {
var search = 'FieldName="' + columnName + '"';
var nodes = document.getElementsByTagName("TEXTAREA");
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].title == "People Picker") {
var outerCell = getParentElementByTagName(nodes[i], "SPAN").parentNode.parentNode;
if (outerCell.innerHTML.indexOf(search) > 0) {
return nodes[i].parentNode;
}}}
return null;
}

//This function returns the People Picker object
function getSPPeoplePicker(columnName)
{
var cell = getPeoplePickerCell(columnName);
if(cell !== null)
{
return cell.childNodes[0].innerHTML;
}
else
{
return null;
} } }

6. Conclusion: The People Picker control definitely present more challenges to the SharePoint Designer/Developer, but by understanding it’s greater complexity you can begin to add dynamic functionality to your SharePoint forms using the People Picker control.

Thanks to Kiran Kakanur’s for his great blog - http://kiran-kakanur.blogspot.com/2010/02/hide-people-picker-control-in.html







Tuesday, December 14, 2010

SharePoint Form Dynamic Field Hide or Reveal Using JavaScript

1. From time to time a customer asks for fields to be dynamically hidden or revealed on the SharePoint EditForm.aspx or NewForm.aspx. One the most versatile and effective ways to accomplish this is by using the Content Editor Web Part and JavaScript. In this article I will guide you through configuring and developing this kind of functionality.

2. Here is our scenario; we need to add dynamic capability to a custom task form so that when the user edits the task form and chooses to reassign a task the hidden Reassignment Reason Multi-Line Text field is revealed. Our custom task form will have a customized Task Status field and an additional custom field, Reassignment Reason, as shown below:

a. Task Status (Choice)
  • Assigned
  • In Progress
  • Completed
  • Reassign 
b. Reassignment Reason (Multiple Lines of Text)

3. So the first question you may be asking is “How do I add a CEWP to the Edit and New forms?” I’m glad you asked! While the New and Edit forms do not provide an interface to access to the Edit Page function in the Site Actions menu, you can still get access to this capability through the browser by appending the following query to the end of the URL string for the New and Edit forms:

&pageview=shared&toolpaneview=2 

4. OK, so now that you can see the Edit Page interface of the Task Form lets add a CEWP in the usual way, just click on the “Add a Web Part” control at the top of the Web Part Zone and then from the Webpage Dialogue scroll down to the Miscellaneous section and choose Content Editor Web Part. Now click on the Add button at the bottom of the dialogue page and the CEWP will be added to the page.

5. Now click on the edit button of the CEWP in the Web Part Zone and choose the menu option “Modify Shared Web Part”. This will bring up the web part configuration interface in the right panel. From this interface click on the Source Editor and the text entry dialogue box will open. This is the area where you will need to write your code. We aren’t going to write any code right now though, so you can close the dialogue box.

6. Now we have to talk about the special JavaScript function we will need to use in order to “discover” the SharePoint controls in the task edit page – this function is called “getTagFromIdentifierAndTitle” and it is displayed below:

function getTagFromIdentifierAndTitle(tagName, identifier, title) { 
var len = identifier.length; 
var tags = document.getElementsByTagName(tagName); 

for (var i=0; i < tags.length; i++)

   var tempString = tags[i].id; 
   if (tags[i].title == title && (identifier == ""  ||
tempString.indexOf(identifier) == tempString.length - len))
   { 
       return tags[i];
   }
 } 
   return null; 


7. According to Microsoft this JavaScript function “parses the page’s query string, locates the HTML objects that are rendered by the relevant SharePoint fields, and sets their value.” The function can identify the fields by matching three parameters:

a. tagName – The name of the tag rendered in the form’s HTML
b. identifier – The string associated with the SharePoint type of the relevant field
c. title – The value of the relevant HTML tag’s “title” attribute, which also matches the field’s display name

8. While the title parameter is easy to obtain, one of the challenges you will often face when using this script is finding the tagName and identifier parameters. Microsoft provides a partial list as a starting point - see this tech net article:

http://blogs.msdn.com/b/sharepointdesigner/archive/2007/06/13/using-javascript-to-manipulate-a-list-form-field.aspx

9. However, there is another way to find this information, by using a very handy tool set that comes installed with Internet Explorer 8, and which Microsoft has very cleverly named “Developer Tools”. To activate the Developer Tools in IE, press F12 or use the "Tools" – "Developer Tools" menu. To find out more information about any element, click on the “Select Element” arrow in the tool set, and then select the element on the page. The tool set will take you to that elements markup and code and provide a great deal of information about that element to include the identifier and tag name. (If you don’t have the option of updating IE to 8 or higher, with IE7 you can use Developer Toolbar for Internet Explorer.)

10. OK, so now we need to create our function to hide the Reassignment Reason field when the user opens the page. Here is our basic function outline:

_spBodyOnLoadFunctionNames.push("hideField"); {   
var theInputMLTRR = getTagFromIdentifierAndTitle("TextArea","TextField","Reassignment Reason");  
//*** Hide the Field ***  
function hideField() 

   theInputMLTRR. parentNode.parentNode.parentNode.style.display = "none";
}  

function getTagFromIdentifierAndTitle(tagName, identifier, title) { 
var len = identifier.length; 
var tags = document.getElementsByTagName(tagName); 

for (var i=0; i < tags.length; i++)

   var tempString = tags[i].id; 
   if (tags[i].title == title && (identifier == ""  ||
tempString.indexOf(identifier) == tempString.length - len))
   { 
      return tags[i]; 
   } 

   return null; 
}


 a. spBodyOnLoadFunctionNames.push() – This is a built in SharePoint function that will allow you run a function when the page loads. This will be very useful to us because we want to hide the Reassignment Reason field before the form is viewed by the user. 
b. Script Variables – We need to set one variable, the Multi-Line Text Reassignment Reason. This variable will be set using the getTagFromIdentifierAndTitle function
c. style.display – setting this control property to “none” will hide the control from the user.

 11. Now we have to find a way to reveal the control if the user selects the custom task status choice “Reassign” (as well as a way to hide it back if she changes her mind and chooses another task status after the field is revealed). Here is our next bit of code, our revealField() function:

//*** Reveal the Field *** 
function revealField() 

   theInputMLTRR .parentNode.parentNode.parentNode.style.display = "";
}

12. All we need now is a way to capture the onChange() event for the custom Task Status field:

var theChoice = getTagFromIdentifierAndTitle("TextArea","TextField","Reassignment Reason");  
getTagFromIdentifierAndTitle("TextArea","TextField","Reassignment Reason").onchange = function(){revealHideControl()};  

//*** Reveal the Field *** 
function revealHideControl(){  
if (theChoice.value == 'Reassign') { 
revealField(); 
}else 

hideField(); 



13. All we have to do now is copy our script into the CEWP, so let’s go back to the web part configuration interface in the right panel. From this interface click on the Source Editor and the text entry dialogue box will open. Now just copy and paste the code below into the text box and click “Save” which will close the dialogue box. From the right panel interface click “OK” and then from the EditForm.aspx click OK again, and your form is ready to test.

_spBodyOnLoadFunctionNames.push("hideField"); {  
var theInputMLTRR = getTagFromIdentifierAndTitle("TextArea","TextField","Reassignment Reason");  

//*** Hide the Field *** 
function hideField() 

theInputMLTRR. parentNode.parentNode.parentNode.style.display = "none"; 
}  

//*** Reveal the Field *** 
function revealField() 

theInputMLTRR .parentNode.parentNode.parentNode.style.display = ""; 
}  

//*** Capture the Change Event *** 
var theChoice = getTagFromIdentifierAndTitle("select","DropDownChoice","Task Status");  
getTagFromIdentifierAndTitle("select","DropDownChoice","Task Status")onchange = function(){revealHideControl()};  

//*** Reveal or Hide the Field *** 
function revealHideControl()
{  
   if (theChoice.value == 'Reassign')
   { 
      revealField(); 
   } 
   else 
  { 
      hideField(); 
  } 


//*** getTagFromIdentifierAndTitle *** 
function getTagFromIdentifierAndTitle(tagName, identifier, title) { 
var len = identifier.length; 
var tags = document.getElementsByTagName(tagName); 

for (var i=0; i < tags.length; i++)

    var tempString = tags[i].id; 
    if (tags[i].title == title && (identifier == ""  ||
tempString.indexOf(identifier) == tempString.length - len))
   { 
      return tags[i]; 
   } 

   return null; 

}

14. There are other ways to find controls, such as using the returnObjById(id) function, but for whatever reason, Microsoft doesn’t recommend using this approach. On the other hand, in the SharePoint Community the getTagFromIdentifierAndTitle function is well known, well documented, and heavily used, so I recommend starting with this method whenever possible.

I hope that helps!

Tom Molskow








Thursday, October 7, 2010

Develop a SharePoint 2007 Event Handler (Part 3)

This is part three of a multi-part article.

For Part 1 see this link - Part 1.
For Part 2 see this link - Part 2.
For Part 4 see this link - Part 4.

1. To begin our development we will add the following class level variables for our due date calculations:

a. We will use this variable to determine the date offset for Holidays and weekends:

DateTime dtgToday = DateTime.Today;

b. We will use this variable to hold the holidays date from the Holidays list:

string strHolidays = "";

2. In order to work properly the application needs to know which sites, lists, libraries, views etc. it is manipulating. To accomplish this we will add the following class level variables to our application:

a. We will use a variable to hold the Absolute URL of the site (we need to use a specific site URL rather than a more general contextual reference because we only want this event handler to run on one specific site).

string strUrl = "http://MySPServer/sites/solutions/ContactUs/default.aspx";

b. Next, we need to instantiate an SPSite object based on the Absolute URL string:

SPSite siteCollection = new SPSite(strUrl);

c. And then we open the specific site passed through the URL string using the OpenWeb method of the SPSite class:

SPWeb web = siteCollection.OpenWeb();

3. Now we will just need a few more class level variables for our Holiday list and All Items view, because the application needs to pull from this list to perform it’s due date calculations:

a. The first variable will instantiate is a SPList object for the Holiday list:

SPList listHolidays = web.Lists["Holidays"];

b. Then we need to set the SPView properties to the “All Items” view:

SPView viewHolidays = listHolidays.Views["All Items"];

c. Finally we instantiate a SPListItemCollection and populate it with the items from the Holidays list, All Items view by using the GetItems method:

SPListItemCollection itemsHolidays = listHolidays.GetItems(viewHolidays);

4. The next code group will involves calculating the change to the Due Date when a Holiday falls during the two business days. Essentially, if you receive an e-mail on Tuesday, and you have two business days to respond, but Thursday is Thanksgiving, this calculation will add one more day to the due date to compensate for the holiday. The code simply loops through the collection of holiday dates from the Holidays list, All Items view, and if the Holiday date is equal to today (the day you receive the e-mail) or today + 1 (1 business day from today) or today + 2 (2 business days from today) then it will add one day to the dtgToday variable, which effectively extends the due date 1 day.

foreach (SPListItem item in itemsHolidays)
{
strHolidays = (string)item.Fields.GetField("Holiday Date").GetFieldValue(item["Holiday Date"].ToString());
if(dtgToday.ToString() == strHolidays
dtgToday.AddDays(+1).ToString() == strHolidays
dtgToday.AddDays(+2).ToString() == strHolidays)
{
dtgToday = dtgToday.AddDays(+1);
}

5. Now we will extract the metadata from the incoming e-mail and add it to the Inbox list, below is the code we need to start with. This code is pretty self explanatory; to begin with, we create a SPListItem object and set its properties equal to the collection of items in the List object. Now, you may ask, where did we declare List object? In the parameters of the overridden EmailReceived method call (see the previous article). Next we set each list item value on the left equal to the e-mail message value on the right. The only exception is the value of the Date Received field which we set equal to the dtgToday variable.

SPListItem Item = List.Items.Add();
{
SPListItem ListItem = List.Items.Add();
ListItem["E-mail Sender"] = Message.Sender.ToString();
ListItem["E-mail From"] = Message.Headers["From"];
ListItem["E-mail To"] = Message.Headers["To"];
ListItem["E-mail Cc"] = Message.Headers["Cc"];
ListItem["E-mail Subject"] = Message.Headers["Subject"];
ListItem["Title"] = Message.Headers["Subject"];
ListItem["E-mail Body"] = Message.HtmlBody;
ListItem["Date Received"] = dtgToday.ToShortDateString();

6. Now we only have one list field value left to set, the all important Due Date field. For our Due Date field we need to account for weekends so that we only count 2 business days. The logic is simple, if the e-mail arrives on Monday, Tuesday or Wednesday, we just add 2 days to today’s date to equal the due date. If the e-mail arrives on Thursday, Friday, or Saturday we add 4 days to account for a full weekend. And finally, if the e-mail arrives on Sunday, we add three days to account for a half weekend.

if (dtgToday.DayOfWeek == DayOfWeek.Monday
dtgToday.DayOfWeek == DayOfWeek.Tuesday
dtgToday.DayOfWeek == DayOfWeek.Wednesday)
{
ListItem["Due Date"] = dtgToday.AddDays(+2).ToShortDateString();
}
else if (dtgToday.DayOfWeek == DayOfWeek.Thursday
dtgToday.DayOfWeek == DayOfWeek.Friday
dtgToday.DayOfWeek == DayOfWeek.Saturday)
{
ListItem["Due Date"] = dtgToday.AddDays(+4).ToShortDateString();
}
else if (dtgToday.DayOfWeek == DayOfWeek.Sunday)
{
ListItem["Due Date"] = dtgToday.AddDays(+3).ToShortDateString();
}

7. Now we only have to add logic to capture attachments. We will need to instantiate two related object types for this code, a SPAttachmentCollection object to add attachments in the list and a SPEmailAttachmentCollection to extract attachments from the e-mail. Essentially we will loop through the SPAttachmentCollection object collection and for each SPEmailAttachment item in the SPAttachmentCollection create a list attachment item. I also added some logic for capturing attachments sent from Outlook. Because Outlook saves it’s attachments in a proprietary format, these files cannot be added to SharePoint list – for more information see here.

SPAttachmentCollection itemAttachments = Item.Attachments;
SPEmailAttachmentCollection emailAttachments = Message.Attachments;
foreach (SPEmailAttachment emailAttachment in emailAttachments)
{
if (emailAttachment.FileName != "winmail.dat")
{
byte[] emailAttachmentbytes = new byte[emailAttachment.ContentStream.Length];
emailAttachment.ContentStream.Read(emailAttachmentbytes, 0, (int)emailAttachmentbytes.Length);
itemAttachments.Add(emailAttachment.FileName, emailAttachmentbytes);
ListItem["Event Log"] = emailAttachment.FileName.ToString() + " : SharePoint added an attachement.";
}
else
{
ListItem["Event Log"] = emailAttachment.FileName.ToString() + " : SharePoint cannot add these types of attachements.";
}
}

8. Finally, we just add the statement to update the list item, and we are done.

ListItem.Update();

9. In my next article I’ll provide the whole code listing as well as discuss how to deploy the event handler as a feature using WSPBuilder, and also some ways to debug the feature.


I hope that helps!

Wednesday, October 6, 2010

Develop a SharePoint 2007 Event Handler (Part 2)

This is Part 2 of a multi-part article.

For Part 1 see this link - Part 1
For Part 3 see this link - Part 3
For part 4 see this link - Part 4

1. The next step is to start developing the custom event handler. For our development we will be using Visual Studio 2008 with WSPBuilder installed.

2. To create the Project follow these steps:

a. Open Visual Studio 2008

b. Create a new project of the type WSPBuilder Project, name it EmailEventHandlers

c. In Visual Studio, Right click on the project name and from the context menu choose Add -> New Item

d. From the pop-up dialogue box click on the WSPBuilder category in the left pane and choose the Event Handler Template in the right pane.

e. Name the event handler “EmailEventHandler”

f. A new pop-up menu will appear prompting you to add a Title, Description, and Scope, we will add the following information:

• Title: EmailEventHandler

• Description: A custom event handler for the e-mail received event.

• Scope: Web (Web Site or Sub Site)

g. WSPBuilder will create the correct 12-structure in the solution; it will also automatically add a reference to "Microsoft.SharePoint.dll" which is required by the event handler.

h. WSPBuilder will also automatically create the feature.xml and elements.xml with some of the tags pre-populated. We need to make a few corrections to the tags in the elements file:

• Name: EmailEventHandlers

• Type: EmailReceived

• Sequence: 20000

i. WSPBuilder also adds a class template as a starting point, and the class has the following using statements:

• using System;

• using System.Collections.Generic;

• using System.Text;

• using Microsoft.SharePoint;

j. WSPBuilder also adds some method stubs, but these are all related to the Item Add and Item Update events so we will not use them.

k. At this point, and due largely to WSPBuilder, all the initial work of project setup is already completed, and we can now proceed to the next step which is adding the remaining code framework.

3. To add the remaining code framework follow these steps:

a. Add the following using statements:

using System.Text.RegularExpressions;

using Microsoft.SharePoint.Utilities;

using Microsoft.SharePoint.Workflow;

b. Change the class inheritance from SPItemEventReceiver to SPEmailEventReceiver

c. Inside the class brackets delete the existing method signatures and add this method signature in their place:

public override void EmailReceived(SPList List, SPEmailMessage Message, string strReceiverData){ }

d. Your code so far should look as follows:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;

namespace EmailEventHandlers
{
     class EmailEventHandler : SPEmailEventReceiver
    {
        public override void EmailReceived(SPList List, SPEmailMessage Message, string strReceiverData)
       {
       }
    }
}

4. Now run build on the project, correct any errors if they occur (and hopefully they won’t) and you are now ready to begin the actual development, which will be the topic of my next Blog.

And that's all there is to it!

Tuesday, October 5, 2010

Develop a SharePoint 2007 Event Handler (Part 1)

This multi-part blog will lead you through the process of creating a custom SharePoint 2007 event handler.

For Part 1 see this link - Part 2.
For Part 2 see this link - Part 3.
For Part 4 see this link - Part 4.

1. Custom SharePoint event handlers are a powerful tool for any SharePoint solution. Essentially custom event handlers replace the default SharePoint list or library event handler behavior with more advanced and powerful behaviors. Custom event handlers add several capabilities to your list event, some of the capabilities you’ll want to explore include the following:

a. Extracting information from an e-mail sent to the list or library

b. Extracting information from another SharePoint list

c. Adding information to a SharePoint list

d. Performing calculations with SharePoint data

e. Starting a list or library workflow

2. Before you begin to design a custom event handler you will need two things a server environment, and a development environment. (To set up you own server environment see this article, and to set up your own development environment see this article). Assuming you already have these environments and they are configured as described in the articles above, let’s proceed with our development.

3. For our task we want to create a custom e-mail event handler. This e-mail event handler will allow us to task someone to answer e-mails that are sent to a SharePoint list. Basically, this event handler will create a list item in the Inbox list, calculate the due date for the response to the e-mail, and trigger a workflow that creates the response task.

4. Before we can develop we need to 1). Define functional requirements, 2). Define technical requirements, and 3). Design the solution, so let’s take it step by step. The functional requirements for our event handler are stated below:

a. When an e-mail is received create a new Inbox list item

b. Calculate the due date, which will be two business days from the date received to include accounting for weekends and holidays (holidays are determined by the Holiday list)

c. Trigger a workflow that creates the response task (task are created in the Task list)

5. The technical requirements for our event handler are stated below:

a. Create an Inbox list that is configured to receive e-mail, the structure of the e-mail list is shown below:



b. Create a Holidays list that is configure to capture holiday metadatathe structure of the e-holiday list is shown below:

c. Create a Task list that is configured to capture user tasksthe structure of the task list is shown below:



d. Create a SharePoint Designer workflow createTask that is designed to create a task in the Task list

e. Override the standard e-mail received event

f. Determine the site context

g. Capture the e-mail metadata

h. Calculate the due date using data from the Holidays list

i. Create a new list item in the Inbox list

j. Trigger the createTask workflow

6. Now using Visio we will create a very simple design, keep in mind this design is for explaining the event handler to our customers, not our fellow software engineers, so we will use the following simple block diagram:



7. Now we are all set to begin our development, which is where the next part of this article will begin.

I hope that helps, and I will write more soon!

Monday, October 4, 2010

Set Up a SharePoint 2007 Development Environment

This blog will help you set up your own SharePoint 2007 development environment.

1. To develop solutions for SharePoint 2007 you will need to install your development tools directly onto the SharePoint server. Since having development tools installed directly to the server is generally not allowed in production or even test environments you will need to build a separate development environment. By using Virtual PC 2007, you can easy to create a virtual SharePoint environment that runs on an average workstation. For more information on creating your own virtual development environment please see the article here.

2. Once you have established your development environment you will need to install and configure several development tools. The following list the set of development tools I use and, if the tools are free, I also list a download location. (I will describe how to install and use these tools later in the article.)

a. Visual Studio 2008

b. SharePoint Server 2007 SDK – Download Here

c. Visual Studio 2008 extensions for Windows SharePoint Services 3.0, v1.3 – Download Here

d. WSPBuilder – Download Here

e. Event Handler Manager – Download Here

f. Search Coder – Download Here

g. SP Log Viewer – Download Here

h. SharePoint Designer 2007 (Now a free tool!) – Download Here

i. Microsoft Visio 2007 – Visio is an optional tool, but given its usefulness for design diagrams I highly recommend it.

3. The first tool to install is Visual Studio 2008. I recommend installing the full MSDN Library with Visual Studio, it takes up a lot of additional space, but if this is your development environment there should be plenty of extra room on your hard drive. If you need help with the install there is a good Video Tutorial located here – Visual Studio Install Video. You will be prompted to choose your development environment, I choose “Visual C# Development Settings” but for SharePoint development you can also choose “Visual Basic Development Settings”. To establish that there are no issues with your Visual Studio install, and before proceeding with the rest of the steps, it’s a good idea to first create a throw away project, build it, run it, and check for configuration or install errors.

4. The next tool is the SharePoint Server 2007 SDK. The SharePoint Server 2007 SDK contains conceptual overviews, “How Do I…?” programming tasks, developer tools, code samples, references, and an Enterprise Content Management (ECM) starter kit to guide you in developing solutions based on Microsoft Office SharePoint Server 2007. The install instructions are very simple and can be found on the same page you download the SDK from. Again, to validate that the install went well, it’s best to open Visual Studio, click on Help -> Search, search for content related to the SharePoint object model, and check for configuration or install errors.

5. Now we can install Visual Studio 2008 extensions for Windows SharePoint Services 3.0 v1.3, or VSEWSS. VSEWSS provides SharePoint project and item templates for Visual Studio 2008. All things considered, the templates provided are limited, but for the most part they offer a better starting point then the out of the box Visual Studio templates. The install is very simple, and to test it I recommend that you open one or two templates, create a throw away project from it, and then check for configuration or install errors. The flowing templates are provided:

a. SharePoint Sequential Workflow

b. SharePoint State-Machine Workflow

c. Team Site Definition

d. List Definition

e. Blank Site Definition

f. Web Part

g. Empty

6. WSPBuilder is probably the best tool to become available for SharePoint development so far. WSP Builder is the invention of AnchorPoint who describes it as “A SharePoint Solution Package (WSP) creation tool for WSS 3.0 & MOSS 2007”. A more complete description is to say that WSP essentially takes the all the hard work out of creating WSP files and/or editing xml or ddf files manually. You can use WSP Builder to create the 12 “hive” structure and then add your features, web parts, receivers, etc. When you run WSPBuilder your code and artifacts get packaged into a solution file that can be passed to the SharePoint administrator for deployment. A great walk through of WSP Builder is provided by Tobias Zimmergren – you can view it here. WSP Builder is very easy to install, with Visual Studio closed, just run the MSI from your virtual environment, and once the install routine completes, open Visual Studio - WSP Builder will be installed.

7. Event Handler Manager is a special tool just for developing Event Handlers, but since most developers struggle with Event Handler debugging, this is a real must. Event Handler Manager allows the developer to browse, register and remove SharePoint event handlers. This application provides the ability to register event handlers to multiple lists at once as well as remove event handlers from multiple lists at once. This tool comes packaged as a Visual Studio project which you can then add to your project folders and run from Visual Studio.

8. Search Coder is another great tool, especially designed to help you write custom search web parts and solutions. Essentially, Search Coder allows you to connect to your SharePoint site and then try out different search queries using both the Object Model and Web Service. You can build, run and measure the performance of the query. To install just download the zip file, run install, and Search Coder will unpack to its own folder.

9. SP Log Viewer is an administrative tool not a development tool, but it is very useful to SharePoint developers. SP Log Viewer enables you to easily read and filter SharePoint log data from log files. If you have ever tried to extract useful information from the SharePoint log files you know this isn’t an easy process, and that is where SP Log Viewer can help. Again, the install is easy, just download the zip file, run the installer, and the utility will extract to its own folder.

10. SharePoint Designer (SPD) is an essential SharePoint development tools. It would take a separate article to describe everything SPD can do for the developer, but some of the main areas are site administration, trouble shooting, workflows, branding, Data View Web Part, XSL\XSLT, JavaScript and more. SharePoint Designer 2007 is now a free tool available from Microsoft, and there is an abundance of documentation available for it. The install is wizard driven and self explanatory.

11. Last but certainly not least is Microsoft Visio 2007 or 2010. In my opinion Visio is the best tool for designing SharePoint solutions and there are several great third party stencils available for SharePoint which you can purchase here. Once purchased the Visio install is wizard driven and self explanatory.

When it comes to SharePoint development, having the right tools is half the battle, armed with the tools I described in this article, you'll be well on your way to making great SharePoint 2007 solutions.

Tuesday, August 31, 2010

Checklist for a Virtual SharePoint 2007 Developer's Build

This is a quick Blog that provides a checklist for a virtual SharePoint 2007 developer's build:

1. Software List:
a. Virtual PC 2007
b. Windows Server 2003 R2
c. Microsoft SQL Server 2008 Enterprise
d. Microsoft Office SharePoint Server 2007 for Enterprise
e. SMTP Server
f. POP3 Server
g. Visual Studio 2008 Professional
h. SharePoint Designer 2007
i. Microsoft Office Viso 2007
j. Microsoft Office InfoPath 2007
k. Microsoft Office 2007 Professional
l. Microsoft Windows SDK v6.0A
m. Office SharePoint Server 2007 SDK
n. MSDN Library for Visual Studio 2008
o. Visual Studio Extensions for WSS 3.0 v1.3
p. WSPBuilder
q. Snippy – Visual Code Snippet Editor
r. NClass
s. SharePoint ULS Log Viewer
t. Windows PowerShell and PowerShell ISE
u. All Microsoft High Priority Updates

2. Virtual PC Install and Configuration:
a. Download Virtual PC 2007 (VPC07)
b. Install VPC07
c. Create a new Virtual Hard Drive (VHD)
d. Allocate 2750 KB’s of RAM to the VHD
e. Allocate at Least 100 GB of disk space to the VHD
f. Enable Undo Disk
g. Enable CD\DVD Second Controller
h. Set Floppy Disk to Auto Detect
i. Set COM 1 to the Physical COM 1 Port
j. Set LPT 1 to the Physical LPT 1 Port
k. Configure Networking to use the host system’s NIC
l. Enable Sound
m. Enable Hardware-Assisted Virtualization
n. Create a Share Folder
o. Set Display to use the guest operating system’s resolution
p. Set Close to Display all three options at shutdown: Save State, Shut Down, Turn Off

3. Operating System Install and Configuration:
a. Install Windows 2003 R2
   i. Obtain the proper ISO images and license Keys
   ii. Run Install Disk 1
   iii. Set Administrator’s Password
   iv. Run Install Disk 2
   v. Turn off Automatic Updates (this system will not be allowed to access the Internet)
   vi. Turn off Windows Firewall
b. Install Service Packs and Updates
   i. Install Windows Server 2003 R2 Service Pack 2
   ii. Got to the Windows Update Site and install all required updates
c. Assign Application Server Role to the Server
   i. From Manage Your Server assign the Application Server role
   ii. Install FrontPage Extensions
   iii. Enable ASP.NET
d. Install Active Directory Role
   i. From Manage Your Server assign the Active Directory role
   ii. Ignore the message about Static IP, choose Dynamically Assigned IP
   iii. FQDN: vmossdev.myserver.com(“v” for virtual)
   iv. Choose the option to install and configure DNS on the local server
e. Create all the SharePoint Service Accounts in Active Directory (See the MOSS 07 Installation Guide pages 12-14 for more detail)
f. Set all SharePoint Service Account GPO’s Directory (See the MOSS 07 Installation Guide pages 12-14 for more detail)
g. Create User Test Accounts in the Active Directory Users OU (password never expires): John Smith, Jane Smith, Joe Smith, June Smith
h. Check Windows Event Logs for errors and correct as needed

4. Database Server Install and Configuration:
a. Install SQL Server 2008
   i. Run the Installation Wizard
   ii. At the Feature Selection install step choose to install “All Features”
   iii. Choose “Default Instance”
   iv. Set SQL Agent to “Automatic”
   v. For SQL Server Reporting Services install the SharePoint Integration Mode Default Configuration
b. Install SQL Server 2008 Service Pack 1
c. Install the Adventure Works Database (the Adventure Works Database contains sample data for developing reporting applications)

5. Microsoft Office SharePoint Server 2007 Installation and Configuration:
a. Complete SharePoint 2007 Pre-Install Steps
   i. Disable Windows Fire Wall
   ii. Disable Internet Explorer Enhanced Security
   iii. Configure Component Services Directory (See the MOSS 07 Installation Guide pages 19-21 for more detail)
   iv. Install the SMTP Mail Server (* Access to production Exchange or other external Mail servers will not be allowed on the Development Server, this step is taken only to provide the capability to receive mail from another server in the Development environment.)
b. Install SharePoint
   i. Run the SharePoint Products and Technologies Configuration Wizard
   ii. Choose New Server Farm
   iii. Choose Complete Install
   iv. Use the SPSServerFarm account for the Database access account
c. Install Windows SharePoint Services 3.0 Service Pack 1
d. Install 2007 Microsoft Office Servers Service Pack 1
e. Perform Basic SharePoint 2007 Configuration (See the MOSS 07 Installation Guide pages 19-21 for more detail)
   i. Choose Single Server or Web Server
   ii. Start Windows SharePoint Services Help Search
      1. Service Account: Domain\SPSWSSSearch
      2. Content Access Account: Domain\SPSWSSCrawl
   iii. Configure and Office SharePoint Server Search Service
      1. Use this server for indexing content
      2. Use this server for serving search queries
      3. Farm Search Service Account: Domain\SPSMOSSCrawl
      4. Index Performance Partly Reduced
      5. Use All Web Front Ends for Crawling
   iv. Start Excel Calculation Services
   v. Create the Portal Web Application Pool (Port - 80)
   vi. Create the Portal Site Collection
   vii. Create the SSP Web Application Pool (Port - 400)
   viii. Create the MySite Web Application Pool (Port - 8000)
   ix. Create the SSP using the SSP and MySite Web Application Pools
   x. Configure Workflow Settings
   xi. Configure Outgoing E-mail
   xii. Enable Excel Services
   xiii. Configure Diagnostic Logging
   xiv. Enable Self Service Site Creation
   xv. Configure Session State (120 Minutes)
   xvi. Enable Features on Existing Sites
f. SharePoint Advanced Configuration
   i. Create managed paths: Search, Record Center, Report Center, Document Center, Publishing, collaboration, Development
   ii. Create a Record Center
   iii. In Central Administration, set the Record Center as the default
   iv. Create a Report Center
   v. Create a Document Center
   vi. Create a Publishing Site
   vii. Create a Collaboration Portal
   viii. Create a Search Center
   ix. Configure the Record Center, Document Center, Report Center, to use the Search Center for Advanced Search (See the MOSS 07 Installation Guide pages 97-98 for more detail)
   x. Publish Links for the Document Center, Publishing Portal and Collaboration Portal
   xi. Enable Usage Processing, 15 Log Files, Times - between 8:00 and 6:00 PM
   xii. Create Content Sources for the Portal, Record Center, Report Center, and Document Center
   xiii. Schedule Weekly Full Crawls for the Content Sources
   xiv. Schedule Incremental Crawls for the Content Sources
   xv. Run Full Crawl on all Content Sources
   xvi. Create a MySite (as Administrator)
   xvii. Configure Diagnostic Logging as needed for Development, example:
      1. Web Part Development: Category – Web Parts, Least Critical Event Log – Error, Least Critical Trace Log – Medium
      2. Workflow Development: Category – Workflow Features, Least Critical Event Log – Error, Least Critical Trace Log – Medium
g. Shared Service Provider Configuration
   i. Configure Usage Reporting:
      1. Enable Advanced Usage Analysis Processing
      2. Enable Search Query Logging
   ii. Start a Full User Profile Import
   iii. After Import has completed remove all profiles except the test users and the administrator
   iv. Create an Audience for Administrator’s, skills = Administrator, compile Audience
h. Configure Search in CA
   i. Contact E-Mail: searchservice@mossdev.net
   ii. Do not connect by using a proxy server
   iii. Timeouts: Connection – 60, Request – 60
   iv. Ignore SSL Certificate Warnings
i. Configuration Search in SSP
   i. Configure the Full Crawl Schedule for the Default Content Type
   ii. Configure the Incremental Crawl Schedule for the Default Content Type
   iii. Start a Full Crawl
   iv. After the Full Crawl has completed examine the Crawl Log for Errors and Correct as Needed

6. Development Tools Installs and Configurations:
a. Visual Studio 2008
   i. Install Visual Studio 2008
   ii. Install MSDN Library
   iii. Install Visual Studio 2008 SP1
b. Install SharePoint 2007 SDK 1.5
c. Install Visual Studio Extensions for WSS3.0 1.4 (for Visual Studio 2008)
d. Install SharePoint Designer 2007

7. Office Application Installs and Configurations:
a. Install Office 2007 Professional
b. Install Office 2007 Professional Updates
c. Activate Microsoft Office Products

8. SharePoint Tools Installs
a. Install WSP Builder
b. Install Snippy
c. Install NClass
d. Install SharePoint ULS Log Viewer
e. Windows PowerShell and PowerShell ISE

9. Activate All Software Products Online


And that's all there is to it!