How can i make attachments working in custom SharePoint listform?

If you use an application page as listform you’ll might notice that the button in the ribbon to attach files to the listitem does not work. It throws javascript errors like listform was customized… or something like id attachmentpart is missing or anything else. It might be that it displays nothing. So i thought – what a awesome story for 2014.

As i started my post serie about custom listforms i only thought about writing maybe 2 or 3 posts. This one will be my fifth post about custom listforms using visual studio and the application page way. Maybe i should make a post about the different ways to customize those forms.

But as short introduction let me give you the links to my previous posts:

Part 1: Setting up a solution with a list definition, a list instance and deploy it.

Part 2: Creating a custom list form and connect it with the list definition.

Part 3: Necessary settings for custom listform in Visual Studio

Part 4: Override Save Button in listform

Well, in order to make attachments working in your custom application page respective the listform page we’ll need to add certain parts with special id’s. Let’s see what parts we need.

Important notice: This has only relevance if you customizing also the fields. Means that you don’t use the webpartzone. To make it more clear: If you make the following part hidden or comment it out

<WebPartPages:WebPartZone runat=”server” FrameType=”None” ID=”Main” Title=”loc:Main” ><ZoneTemplate></ZoneTemplate> </WebPartPages:WebPartZone>

Then you have to manage that the attachments working. Let me show you how to do that.

Part 1:  We need part 1 including the idAttachmentRow



<span id="part1">
<table style="margin-top: 8px;" border="0" cellpadding="0" cellspacing="0" width="100%">
<!-- Normal Row -->
<tr>
<td width="190px" valign="top">
<h3>
<nobr><sharepoint:fieldlabel ID="Title" runat="server" FieldName="Title" ControlMode="New"></sharepoint:fieldlabel></nobr>
</h3>
</td>
<td width="400px" valign="top">
<sharepoint:formfield runat="server" id="fldTitle" ControlMode="New" FieldName="Title"></sharepoint:formfield>
<sharepoint:fielddescription runat="server" id="desc_Title" FieldName="Title" ControlMode="New"></sharepoint:fielddescription>
</td>
</tr>
<!--Attachment Row -->
<tr id="idAttachmentsRow">
<td nowrap="true" valign="top" width="20%">
<sharepoint:fieldlabel ID="FieldLabel1" ControlMode="New" FieldName="Attachments" runat="server"></sharepoint:fieldlabel>
</td>
<td valign="top" width="80%">
<sharepoint:formfield runat="server" id="AttachmentsField" ControlMode="New" FieldName="Attachments"></sharepoint:formfield>
<script type="text/javascript">
var elm = document.getElementById("idAttachmentsTable");
if (elm == null || elm.rows.length == 0)
document.getElementById("idAttachmentsRow").style.display='none';
</script>
</td>
</tr>
</table>


In this example you see the span with the id part 1. This part will be hidden if the user clicks on the “Add Attachment” Ribbon button. In this part we normally put also the row with the id “idAttachmentsRow” which displays the attached files.

Part 2: The Attachment Area.

It’s the area in which the user can search for his file and upload it. If he clicks there on OK or Cancel he will see the normal form again.Important part is here the span “partAttachment” which will be searched by the javascript.



<!-- Attachment AREA -->
<table style="width: 100%; padding-bottom: 10px;">
<tbody>
<tr>
<td id="Td1" colspan="2">
<div id="ctl00_PlaceHolderMain_AttachmentUploadPanel">
<input name="attachmentsToBeRemovedFromServer" type="hidden" />
<input name="RectGifUrl" type="hidden" value="/_layouts/15/images/rect.gif?rev=23" />
<span id="partAttachment" style="display: none;">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" style="padding-bottom: 8px;" colspan="4">
Use this page to add attachments to an item.
</td>
</tr>
<tr>
<td width="190" height="50" valign="top">Name  </td>
<td height="15" id="attachmentsOnClient" valign="bottom">
<span dir="ltr">
<input name="fileupload0" title="Name  " id="onetidIOFile" type="file" size="56" />
</span>
</td>
</tr>
<tr>
<td height="1" colspan="4">
<img width="1" height="1" alt="" src="/_layouts/15/images/blank.gif?rev=23" /></td>
</tr>
<tr>
<td height="10" colspan="4">
<img width="1" height="1" alt="" src="/_layouts/15/images/blank.gif?rev=23" /></td>
</tr>
<tr>
<td colspan="4">
<input id="attachOKbutton" onclick="OkAttach();" type="button" value="OK" />
<span id="idSpace"></span>
<input name="attachCancelButton" id="attachCancelButton" accesskey="C" onclick="CancelAttach()" type="button" value="Cancel" />
</td>
</tr>
</tbody>
</table>

</span>
</div>
</td>
</tr>
</tbody>
</table>


That are the most important parts. So at the end i’ll show you the whole aspx markup page.



