Thursday, June 24, 2010

Object model code for SharePoint List forms

If we ever need to customize SharePoint list forms which a different look and feel then, this can be done with SharePoint designer. But if we have a custom functionality requires us to write SharePoint object model code? Yes, writing SharePoint object model code for List forms is possible in SharePoint. Let's look into it.


All the SharePoint list forms (NewForm.aspx, EditForm.aspx, DisplayForm.aspx) uses rendering template called "ListForm" which is present in the file "DefaultTemplates.ascx" in the following path.


C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\CONTROLTEMPLATES\DefaultTemplates.ascx


This is the code which I am referring to


<SharePoint:RenderingTemplate ID="ListForm" runat="server">


<Template>


<SPAN id='part1'>


<SharePoint:InformationBar runat="server"/>


<wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTbltop" RightButtonSeparator="&nbsp;"
runat
="server">


<Template_RightButtons>


<SharePoint:NextPageButton runat="server"/>


<SharePoint:SaveButton runat="server"/>


<SharePoint:GoBackButton runat="server"/>


</Template_RightButtons>


</wssuc:ToolBar>


<SharePoint:FormToolBar runat="server"/>


<TABLE class="ms-formtable" style="margin-top: 8px;" border=0 cellpadding=0 cellspacing=0 width=100%>


<SharePoint:ChangeContentType runat="server"/>


<SharePoint:FolderFormFields runat="server"/>


<SharePoint:ListFieldIterator runat="server"/>


<SharePoint:ApprovalStatus runat="server"/>


<SharePoint:FormComponent TemplateName="AttachmentRows" runat="server"/>


</TABLE>


<table cellpadding=0 cellspacing=0 width=100%>


<tr>


<td class="ms-formline"><IMG SRC="/_layouts/images/blank.gif" width=1 height=1
alt="">


</td>


</tr>


</table>


<TABLE cellpadding=0 cellspacing=0 width=100% style="padding-top: 7px">


<tr>


<td width=100%>


<SharePoint:ItemHiddenVersion runat="server"/>


<SharePoint:ParentInformationField runat="server"/>


<SharePoint:InitContentType runat="server"/>


<wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTbl" RightButtonSeparator="&nbsp;"
runat
="server">


<Template_Buttons>


<SharePoint:CreatedModifiedInfo runat="server"/>


</Template_Buttons>


<Template_RightButtons>


<SharePoint:SaveButton runat="server"/>


<SharePoint:GoBackButton runat="server"/>


</Template_RightButtons>


</wssuc:ToolBar>


</td>


</tr>


</TABLE>


</SPAN>


<SharePoint:AttachmentUpload runat="server"/>


</Template>


</SharePoint:RenderingTemplate>


If we look more closely into the above code we see the outline structure of the list form which includes Toolbar, Save Button, Cancel Button Attachments etc.. So how are the actual list data columns being generated? They get generated on the fly based in the columns in the list by one more rendering template called "ListFieldIterator" with this code of line


<SharePoint:ListFieldIterator runat="server"/>


Now let's assume that you want to completely customize the list form with custom functionality. To do that we have to follow the below steps



  • Create new rendering template and please it in the ControlTemplates folder

  • Design a usercontrol as per the requirement and write object model code to achieve the required operation

  • Register this template in the SharePoint custom list definition schema

Create new rendering template and please it in the ControlTemplates folder:


Since we should not modify the out of box template we should create a new rendering template an user control (.ascx) file and place it in the control templates folder. Lets name the user control as "CaymanTicketsNewForm.ascx". Below is the code that should be present in the CaymanTicketsNewForm.ascx user control.


<%@ Control Language="C#" AutoEventWireup="false" %>


<%@ Assembly
Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
%>


<%@ Register TagPrefix="SharePoint" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" Namespace="Microsoft.SharePoint.WebControls"
%>


<%@ Register TagPrefix="SPHttpUtility" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
Namespace="Microsoft.SharePoint.Utilities" %>


