Skip to main content

Search

Handwriting

Comments

10 comments

  • Ardevia Forum

    Original Post by dany (Imported from Ardevia Forum)

    Rich Forms supports custom field rendering. So if there were a "handwriting" field you could reuse them on customized forms. Sadly I couldn't find one as an app in the store.

     

    But because Rich Forms is based on standard dynamic HTML and client-side rendering, it is possible to add this functionality to your forms using JavaScript. Do I understand correctly, you would like to have a field on the form looking something like http://jsfiddle.net/zakkzahz/3/ ?

    0
  • Ardevia Forum

    Original Post by VACOI (Imported from Ardevia Forum)

    Exactly, I need a field like this ("Signature (please draw your signature in this box)"). is it possible?

     

    Thanks.

    0
  • Ardevia Forum

    Original Post by dany (Imported from Ardevia Forum)

    Yes, it's possible. I have built a signature field control using HTML5/JavaScript.

     

    Here's how you can reuse it:
    - On the list you want to be signed before saving, add a picture URL field named "Signature" and make it a required field
    - Create a document library called "Signatures" (this is where the signature images are stored)
    - Now customize the new and/or edit form using Ardevia Rich Forms (free version works fine too)
    - Insert a Script Editor web part and embed following code:

    <style>
            #signatureCanvas {
                border: solid 1px lightgray;
            }
    </style>
    <div id="signatureFieldEditor"></div>
    <script type='text/javascript'>
    (function (Ardevia) {
                /*"use strict";*/
    
                Ardevia.SignatureControl = function (options) {
                    var containerId = options && options.containerId || "container",
                        fieldName = options && options.fieldName || "Signature",
                        targetFolder = options && options.targetFolder || "/SiteAssets",
                        label = options && options.label || "Signature (please draw in this box)",
                        requiredMessage = options && options.requiredMessage || null,
                        cWidth = options && options.width || "300",
                        cHeight = options && options.height || "150",
                        penColor = options && options.penColor || 'blue',
                        btnClearId,
                        cleared = true,
                        modified = false,
                        canvas,
                        oldPreSaveItem,
                        ctx;
    
                    function initControl() {
                        hideUrlField();
                        createControlElements();
                        wireButtonEvents();
                        canvas = document.getElementById("signatureCanvas");
                        canvas.addEventListener("mousedown", pointerDown, false);
                        canvas.addEventListener("mouseup", pointerUp, false);
                        canvas.addEventListener("mouseout", pointerOut, false);
                        ctx = canvas.getContext("2d");
                        oldPreSaveItem = window["PreSaveItem"];
                        window["PreSaveItem"] = OnPreSaveItem;
                    }
    
                    function hideUrlField() {
                        var inputController = ArdeviaJQuery('span.ms-formbody[fieldname="' + fieldName + '"]').closest('.ard-formfield').data('Controller');
                        if (inputController) {
                            inputController.InstanseData.SetValue("");
                            ArdeviaJQuery('span.ms-formbody[fieldname="' + fieldName + '"]').closest('.ard-fieldrow').css('visibility', 'hidden').css('position', 'absolute');
                        } else { setTimeout(hideUrlField, 200); }
                    }
    
                    function createControlElements() {
                        var signatureArea = document.createElement("div"),
                            labelDiv = document.createElement("div"),
                            canvasDiv = document.createElement("div"),
                            canvasElement = document.createElement("canvas"),
                            buttonsContainer = document.createElement("div"),
                            buttonClear = document.createElement("button");
    
                        labelDiv.className = "signatureLabel";
                        labelDiv.textContent = label;
    
                        canvasElement.id = "signatureCanvas";
                        canvasElement.width = cWidth;
                        canvasElement.height = cHeight;
                        /*canvasElement.style.border = "solid 2px black";*/
    
                        buttonClear.id = "btnClear";
                        buttonClear.type = "button";
                        buttonClear.textContent = "Clear";
    
                        canvasDiv.appendChild(canvasElement);
                        buttonsContainer.appendChild(buttonClear);
    
                        signatureArea.className = "signatureArea";
                        signatureArea.appendChild(labelDiv);
                        signatureArea.appendChild(canvasDiv);
                        signatureArea.appendChild(buttonsContainer);
    
                        document.getElementById(containerId).appendChild(signatureArea);
                    }
    
    
                    function pointerDown(evt) {
                        ctx.beginPath();
                        ctx.moveTo(evt.offsetX, evt.offsetY);
                        canvas.addEventListener("mousemove", paint, false);
                    }
    
                    function pointerUp(evt) {
                        canvas.removeEventListener("mousemove", paint);
                        paint(evt);
                    }
    
                    function pointerOut(evt) {
                        canvas.removeEventListener("mousemove", paint);
                    }
    
    
                    function paint(evt) {
                        cleared = false;
                        modified = true;
                        ctx.lineTo(evt.offsetX, evt.offsetY);
                        ctx.strokeStyle = penColor;
                        ctx.stroke();
                    }
    
                    function wireButtonEvents() {
                        var btnClear = document.getElementById("btnClear");
                        btnClear.addEventListener("click", function () {
                            ctx.clearRect(0, 0, canvas.width, canvas.height);
                            cleared = true; modified = true;
                        }, false);
                    }
    
                    function getSignatureImage() {
                        return ctx.getImageData(0, 0, canvas.width, canvas.height).data;
                    }
    
                    function getDataUri() {
                        return canvas.toDataURL("image/png");
                    }
    
                    function isModified(changeVal) {
                        if (typeof changeVal !== "undefined") modified = changeVal;
                        return modified;
                    }
    
                    function isCleared() {
                        return cleared;
                    }
    
    
                    function OnPreSaveItem() {
                        if ((requiredMessage) && signature.isCleared()) {
                            var inputController = ArdeviaJQuery('span.ms-formbody[fieldname="' + fieldName + '"]').closest('.ard-formfield').data('Controller');
                            inputController.InstanseData.SetValue("");
                            alert(requiredMessage);
                            if (oldPreSaveItem) return oldPreSaveItem(); else return true;
                        }
                        if (signature.isModified()) {
                            var fieldUrl = Ardevia.Helpers.FormControlEventsHelper.GetValueCallbacks[fieldName]();
                            var fileName;
                            if (fieldUrl) {
                                fileName = fieldUrl.substring(fieldUrl.lastIndexOf("/") + 1);
                            } else {
                                fileName = "Sig_" + Math.random().toString().substring(2) + ".png";
                            }
                            SaveToFile(signature.getDataUri(), fileName, targetFolder);
                            var inputController = ArdeviaJQuery('span.ms-formbody[fieldname="' + fieldName + '"]').closest('.ard-formfield').data('Controller');
                            inputController.InstanseData.SetValue(targetFolder + '/' + fileName);
                            signature.isModified(false);
                        }
                        if (oldPreSaveItem) return oldPreSaveItem(); else return true;
                    }
    
                    function SaveToFile(content, filename, serverRelativeUrl) {
                        var ctx = new SP.ClientContext.get_current();
                        var createInfo = new SP.FileCreationInformation();
                        createInfo.set_content(new SP.Base64EncodedByteArray());
                        var arr = convertDataURIToBinary(content);
                        for (var i = 0; i < arr.length; ++i) {
                            createInfo.get_content().append(arr[i]);
                        }
                        createInfo.set_overwrite(true);
                        createInfo.set_url(filename);
                        this.files = ctx.get_web().getFolderByServerRelativeUrl(serverRelativeUrl).get_files();
                        ctx.load(this.files);
                        this.files.add(createInfo);
                        ctx.executeQueryAsync(function (s, e) {
                        }, function (sender, args) {
                            alert('Error saving signature: ' + args.get_message());
                        });
                    }
    
                    var BASE64_MARKER = ';base64,';
    
                    function convertDataURIToBinary(dataURI) {
                        var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
                        var base64 = dataURI.substring(base64Index);
                        var raw = window.atob(base64);
                        var rawLength = raw.length;
                        var array = new Uint8Array(new ArrayBuffer(rawLength));
                        for (i = 0; i < rawLength; i++) {
                            array[i] = raw.charCodeAt(i);
                        }
                        return array;
                    }
    
    
                    return {
                        init: initControl,
                        getSignatureImage: getSignatureImage,
                        getDataUri: getDataUri,
                        isModified: isModified,
                        isCleared: isCleared
                    };
                }
            })(this.Ardevia = this.Ardevia || {});
    
    
            var signature;
    
            function loaded() {
                if (!signature) {
                    // Configure your settings here !!!
                    signature = new Ardevia.SignatureControl({
                        fieldName: 'Signature',
                        targetFolder: '/sites/dev/Signatures',
                        containerId: 'signatureFieldEditor',
                        label: 'Signature (please draw in this box)',
                        requiredMessage: 'Please sign in the Signature box before saving.',
                        width: 300,
                        height: 150,
                        penColor: 'blue'
                    });
                    signature.init();
                }
            }
    
            _spBodyOnLoadFunctionNames.push('loaded');
    
       
    </script>
    

    - Make sure to configure the properities below the comment "Configure your settings here !!!", mainly the targetFolder
    - Save your customized form and enjoy.

     

    Now you should have a signature control that needs to be filled before it can be saved.

    0
  • Ardevia Forum

    Original Post by ronanmcl (Imported from Ardevia Forum)

    I get an error "Error saving signature: Value does not fall within the expected range." when saving the form.

    0
  • Ardevia Forum

    Original Post by dany (Imported from Ardevia Forum)

    Be sure to set the server-relative URL to the library (or list) for targetFolder in  the code at line 212. In the example targetFolder is set to '/sites/dev/Signatures' where '/sites/dev/' is the sites URL and 'Signatures' is the library.

    0
  • Ardevia Forum

    Original Post by Dale (Imported from Ardevia Forum)

    My list item never saves and 'Working on it' spins forever. When I cancel I do have a sig_nnn file in the Signatures document library.

    0
  • Ardevia Forum

    Original Post by dany (Imported from Ardevia Forum)

    Can you see any JavaScript error messages in the developer tools of your browser(F12)?

    0
  • Ardevia Forum

    Original Post by Dale (Imported from Ardevia Forum)

    Yes, I get two errors:

     

    1) SCRIPT5: Access is denied.
       File: forbidframing.htm, Line: 1, Column: 1

     

    2) SCRIPT5007: Unable to get property 'InstanseData' of undefined or null reference
       File: NewForm.aspx, Line: 644, Column: 21

    0
  • Ardevia Forum

    Original Post by dany (Imported from Ardevia Forum)

    Looks like it can't find the Signature field. Are you sure you have a picture URL field on the form? It must have the internal name (not display name) you define in the fieldname setting (line 211), in the example "Signature". The field will be hidden by the script, but needs to be on the form so that it is saved correctly.

    0
  • Ardevia Forum

    Original Post by Dale (Imported from Ardevia Forum)

    I didn't have 'Signature' displayed in the form. Once I added it, it worked!

     

    Thanks,
    Dale

    0

Please sign in to leave a comment.