Introduction
Many of us are some times face a problem with the default add / edit formthat is
provided in SharePoint. So, at that time we think to have our own pages with
custom implementations. Many of us have developed these pages and associated
them with a list. While doing this some times we miss the attachments functionality
provided by SharePoint for these forms. Here I'm going to explain how we can
achieve this by a simple walk throught. Please have a look at the below image
that shows the new developed web part for this functionality implemented.

Initial Requirements
To complete this walkthrough we need a simple list in SharePoint site. I've created
a list named "Employees" with the following fields.
-
First Name - Renamed the Title column of the list.
-
Middle Name - Single line of text
-
Last Name - Single line of text
-
Full Name - Calculated column with formula " =CONCATENATE(TRIM(CONCATENATE([First Name]," ",[Middle Name])),"
",[Last Name])"
-
Birth Date - Date and time
-
Joining Date - Date and time
-
Department - Single line of text
To develop this web part I've used WSPBuilder project type in Visual Studio 2008
and C# as programming language.
Assumptions
I assume that you are familier with Visual Studio 2008, C# and WSPBuilder.
Development of the web part
Create new project using WSPBuilder project template and provide it meaningful name.
Here I've use "ListAddEditFormWithAttachmentsCS".
Add new "Web Part Features" template and provide it meaningful name. I've
provided "ListAddEditFormWithAttachmentsWebPart".
In the solution explorer you will find couple of items such like folder structure
of 12/TEMPLATES/FEATURES/..., WebPartCode Folder, an snk file, etc.
I've added references of "SPAttachments", "TheToolBar" and "SPWebControlGenerator"
dlls which you can download from here. I'll explain each of these three dll methods
later in this walkthrought. These dlls are required to build the solution successfully.
(Original dll names are different, I've just written down the main namespaces
of the dlls.)
From solution explorer open the cs file from WebPartCode folder.
Clear the default content of the class provided by template.
Now add the following fields at the class level.
#region Fields
private SPWeb m_theWeb;
private SPList m_theList;
private SPListItem m_theItem;
private SPControlMode m_theMode = SPControlMode.New;
private int m_itemID = 0;
private SPWebControlsGenerator m_WebControlGenerator;
private SPAttachments m_attachments;
private TheToolBar m_theToolbar;
private Table m_theTable;
#endregion
Now create constructor for this web part and initialize the require fields which
are listed about. You can refer the below code or can write your own.
public ListAddEditFormWithAttachmentsWebPart()
{
m_theWeb = SPContext.Current.Web;
m_theList = SPContext.Current.List;
m_WebControlGenerator = new SPWebControlsGenerator();
m_attachments = new SPAttachments();
if (this.Context.Request.QueryString["ID"] != null)
{
m_itemID = int.Parse(this.Context.Request.QueryString["ID"]);
m_theItem = m_theList.GetItemById(m_itemID);
m_theMode = SPControlMode.Edit;
}
}
Here in this constructor code , I've assigned the m_theList to SPContext.Current.List.
Note that this will assign the current context list to our fields. You can also
use m_theList = m_theWeb.Lists["ListName"]. I'll tell you later in
this walkthrough why I've used context list instance.
Checking of query string object "ID" is useful to check whether the user
is creating new item or editing existing item. The field variable m_theMode is
set to SPControlMode.Edit if the user is editing. Default value for this is SPControlMode.New.
Now override the "CreateChildControls()" methos for the web part and place
the below code in that.
base.CreateChildControls();
this.tableCreateMainTable();
m_theToolbar = new TheToolBar(this.Page, m_theWeb.Url);
this.m_theTable.Rows.Add(m_theToolbar.trCreateToolbar(true));
this.createToolbarButtons(m_theToolbar);
this.m_theTable.Rows.Add(m_theToolbar.trCreateSpaceRowBetweenToolbarAndDataTable(TheToolBar.eToolbarSeperatorBorder.NoBorder));
this.m_theTable.Rows.Add(m_WebControlGenerator.trCreateDataRow(m_theList, m_theItem, m_theMode, Strings.fldlblFirstName));
this.m_theTable.Rows.Add(m_WebControlGenerator.trCreateDataRow(m_theList, m_theItem, m_theMode, Strings.fldlblMiddleName));
this.m_theTable.Rows.Add(m_WebControlGenerator.trCreateDataRow(m_theList, m_theItem, m_theMode, Strings.fldlblLastName));
this.m_theTable.Rows.Add(m_WebControlGenerator.trCreateDataRow(m_theList, m_theItem, m_theMode, Strings.fldlblBirthDate));
this.m_theTable.Rows.Add(m_WebControlGenerator.trCreateDataRow(m_theList, m_theItem, m_theMode, Strings.fldlblJoiningDate));
this.m_theTable.Rows.Add(m_WebControlGenerator.trCreateDataRow(m_theList, m_theItem, m_theMode, Strings.fldlblDepartment));
this.m_theTable.Rows.Add(this.m_attachments.trCreateAttachmentsRow(m_theWeb));
this.m_theTable.Rows.Add(m_theToolbar.trCreateSpaceRowBetweenToolbarAndDataTable(TheToolBar.eToolbarSeperatorBorder.Top));
m_theTable.Rows.Add(m_theToolbar.trCreateToolbar(true));
this.createToolbarButtons(m_theToolbar);
this.Controls.Add(this.m_attachments.tblCreateFileUploadTable());
Here in the above code first I've called base.CreateChildControls() methods to create
base class's controls if any. Then called the tableCreateMainTable() method (which
is as below) to create the main container table for our controls.
private void tableCreateMainTable()
{
m_theTable = new Table();
m_theTable.ID = "m_theTable";
m_theTable.Width = Unit.Percentage(100);
m_theTable.CellPadding = 0;
m_theTable.CellSpacing = 0;
this.Controls.Add(m_theTable);
}
Then created the toolbar instance and added that toolbar to the container table.
After that created the toolbar buttons using the below method.
private void createToolbarButtons(TheToolBar m_theToolbar)
{
m_theToolbar.vCreateToolbarButtons(new EventHandler(this.btnSave_Click), true, "Save", null, "/_layouts/images/SAVEITEM.GIF", true);
if (m_itemID != 0)
{
m_theToolbar.vCreateToolbarButtons(new EventHandler(this.btnDelete_Click), false, "Delete", "return confirm('Are you sure you want to delete this item?');",
"/_layouts/images/DELITEM.gif", true);
}
m_theToolbar.vCreateToolbarButtons(null, false, "Attach file", "return " + this.m_attachments.p_GetJavascriptFunctionWhichOpenAttachFileFormName + "()",
"/_layouts/images/ATTACHTB.GIF", true);
m_theToolbar.vCreateToolbarButtons(new EventHandler(this.btnCancel_Click), false, "Cancel", null, "/_layouts/images/CRIT_16.GIF", true);
}
Then added the datarows using the use of m_WebControlGenerator object.
After all the datarows are created again created the toolbar for the bottom side.
Then added the file upload controls container table using m_attachments object.
Now overwrite the Render method of the web part and write below line before base.Render(writer);
line.
writer.Write(this.m_attachments.sGetJavascriptsForAttachments(this.ClientID, this.m_theTable.ClientID));
The above line adds required javascript to function "Attach file" button
propertly. When "Attach file" button is clicked the main container
table will be hidden and attach file table will be displayed. This provides the
same functionality like "Attach file" functionlity of SharePoint.
The below methods are used to "Save", "Delete", "Cancel"
operations.
private void btnSave_Click(object sender, EventArgs e)
{
if (m_itemID == 0)
{
m_theItem = SPContext.Current.ListItem;
this.m_attachments.vAddOrDeleteAttachments(m_theItem);
m_theItem.Update();
}
else
{
this.m_attachments.vAddOrDeleteAttachments(m_theItem);
m_theItem.Update();
}
SPUtility.Redirect(m_theList.DefaultViewUrl, SPRedirectFlags.UseSource, this.Context);
}
private void btnDelete_Click(object sender, EventArgs e)
{
m_theItem.Delete();
SPUtility.Redirect(m_theList.DefaultViewUrl, SPRedirectFlags.UseSource, this.Context);
}
private void btnCancel_Click(object sender, EventArgs e)
{
SPUtility.Redirect(m_theList.DefaultViewUrl, SPRedirectFlags.UseSource, this.Context);
}
If you miss any methods then you can download the working example from here and refer
to that for the missing items.
Now right click on the project name in Solution Explorer and click "Build".
If build is successful then again right click on project name and point to"WSP
Builder" and click "Build WSP". After this build succeeds, again
right click the project name, point to WSP Builder and click "Deploy"
to deploy your solution to the SharePoint.
After successful deployment of your solution open your web site in browser. Go to
Site Settings. From "Site Collection Administration" section click
on "Site Collection features".
From there activate your web part feature. For my case its name is "List Add
Edit Form With Attachments WebPart".
Now, we need to modify the "NewForm.aspx" and "EditForm.aspx"
for our "Employees" list.
So, open the site in SharePoint Designer 2007.
From the folder list navigate to "Employees" list and expand that node.
Here I've not modified the default "NewForm.aspx" and "EditForm.aspx".
Rather I've created the copy of those pages and modified them, to avoid any mishappening
or can restore them back if unwanted behaviour is done.
For that, Right click on "NewForm.aspx" page and select "New From
Existing Page", this will create a copy of the page in the editor view.
Now save this page with proper name. I've provided "NewForm1.aspx".
Now remove the default ListFormWebPart and save the page again. Now select that web
part zone and from "Insert" menu point to "SharePoint Controls"
and click on "Web Part". This will open the "Web Parts" window.
From the list of web parts, select your developed web part and click "Insert
Selected Web Part" at the bottom of the window. This will add your web part
to the selected web part zone. Now save the page.
Now, we are setting this "NewForm1.aspx" as the default new page for this
list, so when user click on the "New" button on the list page, he will
be redirect to our new page by default.
In the SharePoint Designer, right click the "Employees" list, from "Folder
List" window and click "Properties".
This will show the "List Properties" dialog. Same as below.

