Showing posts with label DataFormWebPart. Show all posts
Showing posts with label DataFormWebPart. Show all posts

Thursday, 25 February 2010

How to Add Current Item Field Values to DataFormWebPart as a parameter

How to Add Current Item Field Values to DataFormWebPart as a parameter

One of my colleague had to implement a page which should give master detail functionality. So the requirement was displaying related items in the display form page. So she placed two webparts one for current list item (master) and one for related items (details). As it was display form (DispForm.aspx) the only she had was ItemID which is in the querystring. But it was not enough, she wanted it to pass One of the current item field value to filter related Items List. There is no option in the DataFormWebPart to get that. Therefore she asked me if there is any workaround for this.

I did couple of investigation but could not find anything. Then I produced the following solution.

Basicly you place the following class into your project. That is a replacement for DataFormWebPart which allows you to set current Item Field Values as parameters.

* Deploy this class with your DLL into GAC
* Add this as a safe control into web.config
* Open your page do the following modifications

Place this to your page and change assembly, namespace with yours.

<%@ Register Tagprefix="ExWebPart" Namespace="Sobiens.SharePoint.WebParts" Assembly="Sobiens.SharePoint, Version=1.0.0.0, Culture=neutral, PublicKeyToken=e76709a445fee1d6" %>

Goto DataFormWebPart tag and change it to <ExWebPart:EnhancedDataFormWebPart
Finally change your parameterbinding

<ParameterBinding Name="Country" Location="None" DefaultValue="currentitemvalue(Country)" />

This will set Parameter named Country to current item Country field's value.

Hope this helps.



public class EnhancedDataFormWebPart : DataFormWebPart
{
XmlDocument _ParameterBindingsXmlDocument = null;
XmlDocument ParameterBindingsXmlDocument
{
get
{
if (_ParameterBindingsXmlDocument == null)
{
_ParameterBindingsXmlDocument = new XmlDocument();
_ParameterBindingsXmlDocument.LoadXml("" + this.ParameterBindings + "");
}
return _ParameterBindingsXmlDocument;
}
}

XmlNode _ParameterBindingsXmlNode = null;
XmlNode ParameterBindingsXmlNode
{
get
{
if (_ParameterBindingsXmlNode == null)
{
_ParameterBindingsXmlNode = ParameterBindingsXmlDocument.SelectSingleNode("/ParameterBindings");
}
return _ParameterBindingsXmlNode;
}
}


private void SetParameterBinding(string key, string value)
{
XmlNode node = ParameterBindingsXmlNode.SelectSingleNode("/ParameterBindings/ParameterBinding[@Name = '" + key + "']");
if (node == null)
{
XmlNode parameterBindingNode = ParameterBindingsXmlDocument.CreateElement("ParameterBinding");

XmlAttribute nameAtrribute = ParameterBindingsXmlDocument.CreateAttribute("Name");
nameAtrribute.Value = key;
XmlAttribute locationAttribute = ParameterBindingsXmlDocument.CreateAttribute("Location");
locationAttribute.Value = "None";
XmlAttribute defaultValueAttribute = ParameterBindingsXmlDocument.CreateAttribute("DefaultValue");
defaultValueAttribute.Value = value;

parameterBindingNode.Attributes.Append(nameAtrribute);
parameterBindingNode.Attributes.Append(locationAttribute);
parameterBindingNode.Attributes.Append(defaultValueAttribute);

ParameterBindingsXmlNode.AppendChild(parameterBindingNode);
}
else
{
node.Attributes["DefaultValue"].Value = value;
}
}

private void ReplaceFormParameterBindings()
{
foreach (XmlNode node in ParameterBindingsXmlNode.ChildNodes)
{
string defaultValue=node.Attributes["DefaultValue"].Value;
if (defaultValue.ToLower().StartsWith("currentitemvalue(") == true)
{
int startIndex = defaultValue.IndexOf("(");
int lastIndex = defaultValue.IndexOf(")");
string fieldName = node.Attributes["DefaultValue"].Value.Substring(startIndex+1, lastIndex - startIndex-1);
if (SPContext.Current.Item[fieldName] != null)
{
node.Attributes["DefaultValue"].Value = SPContext.Current.Item[fieldName].ToString();
}
}
}
}

private void SetPropertiesAsParameterBindings()
{
ReplaceFormParameterBindings();
this.ParameterBindings = ParameterBindingsXmlNode.InnerXml;
}

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
SetPropertiesAsParameterBindings();
}
}

