Create e-Signature with Salesforce Lightning Design System

Hi All,
In my previous post I have shown you how we can Meta data Api using Oauth 2.0 workflow.
Today I will tell you how we can use canvas to draw your signature and how we can attach this signature with your information in Salesforce lightning Design System.

When insert new contact it will look like this :
new

And when update existing contact it will look like this (using contact id in url with conId parameter):
update

Let’s walk through code:

Create ContactWithSignatureController class:

global with sharing class ContactWithSignatureController {
    public contact con {get;set;}
    public boolean flag {get;set;}
    public string attId {get;set;}
    public ContactWithSignatureController() {
        String conId = apexPages.CurrentPage().getParameters().get('conId');
        con = new contact();
        flag = true;
        attId = '';
        if (conId != null && conId.trim() != '') {
            con = [select id, firstname, lastname, name, phone from contact where id = : conId];
            flag = false;
            list < attachment > attIds = [select id from Attachment where name = 'Signature Image'
                and parentId = : conId
            ];
            if (attIds.size() > 0) {
                attId = attIds[0].id;
            }
        }
    }
    public void saveCon() {
        upsert con;
    }

    @RemoteAction
    global static String saveSignature(String imageUrl, String pId) {
        try {
            delete[select id from Attachment where name = 'Signature Image'
                and parentId = : pId];
            Attachment accSign = new Attachment();
            accSign.ParentID = pId;
            accSign.Body = EncodingUtil.base64Decode(imageUrl);
            accSign.contentType = 'image/png';
            accSign.Name = 'Signature Image';
            accSign.OwnerId = UserInfo.getUserId();
            insert accSign;
            return 'success';

        } catch (Exception e) {
            system.debug('---------- ' + e.getMessage());
            return JSON.serialize(e.getMessage());
        }
        return null;
    }
}

Create page with “ContactWithSignature” name

<apex:page id="pg" controller="ContactWithSignatureController" showHeader="false" sidebar="false" standardStylesheets="false">
    <html xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

    <head>
        <apex:stylesheet value="{!URLFOR($Resource.SLDS080, 'assets/styles/salesforce-lightning-design-system-vf.css')}" />
        <STYLE TYPE="text/css">
            ::-webkit-scrollbar {
                width: 8px;
                height: 8px;
            }
            
            ::-webkit-scrollbar-track-piece {
                background-color: #a8b7c7;
                border-radius: 20px;
            }
            
            ::-webkit-scrollbar-thumb:vertical {
                height: 30px;
                background-color: #e0e5ee;
                border-radius: 20px;
            }
        </STYLE>

    </head>
    <apex:form id="mainForm">
        <apex:outputPanel id="rnd">
            <script>
                function SaveSign() {
                    window.frames[0].frameElement.contentWindow.saveSignature("{!con.id}");
                }
            </script>
        </apex:outputPanel>

        <apex:actionFunction action="{!saveCon}" name="saveCon" reRender="rnd" oncomplete="SaveSign();return false;" />
        <div class="slds">
            <div class="slds-page-header">
                <div class="slds-grid">
                    <div class="slds-col slds-has-flexi-truncate">
                        <div class="slds-media">
                            <div class="slds-media__figure">
                                <svg aria-hidden="true" class="slds-icon slds-icon--large slds-icon-standard-user">
                                    <use xlink:href="{!URLFOR($Resource.SLDS080, 'assets/icons/standard-sprite/svg/symbols.svg#contact')}"></use>
                                </svg>
                            </div>
                            <div class="slds-media__body">
                                <p class="slds-text-heading--label">Contact</p>
                                <div class="slds-grid">
                                    <h1 class="slds-text-heading--medium slds-m-right--small slds-truncate slds-align-middle">
                                        <apex:outputPanel rendered="{!flag}">
                                            New Contact
                                        </apex:outputPanel>
                                        <apex:outputPanel rendered="{!!flag}">
                                            Update Contact
                                        </apex:outputPanel>
                                    </h1>
                                </div>
                            </div>
                        </div>
                    </div>
                    <!-- /slds-col-->
                </div>
                <!-- /slds-grid-->
            </div>
            <!-- /slds-page-header-->
            <div class="container">
                <div class="slds-form--horizontal slds-m-right--xx-large slds-m-top--xx-large slds-p-right--xx-large">
                    <div class="slds-form-element">
                        <label class="slds-form-element__label" for="sample1">First Name</label>
                        <div class="slds-form-element__control">
                            <apex:inputField value="{!con.firstname}" styleClass="slds-input" html-placeholder="First Name" />
                        </div>
                    </div>
                    <div class="slds-form-element">
                        <label class="slds-form-element__label" for="sample1">Last Name</label>
                        <div class="slds-form-element__control">
                            <apex:inputField value="{!con.lastname}" styleClass="slds-input" html-placeholder="Last Name" />
                        </div>
                    </div>
                    <div class="slds-form-element">
                        <label class="slds-form-element__label" for="sample1">Phone</label>
                        <div class="slds-form-element__control">
                            <apex:inputField value="{!con.phone}" styleClass="slds-input" html-placeholder="Phone" />
                        </div>
                    </div>
                    <div class="slds-form-element">
                        <span class="slds-form-element__label">Signature </span>
                        <div class="slds-form-element__control">
                            <iframe src="/apex/ContactWithSignatureComponent?conId={!con.id}" style="border:none; width:360px; height:125px"></iframe>
                        </div>
                        <apex:outputPanel rendered="{!if(!flag && attId!='',true,false)}">
                            <br/>
                            <span class="slds-form-element__label">Current Signature </span>
                            <div class="slds-form-element__control">
                                <apex:image url="/servlet/servlet.FileDownload?file={!attId}" />
                            </div>
                        </apex:outputPanel>
                    </div>
                    <div class="slds-form-element">
                        <div class="slds-button-group slds-float--right" role="group">
                            <apex:commandButton value="Submit" onclick="saveCon();return false;" styleClass="slds-button slds-button--neutral" />
                            <apex:commandButton value="Clear" onclick="window.frames[0].frameElement.contentWindow.clearSign();return false;" styleClass="slds-button slds-button--neutral" />
                        </div>
                    </div>
                </div>
            </div>
			<!-- /container-->
		</div>
    </apex:form>

    </html>
