9

We have a requirement for Customer Sign-up form. We have created a VF Tab and included VF page for creating Customer signup form. In that Customer Signup Form, we have a field to get the Customer signature. After filling the form customer needs to sign on that particular signature pad field. After the formalities, the form should be generated as PDF and should be sent it to the customer as an Email. We have tried using this link http://thomasjbradley.ca/lab/signature-pad/. With reference to this link we are able to get the Customer signature but we don't know how to save this as PDF and send it to as an Email. Can anyone please help me out in this?

Vf Code:

<apex:outputPanel id="signuppopup"> 

    <apex:outputPanel styleClass="popupBackground" layout="block" rendered="{!displayPopUp}"/>
    <apex:outputPanel styleClass="custPopup" layout="block" rendered="{!displayPopUp}" style="overflow:auto; width:800px; height:500px;">
        <!-- <apex:commandButton value="Submit" action="{!saveAnswers}" rerender="signuppopup"/>
        <apex:commandButton value="Save" action="{!saveAnswers}" rerender="signuppopup"/>-->
    <apex:commandButton value="HidePopup" action="{!closePopup}" rerender="signuppopup" style="float:right" />

        <!-------------- Account Detail Header --------------->
        <apex:pageBlock >
        <apex:pageBlockSection title="Account Details" columns="2">
        <apex:outputField value="{!CSignup.Acc.Name}"/>
                </apex:pageBlockSection>  
            <apex:pageBlockSection title="SIGNUP FORM"></apex:pageBlockSection>
            <!--<button onclick="findAccounts();" value = "sign" rerender="signature"/>-->
          <!--<apex:commandButton value="Submit" action="{!saveSignature}" rerender="signature"/>-->
        <!-------------- End of Account Detail Header --------------->   
    <!--</apex:pageBlock>
        <apex:pageBlock >-->
<script>var $j = jQuery.noConflict();</script>
<apex:stylesheet value="{!URLFOR($Resource.jquerymobile132mincss,'styles.css')}"/>
<apex:includeScript value="{!URLFOR($Resource.jqueryjs)}"  />
<apex:includeScript value="{!URLFOR($Resource.jquerymobile132minjs)}"/>

<div data-role="page" id="signatureCaptureHome"> 
<div data-role="content">
<input id="accountNameId" type="text" name="accountName"/>
<input type="button" name="findAccountBtn" onclick="findAccounts();" value="Find Accounts"/>
<h1 id="recordSigId">Record Signature:</h1>
<canvas id="signatureCanvas" height="200px" width="300px"/>
<input id="saveSigButton" type="button" name="SigCap" onclick="saveSignature();" value="Capture Signature"></input>
</div> 
</div> 
<div data-role="page" id="signatureCaptureHome"> 
<div data-role="content">
<input id="accountNameId" type="text" name="accountName"/>
<input type="button" name="findAccountBtn" onclick="findAccounts();" value="Find Accounts"/>
</div> 
</div> 
<!-------------------->
<script>

    var canvas;
    var context;
    var drawingUtil;
    var isDrawing = false;
    var accountId = '';

function DrawingUtil() 
{
    isDrawing = false;
    canvas.addEventListener("touchstart",start,false);
    canvas.addEventListener("touchmove",draw,false);
    canvas.addEventListener("touchend",stop,false);
    context.strokeStyle = "#FFF";  
}

//Start Event for Signature Captuare on HTML5 Canvas
function start(event) 
{
    isDrawing = true;
    canvas = document.getElementById("signatureCanvas");
    context = canvas.getContext("2d");    
    context.strokeStyle = "rgba(155,0,0,0.5)";      
    context.beginPath();
     context.moveTo(event.touches[0].pageX - canvas.getBoundingClientRect().left,event.touches[0].pageY - canvas.getBoundingClientRect().top);
}

//Event while someone is drawing to caputre the path while they draw....
function draw(event) {
    event.preventDefault();
    if(isDrawing) {     
        context.lineTo(event.touches[0].pageX - canvas.getBoundingClientRect().left,event.touches[0].pageY - canvas.getBoundingClientRect().top);
        context.stroke();
    }
}


//Event when someone stops drawing their signature line
function stop(event) {
    if(isDrawing) {
        context.stroke();
        context.closePath();
        isDrawing = false;
    }
}

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

function saveSignature()
{
var strDataURI = canvas.toDataURL();
    // alert(strDataURI);
    strDataURI = strDataURI.replace(/^data:image\/(png|jpg);base64,/, "");
//alert(strDataURI);
AnyObjectSignatureController.saveSignature(strDataURI,accountId,processResult);
}

function processResult(result)
{
alert(JSON.stringify(result));
}

function findAccounts()
{
var nameValue = document.getElementById("accountNameId").value;
AnyObjectSignatureController.findAccounts(nameValue, processSearchResult);
} 

function processSearchResult(result)
{
$j = jQuery.noConflict();
//$j("#accountList").html("");
$j.each(result, function(i, record) {accountId = record.Id; $j("#recordSigId").html("Record Signature: " + record.Name);});
$j("#recordSigId").trigger("update");
//$j("#accountList").trigger("update");
//alert(JSON.stringify(result));
}


</script>

<!----------------->    

        </apex:pageBlock>
    </apex:outputPanel>
</apex:outputPanel>
4
  • 2
    Looking at that plugin, it uses HTML5 canvas to allow a user to draw (or type) a signature. I'm thinking you would probably have to serialize the data of that signature to a file (using canvas.toDataURL()) and then refer to it in your VF markup for rendering as a PDF. Not sure it would work without trying it though. Commented Dec 16, 2013 at 16:25
  • @Phil Thank you for your reply. I will try this and reply to you. Commented Dec 16, 2013 at 16:32
  • 1
    @PhilHawthorn Looks like there is already code written and an API is avaliable. The API includes a method called getSignatureImage() which will return a Base64 encoded PNG to Javascript and may be we can use that to insert into attachment of salesofrce and then grab the image from there for pdf Commented Dec 16, 2013 at 16:34
  • Nice, can't see any reason it would not work then as per sfdcfox's answer Commented Dec 16, 2013 at 16:56

2 Answers 2

5

There is already a nice blogpost on how to do this

http://corycowgill.blogspot.in/2013/12/capturing-signatures-with-html5-canvas.html

global with sharing class AnyObjectSignatureController {
   public AnyObjectSignatureController(){
   }

 @RemoteAction
 global static String saveSignature(String signatureBody, String parentId) {
   try{
    system.debug('Record Id == ' + parentId);
    system.debug(signatureBody);
    Attachment a = new Attachment();
    a.ParentId = parentId;
    a.ContentType = 'image/png';
    a.Name = 'Signature Capture.png';
    insert a;
    return '{success:true, attachId:' + a.Id + '}';
    }catch(Exception e){
        return JSON.serialize(e);
   }
   return null;
 }

}

Script


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

 function saveSignature(){
  var strDataURI = canvas.toDataURL();
// alert(strDataURI);
strDataURI = strDataURI.replace(/^data:image\/(png|jpg);base64,/, "");
 //alert(strDataURI);
AnyObjectSignatureController.saveSignature(strDataURI,accountId,processResult);
}

Visualforce Page


<canvas id="signatureCanvas" height="200px" width="300px"/>
  <input id="saveSigButton" type="button" name="SigCap" onclick="saveSignature();"   value="Capture Signature"></input>
5
  • thank you so much, I got the expected result using your code and link. I am able to achieve this functionality using mobile app. But there are some minor issues when I am trying it in my PC, I am not able to get the signature. Can you please help me out? Commented Dec 17, 2013 at 5:23
  • which browser are you using?Html5 canvas supports only few browsers Commented Dec 17, 2013 at 5:40
  • thanks a lot, I tried using firefox, chrome, IE and Opera. I am able to find the account but not able to sign it. Commented Dec 17, 2013 at 6:42
  • Do a inspect element in your browser to see if some issues in script .Also use alerts in javascript to see data thats coming ? Commented Dec 17, 2013 at 8:58
  • thanks for your reply.When I am trying to do this in popup window signature is not capturing.I have given this code in output panel. I have updated my question with VF code,kindly help me to resolve this. Commented Dec 23, 2013 at 5:13
4
  1. Acquire the image data from the canvas.
  2. Save the data as an attachment on the record.
  3. Generate the PDF linking to that image file.

If I recall correctly, data URLs aren't supported by the PDF renderer, so just save it as an attachment.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .