venerdì 9 ottobre 2015

SharePoint List Item attachment: "old" browser compatibility

Hi everybody!
If you need to add an attachment to an existing list item in SharePoint, which solution would you consider?

Well, using REST API, make a POST call, getting the file content with a File Reader and passing the Blob as body.

Simple, isn't it?

Sure, but which browser are you using? I hope for you Chrome, Firefox and IE...10.
Because, if you need to make the solution compatible with IE9, you will feel much pain.
In fact, reading Marc Anderson's post:
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.
So, to make the solution working with the bloody IE9, I have used the following ingredients:
  • ngFileReader: angular component, compatible IE8+, that allow you to read the file content through the readAsDataURL method.
  • Stripping the first part of the file content off to get the base64 component.
    var BASE64_MARKER = ';base64,';
    var parts = dataURL.split(BASE64_MARKER);
    contentType = parts[0].split(':')[1];
    var data = parts[1];
  • Calling the $().Service passing the data retrieved above
    var deferred = $q.defer();
    jQuery().SPServices({
      operation: 'AddAttachment',
      async: true,
      listName: listId,
      listItemID: itemId,
      fileName: fileName,
      attachment: data,
      completefunc: function(xData, Status) {
        deferred.resolve(xData);
      }
    });
    return deferred.promise;
Otherwise, if you are using also a "modern" browsers, you can get rid of the previous implementation, creating the Blob from the file content

var BASE64_MARKER = ';base64,';
var parts = dataURL.split(BASE64_MARKER);
contentType = parts[0].split(':')[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;

var uInt8Array = new Uint8Array(rawLength);

for (var i = 0; i < rawLength; ++i) {
  uInt8Array[i] = raw.charCodeAt(i);
}

return new Blob([uInt8Array], {type: contentType});

and then setting this object (var file in the code snippet below) as data parameter to build the Ajax POST call to the SharePoint Web API endpoint.

var url = _spPageContextInfo.webServerRelativeUrl + "/_api/web/lists/GetById('" + listId + "')/items("+ itemId +")/AttachmentFiles/add(FileName='"+ fileName +"')"
      
var params = {
  method: "POST",
  url: url,
  data: file,
  headers: {
    "X-RequestDigest": jQuery("#__REQUESTDIGEST").val()
  }          
};

Thats all!

Nessun commento:

Posta un commento