Archive

Archive for the ‘Sharepoint’ Category

SharePoint updates hardcoded link html-tag in layout source code

September 7th, 2009

I recently stumbled upon a strange behaviour in a customers MOSS solution. We have inherited the support contract from another supplier, and I had to update their solution with a new front page template to be used for the different market sites, which in turn were linked from a global landing page.

Now, the upgrade went fairly well and all was in place after deployment except for one thing; the link from the landing page to their “global” market site was malfunctioning. The customer had created the new start page (named start.aspx) and renamed the old one to start_backup.aspx. The link to this page from the landing page was a hard-coded A HREF in the page layouts source code. The strange behavior is that SharePoint changed this hardcoded link in its database to lead to start_backup.aspx – It IS a ghosted layout, but I find it odd that SharePoint modifies it’s source. I had to open the page layout in SharePoint Designers designview and point the link to start.aspx manually to solve the problem.

peter Sharepoint, Uncategorized

Optional SPFieldLookupValue column in list and (none) yields different results!

February 5th, 2009

Suppose you have a list with a lookup field to another list, that is optional. Selecting “(none)” in the lookup yields different values in the column, depending on the layout of the lookup.

Lookup fields have different displays depending on the number of items in the list. It’s either a regular dropdown list (
<select>) or a select with 8 visible rows that pops up after you click the arrow-down icon.

Normal view:

 

Normal select-box, less than 20 items

Normal select-box, less than 20 items

 

 

Other view:

 

Irregular select-box, more than 20 items

Irregular select-box, more than 20 items

 

 

The first alternative gives the field value

null

and the second alternative gives the field value

"0;#"

The normal view is for lookups with less than 20 values.

I have not found anything about this behaviour in the documentation.

LookupField control

The control rendering the output for a lookup is the LookupField. Using reflector I found the reason in code (but not in the docs):

In CreateChildControls there is an if-statement checking if there are more than 20 items in the list, rendering the “Other view”.

Look at the DataSource property:

if (!lookup.Required && !lookup.AllowMultipleValues)
{
    DataRow row = table.NewRow();
    row[0] = 0;
    row[1] = SPResource.GetString("LookupFieldNoneOption", new object[0]);
    table.Rows.Add(row);
    num++;
}

peter Sharepoint

Remove the Title link, replacing it, in list views?

January 14th, 2009

Today a colleague of mine noticed the Title field both in the newform and list view of a custom list we are developing for WSS3. The list itself is not at all complicated, it’s an FAQ entry with two fields: Question (text) and Answer (richtext).

Replacing or removing the Title field was easy as pie, just remove it from the contenttype, with the following snippet inside the contenttype declaration:

<RemoveFieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}"/>

But, removing the title field also removes the handy link to view or edit the list item. Google gave very little on the subject, but I found some goodies here (scroll down to ChrisF post). So without removing the title field, I am going to examine how we can move the view/edit link to another field in the list, looking at how the original Title field works.

I fired up Caml Viewer to take a look on the list. Point Caml Viewer to the subweb containing the list, and view the list tab:

spcamlviewer

There is xml for the actual list, and the fields LinkTitle and LinkTitleNoMenu are defined in there, copy all text into your favourite editor and do a search for “LinkTitle” and “LinkTitleNoMenu”, respectively, and copy the entire <Field> declarations to a new editor window.

Now, generate a pair of fresh new Guid’s, replacing the ones in the two fields, and give them new names. I chose to call mine LinkQuestion and LinkQuestionNoMenu to keep the naming convention. Also go through the fields replacing references to the Title field with references to the Question field, etc.

Xml code for the two fields, after replacing Title for Question:

<Field ID="{1B451C6D-8766-4292-AEDA-62AB3413A66D}" ReadOnly="TRUE" Type="Computed" Name="LinkQuestionNoMenu" DisplayName="Question" Dir="" DisplayNameSrcField="Question" AuthoringInfo="(linked to item)" EnableLookup="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="LinkQuestionNoMenu" FromBaseType="TRUE">
<FieldRefs>
	 <FieldRef Name="Question" />
	 <FieldRef Name="LinkFilenameNoMenu" />
</FieldRefs>
<DisplayPattern>
	 <IfEqual>
		  <Expr1>
			   <LookupColumn Name="FSObjType" />
		  </Expr1>
		  <Expr2>1</Expr2>
		  <Then>
			   <Field Name="LinkFilenameNoMenu" />
		  </Then>
		  <Else>
			   <HTML><![CDATA[<a onfocus="OnLink(this)" href="]]></HTML>
			   <URL />
			   <HTML><![CDATA[" ONCLICK="GoToLink(this);return false;" target="_self">]]></HTML>
			   <Column HTMLEncode="TRUE" Name="Title" Default="(no title)" />
			   <IfEqual>
					<Expr1>
						 <GetVar Name="ShowAccessibleIcon" />
					</Expr1>
					<Expr2>1</Expr2>
					<Then>
						 <HTML><![CDATA[<img src="/_layouts/images/blank.gif" class="ms-hidden" border=0 width=1 height=1 alt="]]></HTML>
						 <HTML>Use SHIFT+ENTER to open the menu (new window).</HTML>
						 <HTML><![CDATA[">]]></HTML>
					</Then>
			   </IfEqual>
			   <HTML><![CDATA[</a>]]></HTML>
			   <IfNew>
					<HTML><![CDATA[<IMG SRC="/_layouts/1033/images/new.gif" alt="]]></HTML>
					<HTML>New</HTML>
					<HTML><![CDATA[">]]></HTML>
			   </IfNew>
		  </Else>
	 </IfEqual>
</DisplayPattern>
</Field>
<Field ID="{33AF1D6E-10D6-4e55-858F-C96836777A0E}" ReadOnly="TRUE" Type="Computed" Name="LinkQuestion" DisplayName="Question" DisplayNameSrcField="Question" ClassInfo="Menu" AuthoringInfo="(linked to item with edit menu)" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="LinkQuestion" FromBaseType="TRUE">
	<FieldRefs>
		 <FieldRef Name="Question" />
		 <FieldRef Name="LinkQuestionNoMenu" />
		 <FieldRef Name="_EditMenuTableStart" />
		 <FieldRef Name="_EditMenuTableEnd" />
	</FieldRefs>
	<DisplayPattern>
		 <FieldSwitch>
			  <Expr>
				   <GetVar Name="FreeForm" />
			  </Expr>
			  <Case Value="TRUE">
				   <Field Name="LinkQuestionNoMenu" />
			  </Case>
			  <Default>
				   <Field Name="_EditMenuTableStart" />
				   <SetVar Name="ShowAccessibleIcon" Value="1" />
				   <Field Name="LinkQuestionNoMenu" />
				   <SetVar Name="ShowAccessibleIcon" Value="0" />
				   <Field Name="_EditMenuTableEnd" />
			  </Default>
		 </FieldSwitch>
	</DisplayPattern>
</Field>

These fields are then placed in the list definitions schema.xml, in /List/MetaData/Fields.

Don’t forget to update ViewFields to reflect the change:
Change

<ViewFields>
	<FieldRef Name="LinkTitleNoMenu">
  </FieldRef>
</ViewFields>

Into

<ViewFields>
	<FieldRef Name="LinkQuestionNoMenu">
  </FieldRef>
</ViewFields>

and

<ViewFields>
	<FieldRef Name="LinkTitle">
  </FieldRef>
</ViewFields>

Into

<ViewFields>
	<FieldRef Name="LinkQuestion">
  </FieldRef>
</ViewFields>

Then just remove the Title field from your contenttype and you’re set!

Result:

question_link

A word of caution. More things depend on the Title-field, for example the breadcrumb and title bar, so these fields will display (no title), after this operation:

result_missing_title

peter Example, Sharepoint , ,

AvailableWebTemplates – for WSS

December 17th, 2008

MOSS publishing infrastructure gives the possibility to declare which web templates that are available on subwebs, in a feature property:

<Properties>
   <Property Key="AvailableWebTemplates" Value="*-MyTemplateName#1"/>
</Properties>

But this is not possible in the same way for WSS. The object model gives us two hints: SPWeb.SetAvailableWebTemplates and SPWeb.SetAvailableCrossLanguageWebTemplates These methods can be used to achieve the same goal: controlling which web templates that are available for creation from a certain site template in the UI (although I have not got the cross language version to work). A feature receiver in a feature stapled to my site template can be used to set which web templates that are available. The code for to set which templates are available are contained in a separate method:

/// <summary>
/// Set available templates for creating subwebs
/// </summary>
/// <param name="web">the web it concerns</param>
/// <param name="siteTemplateNamePredicate">how to match the template name</param>
public static void SetAvailableSubWebTemplates(
	SPWeb web, Predicate<String> siteTemplateNamePredicate,
	bool currentLocale)
{
    Collection<SPWebTemplate> collection = new Collection<SPWebTemplate>();
    foreach (SPWebTemplate template in web.GetAvailableWebTemplates(web.RegionalSettings.LocaleId))
   {
       if (template != null &&
           template.IsSubWebOnly &&
           siteTemplateNamePredicate.Invoke(template.Name))
       {
            collection.Add(template);
       }
   }
   if (collection.Count > 0)
   {
       web.SetAvailableWebTemplates(collection, web.RegionalSettings.LocaleId);
       web.Update();
   }
}

Finally, how to use this method from the feature receiver:

Predicate<String> predicate = new Predicate<string>(s => s.StartsWith("STS"));
SetAvailableSubWebTemplates(web, predicate);

peter Sharepoint , ,