Select "Supporting Files" tab. From there select "Item" for "Content
type specific forms:"
Click "Browse" button for "New item form:". This will open "Current
Web Site" dialog. In that dialog, navigate to the Employees list and select
"NewForm1.aspx" and click Ok button.
Click "Ok" button on "List Properties" dialog to save changes
and close the dialog.
You can follow above steps to create new copy of "EditForm.apx" and to
set is as default for the list.
Now opne you site in browser go to "Employees" list from left quick view.
Now click "New" button from the toolbar. You will be redirected to
your new created form i.e. NewForm1.aspx
Public Methods information of the referenced dlls
SPWebControlGenerator
-
Control GetSharePointControls(SPList theList, SPListItem theItem, SPControlMode theMode,
string sFieldName) - Returns the SharePoint Control based on the field type for the provided list.
-
Control GetSharePointControls(SPList theList, SPListItem theItem, SPControlMode theMode,
string sFieldName, int iWidth, int iHeight) - Overloaded version of the above method.
-
RequiredFieldValidator rfvValidator(string sFieldID) - Creates and returns required field validator control for the field.
-
TableCell tcCreateFieldTitle(string sFieldName, bool bValidatorExist) - Creates and returns the field title wrapped in TableCell object.
-
TableRow trCreateDataRow(SPList theList, SPListItem theItem, SPControlMode theMode,
string sFieldName) - Creates the data row for the provided field and returns TableRow instance containing
the controls. This method has few overloaded versions as below.
-
TableRow trCreateDataRow(SPList theList, SPListItem theItem, SPControlMode theMode,
string sFieldName, bool vRequired)
-
TableRow trCreateDataRow(SPList theList, SPListItem theItem, SPControlMode theMode,
string sFieldName, string sCssClass)
-
TableRow trCreateDataRow(SPList theList, SPListItem theItem, SPControlMode theMode,
string sFieldName, int iWidth, int iHeight)
-
TableRow trCreateDataRow(SPList theList, SPListItem theItem, SPControlMode theMode,
string sFieldName, string sDisplayName, string sCssClass)
-
TableRow trCreateEmptyDataRow(string sTitle, bool bRequired) - Creates and returns empty row only containing title.
TheToolBar
-
ToolBar tbarGetCurrentToolbar() - Returns the current instance of the toolbar object.
-
TableRow trCreateSpaceRowBetweenToolbarAndDataTable(eToolbarSeperatorBorder eToolbarPosition)
- Creates empty row for space between the toolbar and the other containg control.
-
TableRow trCreateToolbar(bool showMessage) - This method creates main toolbar row and returns the TableRow object containing
the toolbar.
-
void vCreateValidationMessage() - Creates validation message text and adds to the right side of the toolbar.
-
void vChangeToolbarButtonText(int iButtonNumber, string sButtonText) - Sets the particular button's text indexed at the number provided.
-
void vChangeToolbarMessage(string sMessage) - Changes the validation message text.
-
void vCreateToolbarButtons(EventHandler vEvent, bool bValidator, string sButtonText,
string sJSEvent, string sImageUrl, bool bToolbarButtonEnabled) - Creates the toolbar button and adds it to the toolbar.
-
void vCreateToolbarButtons(EventHandler vEvent, bool bValidator, string sButtonText,
string sJSEvent, string sImageUrl, string sCssClass) - Overloaded version of the above method.
SPAttachments
-
string sGetJavascriptsForAttachments(string sPageID, string sMainFormID) - Returns the javascript in the form of string to add to the page and to function attachment
propertly
-
Table tblCreateAttachmentsTable(int iFilesAlreadyAttached) - Creates the attachments table to display the attachments associated with the list
item.
-
TableRow trCreateAttachmentsRow(SPWeb TheWeb, string sCssClass) - Overloaded version of the above method.
-
void vAddOrDeleteAttachments(SPListItem lstitmTheItem) - This method is used when updating the list item and to save the attachmetns changes.
Following is the complete source code of the above example and referenced dlls. You
can use these dlls in your code.
-
Walkthrough example solution (.zip)
-
Referenced dll files (.zip)
How to deploy .wsp file
Follow the below steps to deploy the .wsp file.
-
Open the command prompt and navigate for the following path "C:\Program Files\Common Files\Microsoft Shared\Web server extensions\12\bin"
-
Execute the following command "stsadm -o addsolution -filename "<<Path to .wsp file>>". [Don't forget to replace the <<Path to .wsp file>> with original value.
-
Open SharePoint 3.0 Central Administration.
-
Click on "Operations" link from the left navigation.
-
Click "Solution management" in "Global Configuration" section.
-
Click on your wsp file.
-
Click "Deploy Solution".
-
On Deploy Solution page, select the required web site in the "Deploy To?" section or leave the field values as it is and click Ok button. This will deploy your solution to the selected web site or to all the web site based on your selection in "Deploy To?" section.
Conclution
So, this way we can develop custom web part with attchments functionality which is
similar to SharePoint's attachment functionlity.
Hope this will be helpful to you and you can develop complex web part as well by
the referance of this dlls and code.