Thursday, June 24, 2010

Override SharePoint Save Button to Provide Custom Functionality

Let's assume a business scenario that we want to redirect the user to "DisplayForm.aspx" instead of "allItems.aspx" once the user clicks on the SharePoint "NewForm.aspx" save button or if we want to kickoff a Nintex custom workflow. This can as well with the help of the SharePoint Designer, but the client, I work for does not want to use SharePoint Designer. In the case we had to go for SharePoint object model coding.


To override the SharePoint Save button follow the below steps:



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

  • Override the "SaveButton" Class which is present in Microsoft.SharePoint.WebControls

  • Register this template in the SharePoint custom list definition schema

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


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"/>


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. Let's name the user control as "BtmuMTDFaxLogNewFormTemplate.ascx". Below is the code that should be present in the BtmuMTDFaxLogNewFormTemplate.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="MTDFaxLogSaveButton" Namespace="Btmu.MTDFaxLog"
Assembly="Btmu.MTDFaxLog, Version=1.0.0.0, Culture=neutral, PublicKeyToken=53432c81e5329871"%>


<sharepoint:renderingtemplate id="MTDFaxLogNewForm" 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"/> <MTDFaxLogSaveButton:FaxLogSaveButton 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>


<MTDFaxLogSaveButton:FaxLogSaveButton runat="server" />


<SharePoint:GoBackButton runat="server"/>


</Template_RightButtons>


</wssuc:ToolBar>


</td>


</tr>


</TABLE>


</SPAN>


<SharePoint:AttachmentUpload runat="server"/>


</Template>


</sharepoint:renderingtemplate>


If we observed the above highlited code we removed the actual SharePoint Sabe Button and replaced it with our own webcontrol which we have developed. Below shows the Save Button overriding code


Override the "SaveButton" Class which is present in Microsoft.SharePoint.WebControls:


using System;


using System.Collections.Generic;


using System.Linq;


using System.Text;


using Microsoft.SharePoint;


using Microsoft.SharePoint.WebControls;


namespace Btmu.MTDFaxLog


{
public class FaxLogSaveButton : SaveButton


{
protected override bool SaveItem()


{
bool success = base.SaveItem();
//Dont forget to remove the source querystring parameter from the NewForm.aspx URL, otherwise this setting will not work.


RedirectUrl = String.Concat(List.ParentWeb.ServerRelativeUrl, "/", List.Forms[PAGETYPE.PAGE_DISPLAYFORM].Url, @"?ID=", ListItem.ID, @"&Source=", ListItem.ParentList.DefaultViewUrl);
return success;


}


}


}


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


<XmlDocuments>


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


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


<New>MTDFaxLogNewForm</New>


</FormTemplates>


</XmlDocument>


</XmlDocuments>


So the final folder structure looks like this…






4 comments:

  1. Where are you take NewForm.aspx in MTD Fax Log Custom List. Are you may create simple project wich override save button, wich i may compile in my visual studio.

    ReplyDelete
  2. Where are you take NewForm.aspx in MTD Fax Log Custom List. Are you may create simple project wich override save button, wich i may compile in my visual studio.

    ReplyDelete
  3. I would like to ask you, how to remove the source querystring parameter from the NewForm.aspx URL in SharePoint 2010? The Source parameter is mandatory in order to load NewForm.aspx in modal dialog form.

    ReplyDelete
  4. If you copy the listform template from the defaulttemplates.ascx file you will need to modify the line:

    to

    .
    Otherwise your saveitem method will not execute.

    ReplyDelete