Monday, October 20, 2008

Moving....

I'm moving my technical content posts to a new home:

http://dotnet.org.za/mariewessels/

Tuesday, May 20, 2008

Customizing the New Form toolbar

So, here's the requirement:

Add a control (for arguements sake a link button) to the NewForm.aspx toolbar for a specific list definition.

Sounds simple doesn't it? And in fact it is simple... Still took me 3 days to figure out!!

What you need to do is a write an web user control that defines how you want your toolbar to look like via a SharePoint rendering template. Something like this:


Note the name of the rendering template - CustomToolBar
Note also the fact that the attachment button and the link button both lack ID tags.


Right. Save that .ascx file to C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\CONTROLTEMPLATES

iisreset

Now, in your list schema, look riiiiiiiight at the bottom for the forms tag. See this tag?


<form type="NewForm" url="NewForm.aspx" webpartzoneid="Main"/>

You need to add a ToolbarTemplate attribute. Why did this take me three days? Because the toolbartemplate attribute is not declared!!!! It will be underlined in blue, but the solution will deploy. Don't try this in a content type, the content type feature will not be activated.

Anyway, at the end your NewForm declaration should look something like this:
<form type="NewForm" url="NewForm.aspx" webpartzoneid="Main" toolbartemplate="CustomToolBar"/>

And what you end up with should be:


Wednesday, March 5, 2008

ASPX Pages as SharePoint Features

So here’s the requirement:
You need a custom page in SharePoint (WSS 3.0) that must do something. For arguments sake, we’ll say it needs to allow a user to select information from some data source via a combo box and use that to populate a list.
How do you do this?
Part 1: Develop the web part.
Part 2: Create the web page.
Part 3: Add the web page as a feature to your site collection.

Part 1:
1. Create a new Visual Studio SharePoint project.
2. Add a web part to the project. For the purposes of my demonstration, I’ve created a web part that has a text box (for the list title), a drop down list populated by ten items and an ok button (code at the end of this part).
3. Deploy the web part to your site (in VS, just select deploy from the build menu. This should also create the setup.bat file & the MOSS solution, making future deployment incredibly easy).
4. Create a new web part page in your MOSS site.
5. Create a custom list with fields that match the fields you want to update (in my case, the title text field and an additional text field to hold my selected value).
6. Add the web part to your newly created MOSS page.
7. Test.

using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

namespace AddItem
{
[Guid("8f9851d9-c748-4806-b912-addd7a51beaf")]
public class AddItem : System.Web.UI.WebControls.WebParts.WebPart
{
protected DropDownList ddlAvailableValues;
protected System.Web.UI.WebControls.TextBox txtItemTitle;
protected System.Web.UI.WebControls.Button btnAddItem;

public AddItem()
{
this.ExportMode = WebPartExportMode.All;
}

protected override void CreateChildControls()
{
base.CreateChildControls();

ddlAvailableValues = new DropDownList();
ListItem[] memoryItems = new ListItem[11];
memoryItems[0] = new System.Web.UI.WebControls.ListItem("Please select a list item", "0");


for(int i = 1; i < l =" new" value =" i.ToString();" text =" string.Format(" cssclass = "ms-RadioText" txtitemtitle =" new" cssclass = "ms-long" btnadditem =" new" text = "OK" cssclass = "ms-ButtonHeightWidth" bloglist =" SPContext.Current.Web.Lists[" item =" blogList.Items.Add();">
My web part looks like this:








Part 2:
So far so good. Now we come to the “let’s cheat to make this easy part”. Hehe, I knew you’d like that.
You don’t want your web part page lying around in the library right? You want it to be part of your site collection, prefrably as a feature. That would be the ideal.
So, we fire up SharePoint Designer.
We open up the web part page that we created and added the web part to.
We copy the ASPX code.
We create a new ASPX file in the windows directory we want to use as our feature deployment folder (in my case BlogPages).
We copy the code into the new ASPX file.
And that creates our ASPX file. Now for ease of deployment.

Part 3:
Create a feature file.
Create an element manifest.
Deploy the feature (I do this via a setup.bat file that resides in the parent directory above my BlogPages directory).
Now, on the site you deployed the feature on, enter the URL of the page, for instance: http://servername/blog.aspx
And there you are. The page is part of your site, activated as a feature.
Life is beautiful.

My files for all this:



feature.xml


elements.xml



setup.bat

Set stsadm="C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\stsadm.exe"
Set url=""
Set featureFolder="C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\BlogPages\"

%stsadm% -o deactivatefeature -name BlogPages -url %url%
%stsadm% -o uninstallfeature -name BlogPages

rd /s %featureFolder% /q

xcopy /e "Feature\*" "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\"

%stsadm% -o installfeature -name BlogPages

%stsadm% -o activatefeature -name BlogPages -url %url%

pause

Thursday, January 24, 2008

Displaying a field for only the author of a list item.

Here is the problem: I need to display a custom list field for only the author of a discussion post.

Easy you say? Not so much when you have a custom list definition. You need to get hold of author ID and then compare it to the current user id, in the schema.xml

Getting hold of the author's id has to be done via the Lookup Column. Isn't that fun? Now my field is a checkbox allowing the user to close the discussion.

The important bit of code is:
<displaypattern>
<ifequal>
<expr1>
<lookupcolumn name="Author" showfield="ID">
<expr1>
<expr2>
<UserId/>
</expr2>

So a pretty short post but usefull I think.

Wednesday, January 2, 2008

Removing the New action from a MOSS List

So I had an interesting problem with the new project. The client wants an application that uses the dicussion board functionality, but with alot of additional functionality. Amoung other things, the ability to create new dicusssions on the discussion board itself should not be available.

I played around with alot of ideas, using security and disallowing everyone from creating new discussions, using CSS etc, but in the end the answer was surprisingly simple.

I found a javascript function on someone's blog (I'd credit him if I could find it again, too many blogs & Christmas & New Year in between). This javascript function, when added to master page, removed all New items from list menus that are document library types.

Ok, not exactly what I want, but at least a start. So I tried modding the javascript to work with my new feature off the masterpage. No luck. Then I played around with the CEWP, adding it to my forum. Worked like a charm, but I need to add alot of functionality besides this one and I could just extend the new template list with it's CEWP added.

Finally, the solution I found was: Add the javascript to the AllItems.aspx page of my forum, to the content area of the main place holder. Success!

This is the javascript:

function HideNewQADiscussionMenuItem()
{
try
{
var tables = document.getElementsByTagName("table");
for(var i=0; i<> 0 )
{
var elm = tables[i];
elm.parentElement.parentElement.style.display="none";
elm.parentElement.parentElement.nextSibling.style.display="none";
}
}
}
catch(e)
{
}
}

And here's how it fits in:


The last line is:
if(!document.all){ window.onload=HideNewQADiscussionMenuItem; }else{ HideNewQADiscussionMenuItem(); }

This makes sure the javascript is called when the page is loaded. And that removes the New fucntion from the top menu of my dicussion forum.

Step by Step:

  1. Create a new visual studio project, select List Definition from the SharePoint projects. Select the basic list to inherit from, in my case Discussions. This creates all ASPX files & XML files needed for a list definition.
  2. Open the AllItems.aspx file
  3. Find the PlaceHolderMain content tag.
  4. Below the web part zone, add the javascript. Remember the javascript tag & the line of code to make sure the javascript is called (I couldn't figure out why my script wasn't being called :P )
  5. Build & Deploy the solution (Visual Studio should have this option under the build menu, if it doesn't, you deploy the list definition as a feature).

And that's that. Your new list is ready for use. Of course, you now need some way to create new list items :)