<%@ Register TagPrefix="wssuc" TagName="ToolBar" Src="~/_controltemplates/ToolBar.ascx"


%>


<%@ Register TagPrefix="wssuc" TagName="ToolBarButton" Src="~/_controltemplates/ToolBarButton.ascx" %>


<%@ Register TagPrefix="CaymanTicketsNewForm" TagName="CaymanTicketsNewFormFields"
Src="~/_controltemplates/Cayman/CaymanTicketsNewForm.ascx"
%>


<sharepoint:renderingtemplate id="CaymanTicketsNewForm" runat="server">


<Template>


<CaymanTicketsNewForm:CaymanTicketsNewFormFields runat="server"/>


</Template>


</sharepoint:renderingtemplate>


Design a usercontrol as per the requirement and write object model code to achieve the required operation:


The above code references a file called "CaymanTicketsNewForm.ascx" which contains the actual design and implementation of the custom list form requirement.Shown below is the code sample which is present in the file "CaymanTicketsNewForm.ascx"


<%@ Control Language="C#" Inherits="Btmu.Cayman.TicketsNewForm,Btmu.Cayman,Version=1.0.0.0, Culture=neutral, PublicKeyToken=cc3c6db4e0e41def" AutoEventWireup="true" EnableViewState="true" %>


<%@ Assembly
Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
%>


<%@ Register TagPrefix="SharePoint" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
Namespace="Microsoft.SharePoint.WebControls" %>


<style type="text/css">


.ms-input


{


width: 100px;


}


.tableStyle1


{


background-color: #FFF2E6;


border:solid 1px #CD5C5E;


}


.tableStyle2


{


background-color: #F2FFF2;


border:solid 1px #008080;


}


</style>


<asp:Panel ID="panelCustomerSelection" runat="server">
<div style="padding-left: 10px;">
<sharepoint:scriptlink id="ScriptLink1" language="javascript" name="Cayman/Cayman.js" runat="server" />
<table border="0" cellpadding="0" cellspacing="0" style="width: 100%;">
<tr>
<td style="font-size: 14px; font-weight: bold">
<asp:Label ID="labelTransactionMessage" Text="" runat="server" ForeColor="Red"
Visible="false"></asp:Label
>
</td>
</tr>
<tr>
<td style="font-size: 14px; font-weight: bold; padding-top: 20px;">
<asp:Label ID="labelTransactionDate" Text="" runat="server" Visible="false"></asp:Label>
</td>
</tr>
<tr>
<td style="font-size: 14px; font-weight: bold; padding-top: 30px;">
<asp:Label ID="labelNextTransaction" Text="Next Transaction:" runat="server"


Font-Underline="true" Visible="false"></asp:Label>
</td>
</tr>
<tr>
<td style="font-size: 14px; font-weight: bold; padding-top: 20px;">


Select Customer for the form
</td>
</tr>
<tr>
<td style="padding-top: 10px; font-size: 14px; font-weight: bold">
<asp:Label ID="labelPrintDate" Text="" runat="server"></asp:Label>
<div style='width: 100%; border-top-color: Gray; border-top-width: 2px; border-top-style: double;


height: 1px; margin-top: 7px'>
</div>
</td>
</tr>
<tr>
<td style="padding-top: 20px; font-size: 11px; font-weight: bold">


Customer Name<br />
<asp:DropDownList ID="dropDownListCustomerName" runat="server" AutoPostBack="false"
ToolTip="Customer Name">
</asp:DropDownList>
</td>
</tr>
<tr>
<td style="padding-top: 20px">
<asp:Button ID="buttonProcess" runat="server" Text="Process" OnClientClick="return processValidate()" />
</td>
</tr>
</table>
</div>


</asp:Panel>


<script type="text/javascript">


_spBodyOnLoadFunctionNames.push("fillDefaultValuesForTickets");


</script>


And the Code file…


using System;


using System.Collections.Generic;


