Ok so one thing that I haven’t blogged about is developing Web Parts for SharePoint 2007.
One thing about it is that nowadays it’s very easy, far less complicated then SPS 2003 days. As a matter of fact if you’re running Visual Studio 2005 with Office SharePoint Server 2007 SDK 1.2 and Visual Studio 2005 extensions for Windows SharePoint Services 1.1 CTP.
All you really have to do is create a Web Part project, override the right method, press the little “Play” button on top of your Visual Studio (or hit F5) and “Voila!” your brand new Web Part is in your SharePoint Web Part Library, ready to be added to your SharePoint page.

Now that makes the whole experience nice and easy, but sometimes you look around and you wonder why when, for example someone assigns a task to you, you don’t get to see it on your Task Assignments web part on your portal straight away. Then you remember that you need to hit F5 to refresh, but you find doing something like that often annoying.
You ask yourself: “Shouldn’t these web parts use AJAX?”
Well, trouble is that AJAX with SharePoint 2007 is a bit tricky, as opposed to a conventional ASP.NET AJAX application.
The example that I’m going to show you is how to design an AJAX Web Part that will use the update panel and timer control to continuously update tasks from a certain task list in SharePoint 2007 called “Tasks”.
This example is similar to this ASP.NET tutorial (http://www.asp.net/AJAX/Documentation/Live/tutorials/IntroToTimerControl.aspx) with a difference that it involves SharePoint and Web Parts.

Instructions:
1. You download and install ASP.NET 2.0 AJAX Extensions 1.0(http://asp.net/ajax/downloads/default.aspx).
2. You go to this brilliant post from Mike Ammerlaan (http://sharepoint.microsoft.com/blogs/mike/Lists/Posts/Post.aspx?ID=3) and you do everything that he says you should do (up until the code example at the end).
3. Although Eric will tell you in his excellent example (http://www.capdes.com/2007/02/microsoft_office_sharepoint_se.html) that you shouldn’t worry about modifying the master page. As Mike says here (http://sharepoint.microsoft.com/blogs/mike/Lists/Posts/Post.aspx?ID=5):
“Note that he uses a dynamic approach to inserting the ScriptManager onto the page. As I mention below, I don't think this is a recommended practice from the ASP.NET team, but it looks like he got it working for his scenario. I'd generally still recommend just embedding the ScriptManager into the master page.”
I personally suggest you listen to Mike.
4. You follow the instructions as I outlined them at the beginning of the post including this code:
using System;
using System.Collections;
using System.Text;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
namespace NewAjaxWebPart12
{
[Guid("e9205f3c-3043-4891-938e-0ea62c13003f")]
public class NewAjaxWebPart12 : System.Web.UI.WebControls.WebParts.WebPart
{
public NewAjaxWebPart12()
{
this.ExportMode = WebPartExportMode.All;
}
private Label label;
private string htmlstuff = null;
protected override void CreateChildControls()
{
base.CreateChildControls();
this.EnsureUpdatePanelFixups();
UpdatePanel up = new UpdatePanel();
up.ID = "UpdatePanel1";
up.ChildrenAsTriggers = true;
up.UpdateMode = UpdatePanelUpdateMode.Conditional;
this.Controls.Add(up);
this.label = new Label();
this.label.Text = "It hasn't kicked in yet. ";
up.ContentTemplateContainer.Controls.Add(this.label);
Timer timer = new Timer();
timer.Interval = 10000;
timer.Tick += new EventHandler<EventArgs>(HandleButtonClick);
up.ContentTemplateContainer.Controls.Add(timer);
}
private void HandleButtonClick(object sender, EventArgs eventArgs)
{
using (SPWeb web = SPContext.Current.Site.OpenWeb())
{
SPList taskList = web.Lists["Tasks"];
foreach (SPListItem item in taskList.Items)
{
string prefix = null;
string last = null;
string[] split = item.Url.Split(new Char[] { '/' });
foreach (string credential in split)
{
prefix += @"/" + credential;
last = prefix.Substring(0, prefix.Length - credential.Length);
}
htmlstuff += @"<a href='" + web.Url + last + @"/DispForm.aspx?ID=" + item.ID + @"'>" + item["Title"].ToString() + @"<a><br />";
}
}
this.label.Text = htmlstuff;
}
private void EnsureUpdatePanelFixups()
{
if (this.Page.Form != null)
{
string formOnSubmitAtt = this.Page.Form.Attributes["onsubmit"];
if (formOnSubmitAtt == "return _spFormOnSubmitWrapper();")
{
this.Page.Form.Attributes["onsubmit"] = "_spFormOnSubmitWrapper();";
}
}
ScriptManager.RegisterStartupScript(this, typeof(NewAjaxWebPart12), "UpdatePanelFixup", "_spOriginalFormAction = document.forms[0].action; _spSuppressFormOnSubmitWrapper=true;", true);
}
}
}
Sorry about the funny construct of the URL for the tasks (I did it in a rush), but for some reason item.Url doesn’t actually give you a proper URL.
1. Does someone out there know a cleaner way to extract URLs for individual items on a list in SharePoint 2007?
Also there’s another brilliant example (by Mark Collins) of how to build a web part using a SPGridView inside an ASP.net Ajax UpdatePanel (http://sharethispoint.com/archive/2007/02/28/Using-a-SPGridView-inside-an-ASP.net-Ajax-UpdatePanel.aspx) with the source code.
2. Can someone tell me why does he have the following bug?
“For some weird reason the first time you use the pagination or sorting it does a refresh of the entire page, but every time after that it works correctly. Kind of a tweaky little bug, if any one figures out why this is happening please let me know. The updatepanel only seems to do this with the SPGridView.”
Good answer to either one of the two questions (first one should include a code snippet) will be rewarded with a Microsoft t-shirt (or another available gift of choice) in one of my upcoming events (I’m not posting it to anybody).
My following posts will tell you more about upcoming events where I’ll be the speaker.
You can download the source code to this example here (http://dotnet.org.za/blogs/zlatan/ajaxpost/NewAjaxWebPart12.zip).
Dev Environment for this example:
Windows Server 2003 Enterprise Edition SP1
SharePoint Server 2007 Enterprise Edition
Visual Studio 2005 Team Edition for Software Developers
Visual Studio 2005 with Office SharePoint Server 2007 SDK 1.2
Visual Studio 2005 extensions for Windows SharePoint Services 1.1 CTP