Skip to Content
Author's profile photo Happy Chhillar

SAPUI5: Digital Signature Pad

1.   Introduction

This document contains the functionality to draw the digital Signature on Signature Pad in SAP UI5 application. For this, I have used the HTML5 control. Users can draw the digital Signature on Signature Pad and can download the signature performed on .JPEG format. If signature is not performed correctly, then user can use the clear button to clear the signature pad and draw the signature again.

2.   Prerequisite

  • Eclipse with SAP UI5 plugin (1.28 or higher).

3.   SAP UI5 Control

sap.ui.core.HTML is used to implement the Digital Signature Pad.

4.   XML View Code

<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc"
	xmlns="sap.m" controllerName="sap.ui.demo.myFiori.views.SignPad"
	xmlns:html="http://www.w3.org/1999/xhtml">
	<Page title="Digital Signature Pad">
		<content>
			<VBox>
				<core:HTML id="html">
				</core:HTML>
			</VBox>
			<VBox>
				<HBox>
<Button id="Signature" text="Signature" press="onSign"> </Button>
					<Button id="Save" text="Save" press="saveButton"></Button>
					<Button id="clear" text="Clear" press="clearButton"></Button>
				</HBox>
			</VBox>
		</content>
	</Page>
</core:View>

5.   JS Controller Code