<asp:content ID="Content1" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
<sharepoint:listformpagetitle ID="ListFormPageTitle1" runat="server"></sharepoint:listformpagetitle>
</asp:content>
<asp:content ID="Content2" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server">
<span>
<sharepoint:listproperty Property="LinkTitle" runat="server" ID="ID_LinkTitle"></sharepoint:listproperty>
</span>
</asp:content>
<asp:content ID="Content3" ContentPlaceHolderID="PlaceHolderPageImage" runat="server">
<img src="/_layouts/15/images/blank.gif?rev=23" width='1' height='1' alt="" />
</asp:content>

<asp:content ID="Content4" ContentPlaceHolderID="PlaceHolderMain" runat="server">
<sharepoint:uiversionedcontent ID="UIVersionedContent1" UIVersion="4" runat="server">
<contenttemplate>
<div style="padding-left:5px">
</div></contenttemplate>
</sharepoint:uiversionedcontent>

<table id="onetIDListForm">

<tr>
<td>
< %--<WebPartPages:WebPartZone runat="server" FrameType="None" ID="Main" Title="loc:Main" >
<zonetemplate></zonetemplate>
--%>
<table border="0">
<tr>
<td><sharepoint:formtoolbar ID="FormToolBar"  runat="server"  ></sharepoint:formtoolbar><sharepoint:formcomponent ID="formcmop" runat="server"></sharepoint:formcomponent></td>
</tr>
</table>
<!-- START -->
<span id="part1">
<table style="margin-top: 8px;" border="0" cellpadding="0" cellspacing="0" width="100%">
<!-- Normal Row -->
<tr>
<td width="190px" valign="top">
<h3>
<nobr><sharepoint:fieldlabel ID="Title" runat="server" FieldName="Title" ControlMode="New"></sharepoint:fieldlabel></nobr>
</h3>
</td>
<td width="400px" valign="top">
<sharepoint:formfield runat="server" id="fldTitle" ControlMode="New" FieldName="Title"></sharepoint:formfield>
<sharepoint:fielddescription runat="server" id="desc_Title" FieldName="Title" ControlMode="New"></sharepoint:fielddescription>
</td>
</tr>
<!--Attachment Row -->
<tr id="idAttachmentsRow">
<td nowrap="true" valign="top" width="20%">
<sharepoint:fieldlabel ID="FieldLabel1" ControlMode="New" FieldName="Attachments" runat="server"></sharepoint:fieldlabel>
</td>
<td valign="top" width="80%">
<sharepoint:formfield runat="server" id="AttachmentsField" ControlMode="New" FieldName="Attachments"></sharepoint:formfield>
<script type="text/javascript">
var elm = document.getElementById("idAttachmentsTable");
if (elm == null || elm.rows.length == 0)
document.getElementById("idAttachmentsRow").style.display='none';
</script>
</td>
</tr>
</table>
<!-- SAVE AND CANCEL BUTTON -->
<table>
<tr>
<td width="99%" nowrap="nowrap"><img SRC="/_layouts/15/images/blank.gif" width="1" height="18"/></td>
<td nowrap="nowrap">
<sharepoint:savebutton runat="server" ControlMode="New" id="savebutton2"></sharepoint:savebutton>
</td>
<td>&#160;</td>
<td nowrap="nowrap" align="right">
<sharepoint:gobackbutton runat="server" ControlMode="New" id="gobackbutton2"></sharepoint:gobackbutton>
</td>
</tr>
</table>
</span>
<!-- ENDE FORM -->

<!-- Attachment AREA -->
<table style="width: 100%; padding-bottom: 10px;">
<tbody>
<tr>
<td id="Td1" colspan="2">
<div id="ctl00_PlaceHolderMain_AttachmentUploadPanel">
<input name="attachmentsToBeRemovedFromServer" type="hidden" />
<input name="RectGifUrl" type="hidden" value="/_layouts/15/images/rect.gif?rev=23" />
<span id="partAttachment" style="display: none;">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" style="padding-bottom: 8px;" colspan="4">
Use this page to add attachments to an item.
</td>
</tr>
<tr>
<td width="190" height="50" valign="top">Name  </td>
<td height="15" id="attachmentsOnClient" valign="bottom">
<span dir="ltr">
<input name="fileupload0" title="Name  " id="onetidIOFile" type="file" size="56" />
</span>
</td>
</tr>
<tr>
<td height="1" colspan="4">
<img width="1" height="1" alt="" src="/_layouts/15/images/blank.gif?rev=23" /></td>
</tr>
<tr>
<td height="10" colspan="4">
<img width="1" height="1" alt="" src="/_layouts/15/images/blank.gif?rev=23" /></td>
</tr>
<tr>
<td colspan="4">
<input id="attachOKbutton" onclick="OkAttach();" type="button" value="OK" />
<span id="idSpace"></span>
<input name="attachCancelButton" id="attachCancelButton" accesskey="C" onclick="CancelAttach()" type="button" value="Cancel" />
</td>
</tr>
</tbody>
</table>

</span>
</div>
</td>
</tr>
</tbody>
</table>
<sharepoint:attachmentupload ID="AttachmentUpload1"  runat="server"  ControlMode="New" ></sharepoint:attachmentupload>
<sharepoint:itemhiddenversion ID="ItemHiddenVersion1"  runat="server"  ControlMode="New" ></sharepoint:itemhiddenversion>
</td>
</tr>
</table>

