Signature Pad using lightning components:
In this topic , we will display digital signature pad using lightning components and it will be responsive also. we will save the signature in to object also.Note: This signature pad is not using any third party file . We will use our custom js in our lighting component.
Follow the steps below--
Step 1: Create lightning component "ESignature.cmp" and use below code in this component.
<aura:component controller="SignatureCtr" implements="force:appHostable">
<ltng:require afterScriptsLoaded="{!c.Init}"/>
<div
style="text-align: center;">
<canvas aura:id="can"
style="border:2px solid #ddd;background:
transparent;"></canvas>
</div>
<div
style="text-align: center;margin: 7px;">
<button class="slds-button slds-button_brand"
onclick="{!c.erase}">Clear</button>
<button class="slds-button slds-button_brand"
onclick="{!c.save}">Save</button>
</div>
</aura:component>
|
Step 2: Now create "ESignatureController.js" by click on controller and use below code in this controller.
({
Init :
function(component, event, helper) {
helper.doInit(component, event, helper);
},
erase:function(component, event, helper){
helper.eraseHelper(component, event, helper);
},
save:function(component, event, helper){
helper.saveHelper(component, event, helper);
}
})
|
Step 3: Now create "ESignatureHelper.js" by click on helper and use below code in this helper.
({
doInit
: function(component, event, helper) {
var canvas, ctx, flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
dot_flag = false;
var
x = "black",
y = 2,
w,h;
canvas=component.find('can').getElement();
var
ratio = Math.max(window.devicePixelRatio || 1, 1);
w =
canvas.width*ratio;
h =
canvas.height*ratio;
ctx
= canvas.getContext("2d");
console.log('ctx:='+ctx);
canvas.addEventListener("mousemove", function (e) {
findxy('move', e)
},
false);
canvas.addEventListener("mousedown", function (e) {
findxy('down', e)
},
false);
canvas.addEventListener("mouseup", function (e) {
findxy('up', e)
},
false);
canvas.addEventListener("mouseout", function (e) {
findxy('out', e)
},
false);
// Set up touch
events for mobile, etc
canvas.addEventListener("touchstart", function (e) {
var touch = e.touches[0];
console.log('touch start:='+touch);
var mouseEvent = new MouseEvent("mousedown", {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
e.preventDefault();
},
false);
canvas.addEventListener("touchend", function (e) {
var mouseEvent = new MouseEvent("mouseup", {});
canvas.dispatchEvent(mouseEvent);
},
false);
canvas.addEventListener("touchmove", function (e) {
var touch = e.touches[0];
var mouseEvent = new MouseEvent("mousemove", {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
e.preventDefault();
},
false);
// Get the
position of a touch relative to the canvas
function getTouchPos(canvasDom, touchEvent)
{
var rect = canvasDom.getBoundingClientRect();
return {
x: touchEvent.touches[0].clientX - rect.left,
y: touchEvent.touches[0].clientY - rect.top
};
}
function findxy(res, e){
const rect = canvas.getBoundingClientRect();
if (res == 'down') {
prevX = currX;
prevY = currY;
currX = e.clientX - rect.left ;
currY = e.clientY - rect.top;
flag = true;
dot_flag = true;
if (dot_flag) {
ctx.beginPath();
ctx.fillStyle = x;
ctx.fillRect(currX, currY, 2, 2);
ctx.closePath();
dot_flag = false;
}
}
if (res == 'up' || res == "out") {
flag = false;
}
if (res == 'move') {
if (flag) {
prevX = currX;
prevY = currY;
currX = e.clientX - rect.left;
currY = e.clientY -
rect.top;
draw(component,ctx);
}
}
}
function draw() {
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.stroke();
ctx.closePath();
}
},
eraseHelper: function(component, event, helper){
var
m = confirm("Want to clear");
if
(m) {
var canvas=component.find('can').getElement();
var ctx = canvas.getContext("2d");
var w = canvas.width;
var h = canvas.height;
ctx.clearRect(0, 0, w, h);
}
},
saveHelper:function(component, event, helper){
var
pad=component.find('can').getElement();
var
dataUrl = pad.toDataURL();
console.log('dataUrl:='+dataUrl);
var
strDataURI=dataUrl.replace(/^data:image\/(png|jpg);base64,/, "");
var
action = component.get("c.saveSignature");
action.setParams({
signatureBody : strDataURI
});
action.setCallback(this,function(res){
var state = res.getState();
if(state==="SUCCESS"){
alert("Signature saved successfully");
}
});
$A.enqueueAction(action);
}
})
|
Step 4: So We have created working signature pad . Now we will save that signature in our object.
So here I create a object and provide a custom record id in attachment. but you can use any object to save attachment .
Now create a apex class name "SignatureCtr" use below code in class:
public class SignatureCtr{
@AuraEnabled
public
static void saveSignature(String signatureBody){
Attachment
a = new Attachment();
a.ParentId = 'a097F00000765JA'; // record id of object.
a.Body = EncodingUtil.base64Decode(signatureBody);
a.ContentType
= 'image/png';
a.Name = 'Signature Capture.png';
insert a;
}
}
|
So signature pad created successfully ans saved in to object successfully also.
Is it possible to resize the canvas? So that height is bigger so users can sign landscape on mobile. I've tried changing the code, but nothing seems to affect the size. Not sure if this is a salesforce limitation or if I'm just doing it wrong.
ReplyDeleteAm i only the one who can see the code in a single vertical line, please chagne it ,it will be useful
ReplyDelete