Saturday, 12 December 2009

How to add parameters from different sources to DataFormWebPart

Although DataFormWebPart supports several ways to get such as QueryString, Control values, CAML variable etc, There are some cases we need to assign parameters from codebehind. I am not going to show all the scenarios but I will give you hint how you can extend dataform webpart to allow taking parameter variables from different sources.

The first thing we need to do is, creating a new class which will inherit from DataFormWebPart.

using System;
using System.Text;
using Microsoft.SharePoint.WebPartPages;
public class EnhancedDataFormWebPart : DataFormWebPart
{
}

The way we do is, replacing ParameterBindings string property inside of DataFormWebPart. This property is a xml string. We will load it as xml document and use following properties to make it accessible in our code.

XmlDocument _ParameterBindingsXmlDocument = null;
XmlDocument ParameterBindingsXmlDocument
{
get
{
if (_ParameterBindingsXmlDocument == null)
{
_ParameterBindingsXmlDocument = new XmlDocument();
_ParameterBindingsXmlDocument.LoadXml("" + this.ParameterBindings + "");
}
return _ParameterBindingsXmlDocument;
}
}

XmlNode _ParameterBindingsXmlNode = null;
XmlNode ParameterBindingsXmlNode
{
get
{
if (_ParameterBindingsXmlNode == null)
{
_ParameterBindingsXmlNode = ParameterBindingsXmlDocument.SelectSingleNode("/ParameterBindings");
}
return _ParameterBindingsXmlNode;
}
}

Lets also add this helper class to be able to manipulate xml document.

private void SetParameterBinding(string key, string value)
{
XmlNode node = ParameterBindingsXmlNode.SelectSingleNode("/ParameterBindings/ParameterBinding[@Name = '" + key + "']");
if (node == null)
{
XmlNode parameterBindingNode = ParameterBindingsXmlDocument.CreateElement("ParameterBinding");

XmlAttribute nameAtrribute = ParameterBindingsXmlDocument.CreateAttribute("Name");
nameAtrribute.Value = key;
XmlAttribute locationAttribute = ParameterBindingsXmlDocument.CreateAttribute("Location");
locationAttribute.Value="None";
XmlAttribute defaultValueAttribute = ParameterBindingsXmlDocument.CreateAttribute("DefaultValue");
defaultValueAttribute.Value = value;

parameterBindingNode.Attributes.Append(nameAtrribute);
parameterBindingNode.Attributes.Append(locationAttribute);
parameterBindingNode.Attributes.Append(defaultValueAttribute);

ParameterBindingsXmlNode.AppendChild(parameterBindingNode);
}
else
{
node.Attributes["DefaultValue"].Value = value;
}
}

Here is the key method we are going to use. This is where we set our custom properties. Via using this you can set your binding parameters from anywhere you like (web.config property, sql data etc)

private void SetPropertiesAsParameterBindings()
{
SetParameterBinding("WebPartTitle", this.Title);
SetParameterBinding("WebPartTitleURL", this.TitleUrl);
this.ParameterBindings = ParameterBindingsXmlNode.InnerXml;
}

Last thing we should do is calling this method on OnLoad method of the webpart.

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
SetPropertiesAsParameterBindings();
}

Now it is time to replace DataFormWebPart with our EnhancedDataFormWebPart.

Add this line into your page and replace values with appropriate values from your solution.

Here the webpart comes :)

<ExWebParts:EnhancedDataFormWebPart id="TasksDisplayDataFormWebPart" runat="server"
FrameType="None" NoDefaultStyle="TRUE" ViewFlag="1" Title="Tasks"
DisplayName="Tasks" __markuptype="vsattributemarkup"
__WebPartId="{418745AA-67C6-481e-95F9-5C824AD0CE61}" WebPart="true">

<DataSources>

<SharePointWebControls:SPDataSource runat="server" DataSourceMode="List"
UseInternalName="true" selectcommand="<View/>" id="SPDataSource1"><SelectParameters><webpartpages:DataFormParameter Name="ListName" ParameterKey="ListName"
PropertyName="ParameterValues" DefaultValue="Tasks"/>

