Second Life of a Hungarian SharePoint Geek

March 12, 2014

How to check for Duplicated Attachments on SharePoint Forms

Filed under: Attachments, jQuery, SP 2010 — Tags: , , — Peter Holpar @ 23:27

Assume you have a SharePoint form with a lot of input fields as well as the option to append attachments to the list item. Assume one of your users accidentally tries to attach the same file twice (or two separate files with the same name) to the list item. When submitting the form, the following exception is displayed:

Failed to get value of the "Attachments" column from the "Attachments" field type control.  See details in log. Exception message: A file with the name already exists.

image

Note: the reason behind this error is that attachments in SharePoint are stored in individual folders by the item Id (for example, attachments of item with Id 34 of list YourList are stored in folder /lists/YourList/Attachments/34) and you cannot store multiple files within the same folder. This is different as the attachment handling with mails, where you can attach multiple files with the same name without any errors.

You can imagine the frustration of the user, as all of the data typed into the form was lost. Wouldn’t it be better not to allow the user to choose a file to attach if a file with the same name was already attached to the item? Definitely it would be far better, and it is quite simply to fulfill using jQuery.

To be able to perform the validation, first we have to understand, how the name of the attachments are store on the page. Assume a file called test1.txt is already attached to the item, and in this editing session we chose the file called test2.txt (from the path c:\temp) to be attached (as display below).

image

In this case, the HTML DOM of the page looks like this:

image

The key information: a table element with id idAttachmentsTable contains a tbody element, that has tr elements including td elements with class ms-vb. If the file is already attached to the item, then the file name is included in a child a element. If the file has been just uploaded, a span element includes the full path and the file name.

The next task is to find out how we can get the name of the file we would like to attach.

image

Analyzing the HTML of the page we can found an input element of type file under the td element with id attachmentsOnClient:

image

So first I tried to use the value of the onetidIOFile input field, but it turned out that the value of this field does not change as we attach further files to the item.

Assuming we upload the files file1.docx, file2.xlsx and file3.png in this sequence, the value of the $("#attachmentsOnClient").html() expression changes as described below:

Step 1. attaching file1.docx:
<SPAN dir=ltr><INPUT name=fileupload0 title="Name  " class=ms-fileinput id=onetidIOFile type=file size=56 value=C:\directory\file1.docx></INPUT> </SPAN>

Step 2. attaching file2.xlsx:
<SPAN dir=ltr><INPUT name=fileupload0 title="Name  " class=ms-fileinput id=onetidIOFile style="DISPLAY: none" type=file size=56 value=C:\directory\file1.docx></INPUT> </SPAN><INPUT name=fileupload1 tabIndex=1 title=Name class=ms-longfileinput id=fileupload1 type=file size=56 value=C:\directory\file2.xlsx>

Step 3. attaching file3.png:
<SPAN dir=ltr><INPUT name=fileupload0 title="Name  " class=ms-fileinput id=onetidIOFile style="DISPLAY: none" type=file size=56 value=C:\directory\file1.docx></INPUT> </SPAN><INPUT name=fileupload1 class=ms-longfileinput style="DISPLAY: none" type=file value=C:\directory\file2.xlsx><INPUT name=fileupload2 tabIndex=1 title=Name class=ms-longfileinput id=fileupload2 type=file size=56 value=C:\directory\file3.png>

We can see, that former input fields of type file got hidden via style="DISPLAY: none", and new file input elements are appended to the existing ones, That means, we can get the path of the actually attached file from the last file input element.

Last action is to replace the default event handler method (OkAttach) on the OK button. In the new event handler we get the name of the file being actually appended and compare it with the file names of other attachments (attached either in this editing session or already saved to the item). If we find a file with the same name, then a warning is displayed. If there is no conflicting attachment, then we call the default event handler that registers the file to be uploaded as attachment.

  1. $(document).ready(attachEventHandlers);
  2.  
  3. function attachEventHandlers() {
  4.   // override the default event handler with our custom method
  5.   $('#attachOKbutton').attr("onclick", "onAttachOKbuttonClicked()");
  6. }
  7.  
  8. function onAttachOKbuttonClicked() {
  9.   // get the name of the file last attached to the item
  10.   var newFilePath = $('#attachmentsOnClient').find('input').last().val();
  11.   // get the file name from the file path as described at
  12.   // http://stackoverflow.com/questions/423376/how-to-get-the-file-name-from-a-full-path-using-javascript
  13.   // TrimWhiteSpaces is a js method of SharePoint to filter out special characters from the file name
  14.   var newFileName = TrimWhiteSpaces(newFilePath).replace(/^.*[\\\/]/, '');
  15.  
  16.   var foundDuplication = false;
  17.  
  18.   $('#idAttachmentsTable').find('tbody').find('tr').each(function () {
  19.     var existingFileName = $(this).find('.ms-vb').find('a').text();
  20.     // if the existingFileName is empty then the attachment was uploaded in this session
  21.     // that is, it is not saved yet
  22.     if (existingFileName == '') {
  23.       var existingFilePath = $(this).find('.ms-vb').find('span').text();
  24.       existingFileName = existingFilePath.replace(/^.*[\\\/]/, '');
  25.     }
  26.  
  27.     if (newFileName == existingFileName) {
  28.       foundDuplication = true;
  29.       return false;
  30.     }
  31.   });
  32.  
  33.   if (foundDuplication) {
  34.       alert("A file with name '" + newFileName + "' is already attached to this item.");
  35.   }
  36.   else {
  37.     // call the OkAttach js method of SharePoint
  38.     // this is the method that is originally called by uploading attachments
  39.     OkAttach();
  40.   }
  41. }

Hopefully you can apply this method to make the user experience better (or at least less frustrating) when working with attachments.

5 Comments »

  1. hi,
    the idea is good but the event handlers r not getting overridden

    Comment by Kajal — May 27, 2014 @ 06:00

  2. Thankyou so much…
    It worked for me

    Comment by peny — July 10, 2014 @ 10:47

  3. You are a genius! Thanks so much for posting the code.

    Comment by James Roberts — March 9, 2015 @ 13:30

  4. how can I add this in C#?

    Comment by raym0109 — March 20, 2015 @ 07:45

    • works awesome in my code now! thanks for this

      Comment by raym0109 — March 25, 2015 @ 03:12


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: