8

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>
  • 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. – Phil Hawthorn Dec 16 '13 at 16:25
  • @Phil Thank you for your reply. I will try this and reply to you. – Lavanya Sanathkumar Dec 16 '13 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 – Mohith Shrivastava Dec 16 '13 at 16:34
  • Nice, can't see any reason it would not work then as per sfdcfox's answer – Phil Hawthorn Dec 16 '13 at 16:56
4

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>
  • 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? – Lavanya Sanathkumar Dec 17 '13 at 5:23
  • which browser are you using?Html5 canvas supports only few browsers – Mohith Shrivastava Dec 17 '13 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. – Lavanya Sanathkumar Dec 17 '13 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 ? – Mohith Shrivastava Dec 17 '13 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. – Lavanya Sanathkumar Dec 23 '13 at 5:13
3
  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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.