</SelectParameters>


</SharePointWebControls:SPDataSource>

</DataSources>

<ParameterBindings>
<ParameterBinding Name="ListName" Location="None" DefaultValue="Tasks" />
<ParameterBinding Name="dvt_apos" Location="Postback;Connection" />
<ParameterBinding Name="UserID" Location="CAMLVariable"
DefaultValue="CurrentUserName" />
<ParameterBinding Name="Today" Location="CAMLVariable" DefaultValue="CurrentDate" />
<ParameterBinding Name="WebPartTitle" Location="None" DefaultValue="{Title}" />
<ParameterBinding Name="WebPartTitleURL" Location="None" DefaultValue="{TitleUrl}" />
</ParameterBindings>

<datafields>@ID,ID;@ContentType,ContentType;@Title,Title;@Modified,Modified;@Created,Created;@Author,Author;@Editor,Editor;@_UIVersionString,_UIVersionString;@Attachments,Attachments;@LinkTitleNoMenu,LinkTitleNoMenu;@LinkTitle,LinkTitle;@FileRef,FileRef;@FileDirRef,FileDirRef;@FSObjType,FSObjType;@ProgId,ProgId;@ScopeId,ScopeId;@DocIcon,DocIcon;@MetaInfo,MetaInfo;@Priority,Priority;@Status,Status;@PercentComplete,PercentComplete;@AssignedTo,AssignedTo;@TaskGroup,TaskGroup;@Body,Body;@StartDate,StartDate;@DueDate,DueDate;</datafields>

<XslLink>/Style Library/XSL Style Sheets/test.xsl</XslLink>

</ExWebParts:EnhancedDataFormWebPart>



Last thing you need to do is adding following lines into Style Library/XSL Style Sheets as test.xsl file .



<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema"
xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0"
exclude-result-prefixes="xsl msxsl ddwrt"
xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
xmlns:asp="http://schemas.microsoft.com/ASPNET/20"
xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:SharePoint="Microsoft.SharePoint.WebControls"
xmlns:ddwrt2="urn:frontpage:internal">

<xsl:output method="html" indent="no"/> <xsl:decimal-format NaN=""/>

<xsl:param name="dvt_apos">'</xsl:param>

<xsl:param name="WebPartTitle">

</xsl:param>

<xsl:param name="WebPartTitleURL"></xsl:param> <xsl:variable
name="dvt_1_automode">0</xsl:variable>

<xsl:template match="/">
WebPartTitleURL:<xsl:value-of select="$WebPartTitleURL"></xsl:value-of>
WebPartTitle:<xsl:value-of select="$WebPartTitle"></xsl:value-of>
<xsl:call-template name="dvt_1"/> </xsl:template>

<xsl:template name="dvt_1">

<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/>

<xsl:if test="$dvt_1_automode = '1'" ddwrt:cf_ignore="1">

</xsl:if>

<xsl:call-template name="dvt_1.body">

<xsl:with-param name="Rows" select="$Rows"/>

</xsl:call-template>

</xsl:template>

<xsl:template name="dvt_1.body">

<xsl:param name="Rows"/>

<xsl:for-each select="$Rows">

<xsl:call-template name="dvt_1.rowview"/>

</xsl:for-each>

</xsl:template>

<xsl:template name="dvt_1.rowview"> Title: <xsl:value-of select="@Title"/><br/>

</xsl:template>

</xsl:stylesheet>

Wednesday, 24 June 2009

DataFormWebPart

One of the most important part in SharePoint is displaying the content without
braking any SharePoint features.

In this scenario DataFormWebPart is our guidance. There are always other ways to
display the content like custom webparts/webpartpages, but developing with these
methods may cost us lots of time.

In the following example we will learn how to develop a simple DataFormWebPart.


This is the syntax we will work on it.

<WebPartPages:DataFormWebPart id="TasksDisplayDataFormWebPart" runat="server"
FrameType="None" NoDefaultStyle="TRUE" ViewFlag="1" Title="Tasks"
DisplayName="Tasks" __markuptype="vsattributemarkup"
__WebPartId="{418745AA-67C6-481e-95F9-5C824AD0CE61}" WebPart="true">

<DataSources>

<SharePointWebControls:SPDataSource runat="server" DataSourceMode="List"
UseInternalName="true" selectcommand="<View/>" id="SPDataSource1">

<SelectParameters>

<webpartpages:DataFormParameter Name="ListName" ParameterKey="ListName"
PropertyName="ParameterValues" DefaultValue="Tasks"/>

</SelectParameters>


</SharePointWebControls:SPDataSource>

</DataSources>

<ParameterBindings>

<ParameterBinding Name="ListName" Location="None" DefaultValue="Tasks" />

<ParameterBinding Name="dvt_apos" Location="Postback;Connection" />

<ParameterBinding Name="UserID" Location="CAMLVariable"
DefaultValue="CurrentUserName" />

<ParameterBinding Name="Today" Location="CAMLVariable" DefaultValue="CurrentDate" />

<ParameterBinding Name="WebPartTitle" Location="None" DefaultValue="{Title}" />

<ParameterBinding Name="WebPartTitleURL" Location="None" DefaultValue="{TitleUrl}" />

</ParameterBindings>

<datafields>@Title,Title;@ID,ID</datafields>

<XslLink>/Style Library/XSL Style Sheets/SPTest/FullContent.xsl</XslLink>

</WebPartPages:DataFormWebPart >



Now let’s have a look at the properties;


a) DataSources: This defines where the data to get from We have some controls to
get the data, here is some of them;




i) SPDataSource: Gets the data from single or multiple (cross, we
will mention it in later blogs) SharePoint libraries content.


DataSourceMode:


• List: Retrieves
data from a list


• ListItem: Retrieves
data from a single list item


• CrossList:
Retrieves data from multiple lists in multiple websites in the same site
collection.


• ListOfLists:
Retrieves properties of lists in a specified web site.


• Web: Retrieves
properties of subsites of the current web site.


SelectCommand: This is where we define our
query to get data. CAML is the query syntax. Custom parameters such as
QueryString, existing variables, programmatically defined
parameterbindings can be used, but it will be shown on feature blogs.


SelectParameters: That is used to define to
pass parameter binding values and also other type of parameters.

ii) SPXmlDataSource:


<SharePoint:SPXmlDataSource runat="server">

<DataFileParameters>


<WebPartPages:DataFormParameter Name="FileName" ParameterKey="FileName"
PropertyName="ParameterValues" DefaultValue="items.xml"/>


<WebPartPages:DataFormParameter Name="FilePath" ParameterKey="FilePath"
PropertyName="ParameterValues" DefaultValue=""/>

</DataFileParameters>

</SharePoint:SPXmlDataSource>




b) ParameterBindings: To supply user defined or environment defined values to
the actual query.

c) DataFields: Fields those are used in xsl.

d) XSLLink: Xsl file to display content in a custom format.

Sample of the following code xsl;

<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema"
xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0"
exclude-result-prefixes="xsl msxsl ddwrt"
xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
xmlns:asp="http://schemas.microsoft.com/ASPNET/20"
xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:SharePoint="Microsoft.SharePoint.WebControls"
xmlns:ddwrt2="urn:frontpage:internal">

<xsl:output method="html" indent="no"/> <xsl:decimal-format NaN=""/>

<xsl:param name="dvt_apos">'</xsl:param>

<xsl:param name="WebPartTitle">

</xsl:param>

<xsl:param name="WebPartTitleURL"></xsl:param> <xsl:variable
name="dvt_1_automode">0</xsl:variable>

<xsl:template match="/">

<xsl:call-template name="dvt_1"/> </xsl:template>

<xsl:template name="dvt_1">

<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/>

<xsl:if test="$dvt_1_automode = '1'" ddwrt:cf_ignore="1">

</xsl:if>

<xsl:call-template name="dvt_1.body">

<xsl:with-param name="Rows" select="$Rows"/>

</xsl:call-template>

</xsl:template>

<xsl:template name="dvt_1.body">

<xsl:param name="Rows"/>

<xsl:for-each select="$Rows">

<xsl:call-template name="dvt_1.rowview"/>

</xsl:for-each>

</xsl:template>

<xsl:template name="dvt_1.rowview"> Title: <xsl:value-of select="@Title"/><br/>

</xsl:template>

</xsl:stylesheet>