<sharepoint:uiversionedcontent ID="UIVersionedContent2" UIVersion="4" runat="server">
<contenttemplate>

</contenttemplate>
</sharepoint:uiversionedcontent>
</asp:content>
<asp:content ID="Content5" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server">
<sharepoint:delegatecontrol ID="DelegateControl1" runat="server" ControlId="FormCustomRedirectControl" AllowMultipleControls="true"></sharepoint:delegatecontrol>
<sharepoint:uiversionedcontent ID="UIVersionedContent3" UIVersion="4" runat="server">
<contenttemplate>
<sharepoint:cssregistration Name="forms.css" runat="server"></sharepoint:cssregistration>

</contenttemplate>
</sharepoint:uiversionedcontent>
</asp:content>
<asp:content ID="Content6" ContentPlaceHolderID="PlaceHolderTitleLeftBorder" runat="server">
<table cellpadding="0" height="100%" width="100%" cellspacing="0">
<tr>
<td>
<img src="/_layouts/15/images/blank.gif?rev=23" width='1' height='1' alt="" /></td>
</tr>
</table>
</asp:content>
<asp:content ID="Content7" ContentPlaceHolderID="PlaceHolderTitleAreaClass" runat="server">
<script type="text/javascript" id="onetidPageTitleAreaFrameScript">
if (document.getElementById("onetidPageTitleAreaFrame") != null) {
document.getElementById("onetidPageTitleAreaFrame").className = "ms-areaseparator";
}
</script>
</asp:content>
<asp:content ID="Content8" ContentPlaceHolderID="PlaceHolderBodyAreaClass" runat="server">
<sharepoint:styleblock ID="StyleBlock1" runat="server">
.ms-bodyareaframe {
padding: 8px;
border: none;
}
</sharepoint:styleblock>
</asp:content>
<asp:content ID="Content9" ContentPlaceHolderID="PlaceHolderBodyLeftBorder" runat="server">
<div class='ms-areaseparatorleft'>
<img src="/_layouts/15/images/blank.gif?rev=23" width='8' height='100%' alt="" />
</div>
</asp:content>
<asp:content ID="Content10" ContentPlaceHolderID="PlaceHolderTitleRightMargin" runat="server">
<div class='ms-areaseparatorright'>
<img src="/_layouts/15/images/blank.gif?rev=23" width='8' height='100%' alt="" />
</div>
</asp:content>
<asp:content ID="Content11" ContentPlaceHolderID="PlaceHolderBodyRightMargin" runat="server">
<div class='ms-areaseparatorright'>
<img src="/_layouts/15/images/blank.gif?rev=23" width='8' height='100%' alt="" />
</div>
</asp:content>
<asp:content ID="Content12" ContentPlaceHolderID="PlaceHolderTitleAreaSeparator" runat="server"></asp:content>


Hope it helps you.

..:: I LIKE SHAREPOINT ::..

The article or information provided here represents completely my own personal view & thought. It is recommended to test the content or scripts of the site in the lab, before making use in the production environment & use it completely at your own risk. The articles, scripts, suggestions or tricks published on the site are provided AS-IS with no warranties or guarantees and confers no rights.

Karsten Pohnke About Karsten Pohnke
He is Consultant for SharePoint Solutions for collaboration, communication and business processes. He provides his customers applications based on standard features as well as development or combining the power of several microsoft tools like Dynamics CRM. In his free time he tries to collect tipps and worthy experience in this blog.

4 comments on “How can i make attachments working in custom SharePoint listform?

  1. Hi Karsten

    I followed your example and managed to make attaching files work in my custom edit form. However, when I save the form, it display the following message:

    Sorry, there was a problem with File Attached Test (my app)
    The list item was saved, but one or more attachments could not be saved.
    Could not upload file c:\Users\Downloads\test\test.js.

    The file, however, was uploaded and stored in the list item correctly as I was able to retrieve it later.

    Any advise?

    Thank you.

  2. Hi Karsten

    I followed your example here and manage to make attaching file work in my custom edit form. However, when I saved the form with attachment, the following message was displayed:

    Sorry, there was a problem with
    The list item was saved, but one or more attachments could not be saved.
    Could not upload file c:\Users\test\test.js

    The files, however, appeared to be uploaded and stored correctly in the list item as I can retrieve it later.

    My environment is Sharepoint online 2013.

    Any advise?

    Thank you.

  3. Lucílio Oliveira

    Hi,

    Thank you for the post.

    I have exactly the same issue on my form as the previous person who commented the post.

    My form is a new form and is associated to a customed content type. If the form is associated directly to the list it works perfectly, no issue.

    Has anyone solved this?

    Thank you

  4. Asimina Papakonstantinou

    I had an savehandler in custom form and when I changed
    SaveButton.SaveItem(this.sbApprove.ItemContext, false, string.Empty) to SPContext.Current.ListItem.Update() the error dissapeared.

Submit comment

Allowed HTML tags: <a href="http://google.com">google</a> <strong>bold</strong> <em>emphasized</em> <code>code</code> <blockquote>
quote
</blockquote>

Please fill in the captcha: * Time limit is exhausted. Please reload CAPTCHA.