using System.Text;


using System.Web;


using System.Web.UI;


using System.Web.UI.WebControls;


using System.Web.UI.HtmlControls;


using System.Data;


using Microsoft.SharePoint;


using Microsoft.SharePoint.Utilities;


using Microsoft.SharePoint.WebControls;


using Microsoft.Office.Server.Diagnostics;


namespace Btmu.Cayman


{
public class TicketsNewForm : UserControl


{


#region Variable Decleration
//Variables declaration which includes control names in the .ascx page template
protected Label labelPrintDate;
protected Label labelTransactionMessage;
protected Label labelTransactionDate;
protected Label labelNextTransaction;
protected DropDownList dropDownListCustomerName;
protected Button buttonProcess;
protected Panel panelCustomerSelection;
private Utility _oUtility;


#endregion


#region Constants
const string customersListURL = "/Lists/Customers";
const string portfolioListURL = "/Lists/Portfolio";
const string typeListURL = "/Lists/Type";
const string currencyListURL = "/Lists/Currency";
const string ticketsListURL = "/Lists/Tickets";
const string transactionNumberColumnName = "TransactionNumber";


#endregion
/// </summary>
/// <param name="e"></param>
protected override void OnLoad(EventArgs e)


{
try


{
if (!Page.IsPostBack)


{


labelPrintDate.Text = "Print Date: "+DateTime.Today.ToShortDateString();


createUtilityObject();
//Load Customer Names
DataTable dtCustomerNames = null;
string query = "<Where><Eq><FieldRef Name='ActiveProfile' /><Value Type='Choice'>Active</Value></Eq></Where><OrderBy><FieldRef Name='Title' Ascending='True' /></OrderBy>";
string viewFields = "ID,Title";
using (SPWeb web = SPControl.GetContextSite(Context).OpenWeb())


{


dtCustomerNames = _oUtility.getListItemsDataTable(web, customersListURL, query, 0, viewFields);


}
if (dtCustomerNames != null && dtCustomerNames.DefaultView.Count > 0)


{


dropDownListCustomerName.DataValueField = "ID";


dropDownListCustomerName.DataTextField = "Title";


dropDownListCustomerName.DataSource = dtCustomerNames;


dropDownListCustomerName.DataBind();


dropDownListCustomerName.Items.Insert(0, new
ListItem("-Select-", "0"));


}


panelTicketsForm.Visible = false;


}


}
catch (System.Exception ex)


{
PortalLog.LogString(ex.StackTrace);
throw new SPException(ex.Message);


}


}


#region Event Handlers
/// <summary>
/// lists all the eventhandlesr
/// </summary>
/// <param name="e"></param>
protected override void OnInit(EventArgs e)


{


buttonProcess.Click += new EventHandler(buttonProcess_Click);


}
protected void buttonProcess_Click(object sender, EventArgs e)


{
try


{


}
catch (System.Exception ex)


{
PortalLog.LogString(ex.StackTrace);
throw new SPException(ex.Message);


}


}


#endregion


#region Methods
private void createUtilityObject()


{
if (_oUtility == null)


{


_oUtility = new Utility();


}


}


#endregion


}


}


Register this template in the SharePoint custom list definition schema:


Now once we complete our development we need to register this custom rendering template which we have developed in our custom list definition as follows


</FieldRefs>


<XmlDocuments>


<XmlDocument
NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms"
>


<FormTemplates xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms"&gt;


<Display>CaymanTicketsDisplayForm</Display>
<Edit>CaymanTicketsEditForm</Edit>


<New>CaymanTicketsNewForm</New>


</FormTemplates>


</XmlDocument>


</XmlDocuments>


</ContentType>


So the final folder structure looks like this…




1 comment:

  1. this is fine...........but i have query
    actually i need to get the size of list attachment file through javascript and if you could help me and if you can provide a javascript code for the same iwould be very thankful to you.

    Gaurav

    ReplyDelete