Using the Signature Pad jQuery Plugin with SharePoint & InfoPath – Redux

I’m using Thomas Bradley’s Signature Pad plugin for a project, which I’ve used successfully before. The twist this time is that I want to save the signature as an image rather than just as JSON.

There’s a method called getSignatureImage()  that works just fine to grab the signature as a base64 string, like so (this is the result for an empty canvas):

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAArwAAACWCAYAAAA8Els6AAAIjElEQ…QIECBg8LoBAgQIECBAgACBtIDBm65XOAIECBAgQIAAgQtmc1xdE+aNPAAAAABJRU5ErkJggg==

(Note the “…”; it’s a much longer string.)

Snazzy signatureI was having a problem saving the signature to a library successfully. Uploading the file was easy, but the image file was always ending up corrupted. It didn’t matter if I uploaded to a Document library or Picture Library; no joy.

I knew I was missing something obvious. I tried removing the leading “data:image/png;base64,”. I tried different values for Content-Type, etc. It had to be something about the way I was creating the file.

In the end, I got some great advice from a colleague. The base64 content has to be *decoded* so that we can save it. This is what worked:

// Get the base64-encoded image from the plugin
var img = signatureArea.getSignatureImage();
var outfile = fakefilename(); // I'm creating a unique filename to use for saving in my testing

$.ajax({
    url: _spPageContextInfo.webAbsoluteUrl +
        "/_api/web/getfolderbyserverrelativeurl('/path/to/my/picture/library/')/files/add(overwrite=true, url='" + outfile + "')",
    type: "POST",
    data: convertDataURIToBinary(img),
    processData: false,
    headers: {
        "accept": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val()
    },
    success: function() {
        $("#sig-file").attr("src", outfile); // Show the image file in the form
    }
});

// Useful function "borrowed" from http://sharepoint.stackexchange.com/questions/60417/cant-upload-a-non-text-file-to-sharepoint-app-via-rest-api
// Decodes the base64 text data back into the binary data representation of the image file
var convertDataURIToBinary = function(dataURI) {
    var base64Marker = ";base64,";
    var base64Index = dataURI.indexOf(base64Marker) + base64Marker.length;
    var base64 = dataURI.substring(base64Index);
    var raw = window.atob(base64);
    var rawLength = raw.length;
    var array = new window.Uint8Array(new window.ArrayBuffer(rawLength));

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

Similar Posts

7 Comments

  1. Hi Marc,

    I was able to implement Signature in Infopath form according to your previous article. But since I want to print out the form with signature I think I will need to save the signature as an image.
    Should I add the above script to code already written for JSON signature ?
    And should I create an image field in form and place it in section with screenTip “==Signature==” ?
    Do I need to create a picture library and how can I reference it to the field ?

    Thanks in advance for all your help.

    1. @MMomin:

      In another implementation of this, I stored the image files in a library and put the URL to the image(s) in the InfoPath form. So it’s definitely possible; you just need to figure out how you want it to work.

      M.

      1. Thanks Marc
        That worked very well in Chrome. I really appreciate all your help.
        But in IE 11 it throws error at

        var array = new window.Uint8Array(new window.ArrayBuffer(rawLength));

        Any advice ?

      2. Hello Marc. The signature on the form shows as coordinates when I use the PeoplePicker or save the form. Any ideas on getting it to show as an actual signature on the form when saved or the PeoplePicker is populated?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.