Showing posts with label list item attachments. Show all posts
Showing posts with label list item attachments. Show all posts

Tuesday, August 7, 2012

Track SharePoint Attachments Uploaded and Deleted in the EditForm using JavaScript

To track the changes to attachments in a SharePoint item for auditing/record keeping purposes:

1. Create a new SharePoint edit form for the list using SharePoint Designer
2. Make sure that your Edit Form is updated and can upload attachments (use this MSDN article if you are having issues http://support.microsoft.com/kb/953271/en-us)

3. **Updated step**

Find <tr id="idAttachmentsRow" > and directly underneath of that closing </tr> add the following:


<tr style="display:none">
      <td colspan="2" valign="top" class="ms-formbody" nowrap="" height="20px">
       <H3 class="ms-standardheader">
              <SharePoint:AttachmentsField ControlMode="Display" FieldName="Attachments" runat="server" Visible="true"/>
       </H3>
      </td>
     </tr>
(By adding this row and this field, it will retain the name of the attachment)
    
4. To get the newly added attachments, you will want to grab the "attachmentsOnClient" element. This is where the references to the newly added attachments are stored. Next, you will want to iterate through all the INPUT tags and get the "value" attribute to get the names of the files that were uploaded.

5. To get the removed attachments from the SharePoint list item, we will grab the "attachmentsToBeRemovedFromServer" element. All of the GUIDs of the list item attachments to be removed are stored in this element. We will parse out each guid and use it to identify the attachmentRow found under the attachmentsTable. This row will have a reference to the removed items.

6. To view the changes that have been made when a user clicks to save the form, add the script below. Of course, instead of alerting the user of the changes made, you can record it in a status or audit trail field to make it more seamless!


 
<script type="text/javascript">

function GetNewlyUploadedAttachments()
{
 var uploadedAttachments = new Array();
 var oAttachments = document.getElementById("attachmentsOnClient");
 if( oAttachments.innerHTML != null )
 {
  var attachmentTable = oAttachments.getElementsByTagName("INPUT");
  for (var i = 0; i < attachmentTable.length; i++) 
  {    
   var value = attachmentTable[i].getAttribute("value");    
   if ( value != null && value.length > 0 ) 
   {   
    var lastIndex = value.lastIndexOf("\\");
    var fileName = value.substring(lastIndex+1);
    uploadedAttachments.push(fileName); 
   } 
  } 
 }

 return uploadedAttachments.toString();
}

function GetRemovedAttachments()
{
 var removedAttachments = new Array();
 var attachmentsToBeRemoved = document.getElementsByName("attachmentsToBeRemovedFromServer").item(0).value;

 if( attachmentsToBeRemoved != null && attachmentsToBeRemoved != "")
 {
  var array = attachmentsToBeRemoved.split(';');
  for(var i =0; i < array.length; i++ )
  {
   attachmentGuid = array[i];
   if( attachmentGuid != null && attachmentGuid != "" )
   {
    var attachmentRow =  document.getElementById(attachmentGuid);
    var span = attachmentRow.getElementsByTagName('span')[0];
    var links = span.getElementsByTagName("a");
    for (z = 0; z < links.length; z++) 
    {
     removedAttachments.push(links[z].firstChild.nodeValue);
    }
   }
  }
 }
 return removedAttachments.toString();
}

function PreSaveAction()
{
 var newUploadedAttachments = GetNewlyUploadedAttachments();
 var removedAttachments = GetRemovedAttachments();
 if( removedAttachments != null && removedAttachments != "" )
 {
  alert("User removed attachments: " + removedAttachments );
 }
 if( newUploadedAttachments != null && newUploadedAttachments != "" )
 {
  alert("User uploaded attachments: " + newUploadedAttachments );
 }
}
</script>



Monday, July 9, 2012

Display SharePoint List Item Attachments as Images

Suppose you want a visual display of the images that you attach to a SharePoint list. Clicking on each attachment to open it can be a hassle instead of just having it automatically display the images on load.


By default, the attachments are listed as links:




If you view the properties of a SharePoint list item, you will see that the link to each attachment is calculated by: 

[Site Url]/Attachments/[Item ID]/[Attachment Name]

So, if we can grab the item id of the list item, and then determine the attachment names, we will be able to use those properties to display the image with an img tag.

First thing's first. If you view the source of that default SharePoint item view page, you will see that the attachments are store din the element: idAttachmentsTable. We want to grab all of the attachment names in that element. To do so, we will iterate through the span elements and parse out the attachments:  


 

<script type="text/javascript">
spanTag = document.getElementById("idAttachmentsTable").getElementsByTagName("span");
var attachmentArray = new Array();
for (var i = 0; i < spanTag.length; i++) 
{
  filename = spanTag[i].innerHTML;
  var index  = filename.indexOf('>')+1;
  var lastindex = filename.lastIndexOf('<');

  var name = filename.substring(index, lastindex);

  name = name.replace(/ /g, '%20');
  name = name.replace(/'/g, '%27');

  for( var x = 0; x < imgExtensions.length; x++ )
  {
   if( name.indexOf(imgExtensions[x]) >=0 )
   {
    attachmentArray.push([name]);
    break;
   }
  }
}
</script>

Now that we have the names of the attachments, we want to grab the current item id of our list item, which we can simply grab from the source url.

Call to get the item ID:

var paramID = getParameterByName("ID");

Function to grab the parameter from the source url:
function getParameterByName(name) 
{   
 name = name.replace(/[\[]/, "
\\\[").replace(/[\]]/, "\\\]");  
 var regexS = "[\\?&]" + name + "=([^&#]*)"; 
 var regex = new RegExp(regexS);  
 var results = regex.exec(window.location.href); 
 if(results == null) 
  return "";
 else   
  return decodeURIComponent(results[1].replace(/\+/g, " "));
}

Now, we will use the paramID and the attachment names to create our img tags and append it to the Attachments element:

var ctrl = document.getElementById("idAttachmentsTable");
 var attachmentString = "";
 for( i = 0; i < attachmentArray.length; i++)
 {
  attachmentString += 
  " <img src='" + listAttachmentUrl + paramID + "/"+ attachmentArray[i] + "' width='400px' border='2'>";
 }
 ctrl.parentNode.innerHTML += attachmentString;


After adding our script:





To use this script, you will need to use SharePoint designer to edit the "View" page of the list. Navigate to the end of the PlaceHolderMain content placeholder, and right before the closing "</asp:Content>" tag, place the script below in it's entirety. Make sure to modify the listAttachmentUrl to reflect your site and list names:

<script language="javascript" type="text/javascript"> 
var listAttachmentUrl = '/mysite/Lists/mylist/Attachments/';
var imgExtensions = new Array(".jpg",".jpeg", ".png", ".bmp", ".tif", ".tiff");
LoadAllAttachments();

function LoadAllAttachments()
{
 spanTag = document.getElementById("idAttachmentsTable").getElementsByTagName("span");
 var attachmentArray = new Array();
 for (var i = 0; i < spanTag.length; i++) 
 {
  filename = spanTag[i].innerHTML;
  var index  = filename.indexOf('>')+1;
  var lastindex = filename.lastIndexOf('<');

  var name = filename.substring(index, lastindex);

  name = name.replace(/ /g, '%20');
  name = name.replace(/'/g, '%27');
  for( var x = 0; x < imgExtensions.length; x++ )
  {
   if( name.indexOf(imgExtensions[x]) >=0 )
   {
    attachmentArray.push([name]);
    break;
   }
  }
 }

 var paramID = getParameterByName("ID");
 var ctrl = document.getElementById("idAttachmentsTable");
 var attachmentString = "";
 for( i = 0; i < attachmentArray.length; i++)
 {
  attachmentString += 
  " <img src='" + listAttachmentUrl + paramID + "/"+ attachmentArray[i] + "' width='400px' border='2'>";
 }
 ctrl.parentNode.innerHTML += attachmentString;
}

function getParameterByName(name) 
{   
 name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");   
 var regexS = "[\\?&]" + name + "=([^&#]*)";  
 var regex = new RegExp(regexS);   
 var results = regex.exec(window.location.href);  
 if(results == null)  
  return ""; 
 else    
  return decodeURIComponent(results[1].replace(/\+/g, " "));} 
</script>