sap.ui.controller("views.SignPad_Edited", {

	onInit: function() {
		this.getView().byId("html").setContent("<canvas id='signature-pad' width='400' height='200' class='signature-pad'></canvas>");
	},
	
	/******************Signature Pad Draw************************/
	
	onSign : function(oEvent){
		var canvas = document.getElementById("signature-pad");
		var context = canvas.getContext("2d");
		canvas.width = 276;
		canvas.height = 180;
		context.fillStyle = "#fff";
		context.strokeStyle = "#444";
		context.lineWidth = 1.5;
		context.lineCap = "round";
		context.fillRect(0, 0, canvas.width, canvas.height);
		var disableSave = true;
		var pixels = [];
		var cpixels = [];
		var xyLast = {};
		var xyAddLast = {};
		var calculate = false;
		{ 	//functions
			function remove_event_listeners() {
				canvas.removeEventListener('mousemove', on_mousemove, false);
				canvas.removeEventListener('mouseup', on_mouseup, false);
				canvas.removeEventListener('touchmove', on_mousemove, false);
				canvas.removeEventListener('touchend', on_mouseup, false);

				document.body.removeEventListener('mouseup', on_mouseup, false);
				document.body.removeEventListener('touchend', on_mouseup, false);
			}

			function get_coords(e) {
				var x, y;

				if (e.changedTouches && e.changedTouches[0]) {
					var offsety = canvas.offsetTop || 0;
					var offsetx = canvas.offsetLeft || 0;

					x = e.changedTouches[0].pageX - offsetx;
					y = e.changedTouches[0].pageY - offsety;
				} else if (e.layerX || 0 == e.layerX) {
					x = e.layerX;
					y = e.layerY;
				} else if (e.offsetX || 0 == e.offsetX) {
					x = e.offsetX;
					y = e.offsetY;
				}

				return {
					x : x, y : y
				};
			};

			function on_mousedown(e) {
				e.preventDefault();
				e.stopPropagation();

				canvas.addEventListener('mouseup', on_mouseup, false);
				canvas.addEventListener('mousemove', on_mousemove, false);
				canvas.addEventListener('touchend', on_mouseup, false);
				canvas.addEventListener('touchmove', on_mousemove, false);
				document.body.addEventListener('mouseup', on_mouseup, false);
				document.body.addEventListener('touchend', on_mouseup, false);

				empty = false;
				var xy = get_coords(e);
				context.beginPath();
				pixels.push('moveStart');
				context.moveTo(xy.x, xy.y);
				pixels.push(xy.x, xy.y);
				xyLast = xy;
			};

			function on_mousemove(e, finish) {
				e.preventDefault();
				e.stopPropagation();

				var xy = get_coords(e);
				var xyAdd = {
					x : (xyLast.x + xy.x) / 2,
					y : (xyLast.y + xy.y) / 2
				};

				if (calculate) {
					var xLast = (xyAddLast.x + xyLast.x + xyAdd.x) / 3;
					var yLast = (xyAddLast.y + xyLast.y + xyAdd.y) / 3;
					pixels.push(xLast, yLast);
				} else {
					calculate = true;
				}

				context.quadraticCurveTo(xyLast.x, xyLast.y, xyAdd.x, xyAdd.y);
				pixels.push(xyAdd.x, xyAdd.y);
				context.stroke();
				context.beginPath();
				context.moveTo(xyAdd.x, xyAdd.y);
				xyAddLast = xyAdd;
				xyLast = xy;

			};

			function on_mouseup(e) {
				remove_event_listeners();
				disableSave = false;
				context.stroke();
				pixels.push('e');
				calculate = false;
			};
		}
		canvas.addEventListener('touchstart', on_mousedown, false);
		canvas.addEventListener('mousedown', on_mousedown, false);

	},
	
	
	/***********Download the Signature Pad********************/
	
	saveButton : function(oEvent){
		var canvas = document.getElementById("signature-pad");
		var link = document.createElement('a');
		link.href = canvas.toDataURL('image/jpeg'); 
		link.download = 'sign.jpeg';
		link.click(); 
		var signaturePad = new SignaturePad(document.getElementById('signature-pad'), {
			  backgroundColor: '#ffffff',
			  penColor: 'rgb(0, 0, 0)'
		})
	},
	
	/************Clear Signature Pad**************************/
	
	clearButton : function(oEvent){
		var canvas = document.getElementById("signature-pad");
		var context = canvas.getContext("2d");
		context.clearRect(0, 0, canvas.width, canvas.height);
		
		var signaturePad = new SignaturePad(document.getElementById('signature-pad'), {
			  backgroundColor: '#ffffff',
			  penColor: 'rgb(0, 0, 0)',
			  penWidth : '1'
		})
	}
}

6.   Saving the Signature

I am using HTML attribute tag to download the signature done on signature pad. Save method is defined as a part of controller.

saveButton : function(oEvent){
		var canvas = document.getElementById("signature-pad");
		var link = document.createElement('a');
		link.href = canvas.toDataURL('image/jpeg'); 
		link.download = 'sign.jpeg';
		link.click(); 
		var signaturePad = new SignaturePad(document.getElementById('signature-pad'), {
			  backgroundColor: '#ffffff',
			  penColor: 'rgb(0, 0, 0)'
		})
	}

7.  Scope of Application:

I have built this application as a part of POC and didn’t get chance to use it in any real time environment. This application can be used wherever we need to perform the digital signature on documents etc.

8.   Result Screens:

Before Drawing the Signature

After Drawing the Signature

Screenshot of Saved image (.JPEG format)

Assigned Tags

      15 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Vishal Kumar
      Vishal Kumar

      Great work !!!

      Author's profile photo Mutyala Rao Pasam
      Mutyala Rao Pasam

      Hi Happy Chhillar,

      Nice Blog but touch is not working. I am trying in wed ide.

       

      Thanks&Regards,

      Mutyam.

      Author's profile photo Former Member
      Former Member

      Hi Mutyala Rao,

      Please add the following URL in  the index.html of your application then touch will work

      <script src="https://cdnjs.cloudflare.com/ajax/libs/signature_pad/1.5.3/signature_pad.min.js"></script>

      Regards,
      Sai Ram Dinesh Pallapotu

      Author's profile photo Mutyala Rao Pasam
      Mutyala Rao Pasam

      Hi Former Member,

      thank you for reply add but also not working in touch what is that problem.

       

      Regardfs,

      Mutyam.

      Author's profile photo Lakshmareddy Surapureddy
      Lakshmareddy Surapureddy

      Hi Happy Chhillar,

      Nice Blog it's working fine in eclipse version but in  web ide touch is  not working please give me any suggestion

      Author's profile photo Lakshmareddy Surapureddy
      Lakshmareddy Surapureddy

      it's working fine both web ide and eclipse, but after deployed to Launchpad, sap fiori client in mobile touch events not working can you please give suggestion.

      Author's profile photo Adam Harkus
      Adam Harkus

      This works, but on desktop only.

       

      How can I make it responsive?

      Author's profile photo Raphaël Cellard
      Raphaël Cellard

      Hello,

      There is an issue with this code if your signature pad can move in the screen through a scrolling action. In this case, you can't use it with 'touch' but only with mouse.

      This is due to the fact that the position of the finger on the screen is always determined relative to the screen device itself, not relative to the content of the screen.

      In order to make the signature pad works every time, everywhere, you have to change the coding in the get_coords(e) function:

      Replace :
      var offsety = canvas.offsetTop || 0;
      var offsetx = canvas.offsetLeft || 0;

      By:
      var canvasArea = canvas.getBoundingClientRect();
      var offsety = canvasArea.top || 0;
      var offsetx = canvasArea.left || 0;

      Without this little change, your signature is displayed out of the <canvas> boundaries. Usually in a virtual and invisible area above the screen (y-position < 0).

      Author's profile photo Devisha Bhavik
      Devisha Bhavik

       

      This is very nice blog. I have tried and it worked fine from WebIDE as SAPUI5 application running with index.html.

       

      But, when I tried to add the same code in the another application which I had creating using Fiori Worklist template, drawing is not working.. Looks like, mouse down and other events are not getting recognized and not being triggered. Only Mouse Up event is getting triggered.

      Not sure what could be wrong.

       

      Note: I can see the signature_pad.js and custom control JS files in the developer tools in source section. That means, those files are loaded on the browser. Also, I do not get any errors on the console.

       

      It would be wonderful if someone cracks this issue.

       

      Thanks,

      Bhavik

      Author's profile photo Praseena Nair
      Praseena Nair

       

      Hi Bhavik,

       

      In WebIDE, I created a UI5 application and tried this code. I am unable to view the canvas to sign digitally.

      Did you make any changes to the view/controller?

      I can see the 3rd party JS files loaded in developer tools. I see something as below:

       

      Could you please help?

      Author's profile photo Devisha Bhavik
      Devisha Bhavik

      Hi Praseena,

       

      Please check this question on the forum posted by me. I had provided the answer how it was resolved.

       

      https://answers.sap.com/questions/511353/signature-capture-does-not-work-from-fiori-launchp.html?childToView=511355#answer-511355

       

      Thanks,

      Bhavik

      Author's profile photo Rahul Kurane
      Rahul Kurane

      Hi Happy Chhillar,

      I used this code but got error on web ide-

      Uncaught ReferenceError: on_mousedown is not defined

      controller.js- canvas.addEventListener(‘touchstart’, on_mousedown, true);

       

      Thanks & Regards,

      Rahul

      Author's profile photo Meenakshi Raina
      Meenakshi Raina

      Hi Rahul,

      The placement of addEventListener needs to be corrected here. The error will be removed and the signature can be done and saved.

                          function on_mouseup(e) {
                              remove_event_listeners();
                              disableSave = false;
                              context.stroke();
                              pixels.push('e');
                              calculate = false;
                          };
                          canvas.addEventListener('touchstart', on_mousedown, false);
                          canvas.addEventListener('mousedown', on_mousedown, false);
                      }
      Author's profile photo Pratik Modh
      Pratik Modh

      Happy Chhillar

      Please can share code code on pratik.modh@vsdtechno.com

      Author's profile photo Prasenjit Bera
      Prasenjit Bera

      Hi Happy Chhillar,
      Thank you for this type of document. It is working fine for me.