SPServices Stories #22 : SPServices SharePoint Attachments in Internet Explorer 9

This entry is part 21 of 21 in the series SPServices Stories

Introduction

This is another story I ran across on Twitter and wanted to add to the SPServices Stories series. I wrote about my own experience getting attachment uploading to work in my post Uploading Attachments to SharePoint Lists Using SPServices. My cheat in that case was to change the DOCTYPE to HTML5 in a SharePoint 2010 master page. It was a cheat in the sense that it broke a lot of basic SharePoint functioning. Luckily I could get away with it in that particular case.

In this story, Jason Williams (@JayWll) explains how he got uploading to work with the fileReader polyfill. As much as all of us would like to be working with the latest and greatest technologies, in reality most organizations – especially larger ones – don’t update their tech very often. In Jason’s case he needed the upload capability to work with IE9, which doesn’t have a lot of the HTML5 spec implemented in it.

I’ve combined two of Jason’s posts here, SPServices addAttachment jquery example and SPServices SharePoint Attachments in Internet Explorer 9. Jason built on a post from Brendon Wilbore (@bjwildbore) to get things up and running. This is one of the great things about the SharePoint community: there are many people out there who are generous enough to post their work so that we can build upon it.

SPServices SharePoint Attachments in Internet Explorer 9

Brendon Wilbore:

If you’re having a few issues adding attachments via ajax and SPServices on SharePoint have a look over the code snippets below.

To upload a file to a list you need to make use of the fileReader javascript class, using the readAsDataURL method and stripping the first part off the dataurl to get the base64 component. Then submit this to SPServices.

I’ve been asked a few times to add the ability to upload attachments to SharePoint tools that I’ve created, and I’ve never been able to achieve it until I eventually came across this blog post last week.

If (like me) you’re developing in a front-end only way without any server-side programming then it seems like this is the way to upload files and attach them to SharePoint list items.

It relies on the javascript fileReader feature so your users will need a fairly modern browser… which is where I ran into trouble. The default browser deployed within my company is Internet Explorer 9, and that doesn’t have fileReader support.

With much work and even more googling I was able to get this technique to work in Internet Explorer 9. In the future I’ll write more about how I managed it, and how you can too!


There was a problem, though – the solution relies on the fileReader JavaScript feature which requires Internet Explorer 10, and the default browser deployed within my organization is Internet Explorer 9. What we need is a fileReader alternative for older browsers. Thankfully, such a thing exists. Today I’m going to post some example code that uses the fileReader polyfill and works in older browsers.

What You Need

The code has several pre-requisites. You’ll need jQuery, jQuery UI, SPServices, SWFObject and the JavaScript and flash file that form the fileReader polyfill.

For the purposes of my demo I created a simple SharePoint list called “File Attachment Test.” The list has a single field – title – and attachments to the list are enabled. Your list is probably named differently, so you’ll need to change the references in the code to reflect your list name.

The Code

<html>
<head>
  <meta charset="utf-8" />
  <title>File Attachment Test</title>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
  <script type="text/javascript" src="js/jquery.FileReader.min.js"></script>
  <script type="text/javascript" src="js/jquery.SPServices-2013.01.min.js"></script>
  <script type="text/javascript">
    var selectedfile = false;

    $(document).ready(function() {
      $('input#itemfile').fileReader({filereader: 'js/filereader.swf'});

      $('input#itemfile').change(function(e) {
        selectedfile = e.target.files[0];

        $('span#filename').html(selectedfile.name);
        $('span#fileinput').hide();
      });

      $('input#createitem').click(function() {
        $().SPServices({
          operation: 'UpdateListItems',
          async: false,
          listName: 'File Attachment Test',
          batchCmd: 'New',
          webURL: '/demo',
          valuepairs: [
            ['Title', $('input#itemtitle').val()]
          ],
          completefunc: function(xData, Status) {
            if (Status == 'success' && $(xData.responseXML).find('ErrorCode').text() == '0x00000000') {
              currentitem = $(xData.responseXML).SPFilterNode("z:row").attr("ows_ID");
              alert('List item created with ID ' + currentitem);

              if (selectedfile) {
                filereader = new FileReader();
                filereader.filename = selectedfile.name;

                filereader.onload = function() {
                  data = filereader.result;
                  n = data.indexOf(';base64,') + 8;
                  data = data.substring(n);

                  $().SPServices({
                    operation: 'AddAttachment',
                    async: false,
                    listName: 'File Attachment Test',
                    listItemID: currentitem,
                    fileName: selectedfile.name,
                    attachment: data,
                    completefunc: function(xData, Status) {
                      alert('File uploaded');
                    }
                  });
                };

                filereader.onabort = function() {
                  alert('Upload aborted');
                };

                filereader.onerror = function() {
                  alert('Upload error');
                };

                filereader.readAsDataURL(selectedfile);
              }
            } else alert('List item creation failed');
          }
        })
      });
    });
  </script>
</head>
<body>
  <p>Title:<br><input type="text" id="itemtitle"></p>
  <p>File:<br><span id="fileinput"><input type="file" id="itemfile"></span><span id="filename"></span></p>
  <p><input type="button" id="createitem" value="Go!"></p>
</body>
</html>

Notes

The fileReader polyfill takes the file input box and puts the flash file on top of it, so that the file selection and upload is handled by flash instead of natively in the browser. I found that this fell apart if the file input box didn’t remain in the same place on the page. In other words, I had problems if I tried to use jQuery’s .show() and .hide() functions (or similar).

I solved this by putting the file selection form in a pop-up window. If the page you place your form on is static (i.e. nothing changes after the DOM is loaded) then you shouldn’t have this problem.

Enjoy!

Series Navigation<< SPServices Stories #20 – Modify User Profile Properties on SharePoint Online 2013 using SPServicesSPServices Stories #21 – Redirect If User Clicked a Button Previously >>

5 Comments

  1. No me funcionó, me marca el siguiente error:

    “No se puede obtener la propiedad ‘0’ de referencia nula o sin definir”

    En la linea: selectedfile = e.target.files[0];

    Reply

Have a thought or opinion?