</apex:page>

Create another page with “ContactWithSignatureComponent” name

<apex:page controller="ContactWithSignatureController" standardStylesheets="false" sidebar="false" showHeader="false">
    <apex:includeScript value="/soap/ajax/28.0/connection.js" />
    <apex:form id="pbform">
        <div>
            <canvas id="signatureCanvas" height="100px" width="350px" style="    border: 1px solid #d8dde6; border-radius: 8px;"></canvas>
        </div>
    </apex:form>
    <script>
        var canvas;
        var context;
        var drawingUtil;
        var isDrawing = false;
        var pId = '';
        var prevX, prevY, currX, currY = 0;
        var pId;

        function DrawingUtil() {
            isDrawing = false;
            canvas.addEventListener("mousedown", start, false);
            canvas.addEventListener("mousemove", draw, false);
            canvas.addEventListener("mouseup", stop, false);
            canvas.addEventListener("mouseout", stop, false);
            canvas.addEventListener("touchstart", start, false);
            canvas.addEventListener("touchmove", draw, false);
            canvas.addEventListener("touchend", stop, false);
            w = canvas.width;
            h = canvas.height;
        }

        function start(event) {
            event.preventDefault();

            isDrawing = true;
            prevX = currX;
            prevX = currY;
            currX = event.clientX - canvas.offsetLeft;
            currY = event.clientY - canvas.offsetTop;

            context.beginPath();
            context.fillStyle = "cadetblue";
            context.fillRect(currX, currY, 2, 2);
            context.closePath();

        }

        function draw(event) {
            event.preventDefault();
            if (isDrawing) {
                prevX = currX;
                prevY = currY;
                currX = event.clientX - canvas.offsetLeft;
                currY = event.clientY - canvas.offsetTop;
                context.beginPath();
                context.moveTo(prevX, prevY);
                context.lineTo(currX, currY);
                context.strokeStyle = "cadetblue";
                context.lineWidth = "2";
                context.stroke();
                context.closePath();
            }
        }

        function stop(event) {
            if (isDrawing) {
                context.stroke();
                context.closePath();
                isDrawing = false;
            }
        }

        function clearSign() {
            context.clearRect(0, 0, w, h);
        }

        canvas = document.getElementById("signatureCanvas");
        context = canvas.getContext("2d");
        context.strokeStyle = "black";
        context.lineWidth = "2";
        drawingUtil = new DrawingUtil(canvas);

        function saveSignature(conId) {
            var strDataURI = canvas.toDataURL();
            strDataURI = strDataURI.replace(/^data:image\/(png|jpg);base64,/, "");
            pId = conId;
            var result = ContactWithSignatureController.saveSignature(strDataURI, conId, processResult);

        }

        function processResult(result) {
            window.parent.location.href = '/apex/ContactWithSignature?conId=' + pId;
        }
    </script>
</apex:page>

Now its time to preview the ContactWithSignature page and fill contact information with e-Signature. And When you click on “Submit” button it will redirect to detail page of contact.

For more information mail me on this Email Address: sushil.verma1988@gmail.com

Thanks

2 thoughts on “Create e-Signature with Salesforce Lightning Design System

Leave a reply to Ganesh Cancel reply