SharePoint List Attachment Technical Brief

by michael greene on January 23rd, 2010

I recently found myself searching (to no avail) for information on how the SharePoint list attachment process actually works; it seemed as if there was no documentation or previous experiences available anywhere. In my particular scenario, I needed to be able to produce an auditable list which showed the date/time, filename, and username for every upload, a report which WSS doesn’t offer out of the box.

My solution became the creation of a second list, which would serve as this master record of all uploads. Once I understood how SharePoint actually processes the file attachments, I was able to use a combination of the PreSaveAction function and the jQuery Library for SharePoint Web Services to log each of the file names into my list.

This article isn’t meant to address the complete breadth of capability, but more to offer the technical ins and outs. I should point out that for the purposes of the article I’m making the assumption that you’re working on the default NewForm.aspx or EditForm.aspx forms. While I would imagine the document model and process is very similar for custom list forms, I have yet to dive into that world.

Where is the attachment form?
You may (or may not) be surprised to learn that the attach file form actually exists right inside your stock list form. The following graphic breaks out the overall form structure—more on the details in a minute. For the purpose of this article I’ve created a test list with 4 fields.

  1. All of the list fields and their submit buttons exist inside a span with an ID of “part1”.
  2. The “idAttachmentsTable” is populated dynamically to display the paths, names, and delete icon for each attachment.
  3. The file fields and related submit buttons exist inside a span with an ID of “partAttachment”. This is hidden by default so it is not viewed when the form is initially opened.
  4. The “attachmentsOnClient” table contains all of the file fields for the form. The contents of this table are always hidden to the user.

Clicking the “Attach File” link at the top of the form calls a JavaScript function that has two tasks. First and foremost it checks to make sure that the form structure (sections 1 and 3) exist. Assuming that check passes it then hides section 1, reveals section 3, and sets the focus to the active file field—creating an illusion to the end user of a new form loading.

What actually happens when I attach a file?
When you select a file for attachment and click OK, you’re not actually sending the files to the server yet. SharePoint keeps track of all of your changes to the list fields, attachment of files, deletion of files, etc., then waits until you save the overall list entry to transfer any new files to the server.

SharePoint manages a numerical variable called “FileUploadIndex” which it uses to keep track of how many attachments you have, and ultimately translates into the names of the file fields that you interact with to supply your attachments. The ID for each file field becomes “fileupload” concatenated with the current “FileUploadIndex” (ie: “fileupload0”). I’ll point out now that Microsoft is very inconsistent with field and variable lexicon here; sometimes they use “FileUpload” and other times it’s “Fileupload”, etc.

When you click the OK button to attach your file, SharePoint calls the “OKAttach” function that performs the following tasks:

  1. First it creates a new row in Section 2 containing the file path and the link to delete the file, should you wish to suddenly change your mind.
  2. Next it hides the file field you used to select your file, creating the illusion that it now sits inside Section 4.
  3. Thirdly it creates a new file field inside Section 3 incrementing 1 to the “FileUploadIndex”. So for example, if you had just uploaded your first file (fileupload0), this step would create a new file field inside Section 3 called fileupload1.
  4. Finally, it hides Section 3 in its entirety and displays Section 1, creating the illusion that the other form has now loaded again.

Should you now choose to click “Attach” again to add another file, you’ll actually be populating the new field (ie: “fileupload1”) created in step 3, and the process repeats. When the attach form is displayed for your next file, only the active field (essentially the one with the highest index) is displayed, while all

others are hidden inside Section 4.

So what does this get me?
Let’s say for example we wanted to check file extensions to prevent certain file types from being uploaded, or possibly make a web service call to see if documents with the same name have already been added to a document library or another list. In my particular use, I was making a web service call to log the names of the files in another list. Due to the fact that SharePoint names the file fields with a constant prefix, we can access those fields and run our own script or validation against them.

You can either use straight JavaScript or jQuery to access the file fields. In my particular case I had already loaded jQuery so it makes sense to utilize that method. The following example code loops though all fields that have a name starting with “fileupload”, outputting the full local path and filename.

<script type="text/javascript">
  function PreSaveAction() {
    $("input[name^='fileupload']").each(function() {
      if ($(this).val() != "") {
        alert($(this).val());
      }
    });
  }
</script>

You’ll notice that I’ve placed my alert inside an “if” statement that checks to make sure the value isn’t “nothing”. Remember that step 3 of the OKAttach call creates a new file field ready to accept the next file. As a result of this, there will always be a file field on the form that has no file in it. Obviously when you’re processing the files you don’t want to be bothered with blank rows, so a simple check to make sure the value isn’t blank, or the length of the string is greater than zero will suffice here.

If you wanted to record the file name to another list, like in my application, you can utilize the jQuery Library for SharePoint Web Services to call the UpdateListItems operation of the Lists web service and record $(this).val() into your list.

Conclusion
My particular scenario concluded with accessing the file names the user had selected, utilizing PreSaveAction to call the UpdateListItems web service and log the selected names to another list. That said, the true potential of understanding the process surrounding list attachment process is to couple it with the attachment deletion process. In my next article, we will explore how SharePoint tackles deleting files within the form and how to integrate the two processes to prevent people from uploading file types that you specify.

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS