SharePoint Create List Add/Edit Form Web Part With Custom Toolbar and Attachments Option

In this article, we explain how you can implement a custom web part for an add/edit form with custom toolbar and with attachments option that you find in SharePoint's toolbar. Though I've explained here a simple list example,with the reference of this walkthrough you can implement your complex custom web part.

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.

  1. First Name - Renamed the Title column of the list.

  2. Middle Name - Single line of text

  3. Last Name - Single line of text

  4. Full Name - Calculated column with formula " =CONCATENATE(TRIM(CONCATENATE([First Name]," ",[Middle Name]))," ",[Last Name])"

  5. Birth Date - Date and time

  6. Joining Date - Date and time

  7. 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.

  1. Walkthrough example solution (.zip)

  2. Referenced dll files (.zip)

How to deploy .wsp file

Follow the below steps to deploy the .wsp file.

  1. Open the command prompt and navigate for the following path "C:\Program Files\Common Files\Microsoft Shared\Web server extensions\12\bin"

  2. 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.

  3. Open SharePoint 3.0 Central Administration.

  4. Click on "Operations" link from the left navigation.

  5. Click "Solution management" in "Global Configuration" section.

  6. Click on your wsp file.

  7. Click "Deploy Solution".

  8. 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.

By Jatin Prajapati   Popularity  (9473 Views)
Picture
Biography - Jatin Prajapati
I think, most of the people are interested only in answers so no Biography provided... Want know more just write me at jatin.prajapati.er@gmail.com