Tuesday, May 6, 2008

Override the Edit Form SaveButton - Part 1

An overview of how to override the action of the Save Button in a SharePoint form for a specific document library (in this case a Wiki library). The intention of this brief series of articles is to record how to add a custom behaviour to the Save button of a wiki edit form.

The elements in this solution can be all included in a single Visual Studio solution, but I suggest that they are compiled into several separate SharePoint features for ease of management/deployment. All the features can be referenced in a single Manifest.xml file.

1. Create a content type feature to define a custom content type for the document library. In the XmlDocument section of the ContentType definition, specify the name of a custom template for the edit form template:


<XmlDocuments>
<XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
<FormTemplates xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
<Display>DocumentLibraryForm</Display>
<Edit>MyCustomWikiEditForm</Edit>
<New>WikiEditForm</New>
</FormTemplates>
</XmlDocument>
</XmlDocuments>

The result of this will be that any library using this content type will display the custom content (to be created in later steps) on the edit form.

2. Create a user control file containing a new RenderingTemplate with the
template custom ID matching that in the custom content type.

To achieve this, create the new ascx file in the Visual Studio solution (as an example, I'll name it MyCustomWikiEditForm.ascx). Copy the Assembly and Register tags from the top of DefaultTemplates.ascx (located in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\CONTROLTEMPLATES).

Then find (in DefaultTemplates.ascx) the RenderingTemplate node for the template being replaced, and copy/paste this into the new ascx file - in this case, I would copy the complete RenderingTemplate with ID of WikiEditForm into my new ascx file. Rename the ID of the RenderingTemplate to match the custom ID from step 1 (i.e. to MyCustomWikiEditForm).

This new ASCX file will need to be deployed to the CONTROLTEMPLATES folder by stating the destination folder in a TemplateFiles node in the Manifest.xml for the solution, as in the following example snippet:

<TemplateFiles>
<TemplateFile Location="CONTROLTEMPLATES\MyCustomWikiEditForm.ascx" />
</TemplateFiles>

In the next installment, I'll look at modifying the edit template to include a custom save button.

Sunday, April 6, 2008

Whoops, Where are Those Site Themes Hiding?

I am trying to persuade the application pages in a WSS site to look similar to the site pages that are customised by a master page - my approach was to create a new theme, and modify the CSS in that theme using the CSS applied to the master page.

It almost worked, but had a nasty side-effect. Some part of the CSS caused the "select theme" list on the Site Theme admin page to be squashed out of screen space by the left-hand cells expanding too far across the page. The image of the still displayed, but there was no way to remove the bad theme.

Oh dear, what to do?

Then some playing in the IE Developer toolbar revealed a solution - the toolbar allows CSS styles to be edited and applied in the live page. I applied a width attribute to several of the cells in the affected table, and managed to reveal the theme list box in the displayed page, thereby allowing me to reapply the default theme before modifying the new theme.

This difficulty in modifying the application pages to match the site pages is an oft-quoted citicism of SharePoint. During a little research for this post, I have noticed that Microsoft has published a KB article on their recommended server-side fix for this.

Thursday, March 13, 2008

A Few Useful WSS Icons

Based on an idea in the AutoSponge blog, here are content editor web parts that display some of the icons available in WSS:
You can simply import these into any page on a WSS site to see the icons - right click on the links above, save the dwp files and then import 'em.

Thursday, February 28, 2008

Why Reflector is a Developer's Friend

If you have been wondering why some .net developers rave about Reflector as the one tool that rules them all, and have thought that maybe you should give it a try, here's a little tale about how it made my day better... (hope it encourages you)

Whilst attempting to bind an SPGridView to a LinqDataSource, one of the requirements was to use the filtering features of the SharePoint gridview (that's one of it's strengths above the standard GridView control).

I came across a post by Robert Fridén that described how to enable filtering when binding to an ObjectDataSource. An SPGridView property named FilteredDataSourcePropertyName needs to be set, and that must contain the name of the property on the bound datasource which will be called when filtering the data. In other words, it requires a string containing the name of a control property.

For an ObjectDataSource, that property is named "FilterExpression". I decided it was highly unlikely that the LinqDataSource would use the same property name, so I turned to Reflector.

In Reflector, I found and opened the System.Web.Extensions dll, browsed to the LinqDataSource class and then looked through the properties. Didn't need to right-click and disassemble the dll in this case, as one of the properties was named "Where". Sounded a good option for filtering. So I used that as the FilteredDataSourcePropertyName value, played around a little with the FilteredDataSourcePropertyFormat property of SPGridView, and hey presto the filtering worked. Sure, I could have looked through the MSDN documentation, but with Reflector I can browse inside the methods of the data source class if needed.

If you've not yet delved inside the .Net dlls with Reflector, give it a go. You'll be rewarded!

...and by the way, as tempting as it was I just couldn't bring myself to put the word"best" in the title ;-)

Sunday, February 24, 2008

VMWare Virtual Machine 'Failed to Lock the File'

Scary moment occurred last week when one of my virtual machines failed to start from VMWare Workstation. The reported error was "failed to lock the file". A bit of searching revealed that I needed to delete the .LCK file in the VM's folder.

The cause for this (I think) was that I had opened the virtual disk of this VM as a mapped drive on the host machine (TIP: very useful feature to get at files from the VM without powering it up - just right click on the .VMDK file in Windows Explorere, and you'll see a couple of options there to map the disk as a drive). That drive was still mapped when trying to start the VM, meaning that the host machine was accessing the VM's files.

Thursday, February 14, 2008

Some OWSSVR Parameters are Case-Sensitive

Experimenting with some owssvr URL protocol calls today, and kept getting error pages back when trying to retrieve data from a particular view by specifying a "View" parameter in the querystring

e.g. http://[site url]/_vti_bin/owssvr.dll?CS=109&List={list Guid}&View={View Guid}

Tried swapping various list ids, and removing the view id parameter. Well, it turns out that the View ID is CASE-SENSITIVE, yet the List ID value is not case-sensitive. Cunning way to throw me off the scent, there!

Monday, February 4, 2008

MOSS Search Box Missing Search Scopes

Had a situation where the search box on the SharePoint home page on a MOSS site was missing the "All Sites" and "People" options in the search scope dropdown.

Luckily John M. Cass has posted a fix - if the display group named "Search Dropdown" is missing (you only see the group named "Unused Scopes" on the Search Scopes admin page in the Site Settings), add a new group named "Search Dropdown" and add the two scopes to that group.

Thanks for that, John.