Skip to Content

Hi all,

Recently I have got a requirement in which I need to display the captured digital signature in editable mode.

SVG is is a graphic container element in HTML which stands for Scalable Vector Graphics. It used for defining graphics for the web.

Earlier we used to capture and display signatures using Canvas. But I found it is better opting for SVG rather than going for Canvas for my requirement after going through many links. I also came know that when ever we need to make a change in Canvas we need to redraw the entire scene. The main advantage of SVG is it is scalable and it supports event handlers.

Firstly I have created an OData service to get and create an entity.

The logic for get entity operation: 

DATA: lt_keys       TYPE /iwbep/t_mgw_tech_pairs,
      ls_key        TYPE /iwbep/s_mgw_tech_pair,
      LV_name TYPE char20.

   lt_keys = io_tech_request_context->get_keys( ). //Get key elements
**Reading key properties
                                INTO ls_key.
***Setting key value to a local variable
   lv_name = ls_key-value.
***Retrieving data
  SELECT SINGLE * from ztsvg_signature into ER_ENTITY WHERE Name = lv_name.

Create operation:

Logic is as follows:

DATA: wsvg_signature TYPE ztsvg_signature.
**Read request data

ER_ENTITY-Name   = wsvg_signature-Name.
ER_ENTITY-SIGNURL  = wsvg_signature-SIGNURL.

INSERT ztsvg_signature FROM ER_ENTITY.

In order to create an entity, perform get to read a single entity and click on use as request to perform post operation.

Create the entity as highlighted in the HTTP Request and select HTTP method as Post. Click on execute

Custom Controller: 

In the custom controller, we are providing meta data to create a signature pad, its properties to capture mouse movement and the functions to get, set and clear signature details. The logic is as follows."com.finalcanvasFinal.controller.SignaturePad");
sap.ui.core.Control.extend("com.finalcanvasFinal.controller.SignaturePad", {	
  metadata: {
      properties: {
        width: {type: 'int', defaultValue: 300},
        height: {type: 'int', defaultValue: 100},
        bgcolor: {type: 'string', defaultValue: '#ffa'},
        lineColor: {type: 'string', defaultValue: '#666'},
        penColor: {type: 'string', defaultValue: '#333'},
        signature: 'string'
    renderer: function(oRm, oControl) {
      var bgColor = oControl.getBgcolor();
      var lineColor = oControl.getLineColor();
      var pen = oControl.getPenColor();
      var id = oControl.getId();
      var w = oControl.getWidth();
      var h = oControl.getHeight();
      oRm.write('<svg xmlns="" width="' + w +
                '" height="' + h + '" viewBox="0 0 ' + w + ' ' + h + '">');
      oRm.write('<rect id="' + id  + '_r" width="' + w + '" height="' + h + 
                '" fill="' + bgColor  + '"/>');
      var hh = h - 20;
      oRm.write('<line x1="0" y1="' + hh  + '" x2="' + w + '" y2="' + hh + 
                '" stroke="' + lineColor + 
                '" stroke-width="1" stroke-dasharray="3" ' + 
                'shape-rendering="crispEdges" pointer-events="none"/>');
      oRm.write('<path id="' + id + '_p" stroke="' + pen + '" stroke-width="2" ' +
                'fill="none" pointer-events="none"/>');
    clear: function() {
    	var that = this;
      that.signaturePath = '';
      var p = document.getElementById(that.getId() + '_p');
      p.setAttribute('d', '');

    onAfterRendering: function() {
      var that = this;
      that.signaturePath ='';
      isDown = false;
      var elm = that.$()[0];
      var r = document.getElementById(that.getId() + '_r');
      var p = document.getElementById(that.getId() + '_p');

      function isTouchEvent(e) {
        return e.type.match(/^touch/);

      function getCoords(e) {
        if (isTouchEvent(e)) {
          return e.targetTouches[0].clientX + ',' +
        return e.clientX + ',' + e.clientY;

      function down(e) {
        that.signaturePath += 'M' + getCoords(e) + ' ';
        p.setAttribute('d', that.signaturePath);
        isDown = true;
        if (isTouchEvent(e)) e.preventDefault();

      function move(e) {
        if (isDown) {
          that.signaturePath += 'L' + getCoords(e) + ' ';
          p.setAttribute('d', that.signaturePath);
        if (isTouchEvent(e)) e.preventDefault();

      function up(e) {
        isDown = false; 
        if (isTouchEvent(e)) e.preventDefault();

      r.addEventListener('mousedown', down, false);
      r.addEventListener('mousemove', move, false);
      r.addEventListener('mouseup', up, false);
      r.addEventListener('touchstart', down, false);
      r.addEventListener('touchmove', move, false);
      r.addEventListener('touchend', up, false);
      r.addEventListener('mouseout', up, false);
     //To get signature path 
       if (this.getSignature()) {
        this.signaturePath = this.getSignature();
        var p = document.getElementById(this.getId() + '_p');
        if (p) {
          p.setAttribute('d', this.signaturePath);
      // to set signature path to the signaturepad to display
       that.setSignature = function(s) {
        that.setProperty('signature', s);


Controller Logic:

Here I have accessed the custom controller to load all the metadata to create SVG Container and all the functions necessary to draw SVG graphics.

I have created an instance for signature pad and all other UI elements like buttons and input field for name,.

//Global variables
var prevSignature;
var isDown;
], function(Controller, SignaturePad) {
	"use strict";

	return Controller.extend("com.finalcanvasFinal.controller.View1", {
		onInit: function() {
		//instance for signature pad	
			var oCtrl = new SignaturePad({
				id: "signPad",
				width: 400,
				height: 200
		//Adding signature pad to page content
			var content = this.byId("signEdit");
			var that = this;
		//Input field for Name	
			var textField = new sap.m.Input({
				id: "nameValue",
				width: '10rem',
				placeholder: 'Name'

		//Clear button	to clear signaturePad
			var clearButton = (new sap.m.Button({
				text: 'Clear',
				press: function() {
					sap.ui.getCore().byId("nameValue").setValue(" ");
		//Accept button to save data in backend
			var acceptButton = (new sap.m.Button({
				text: 'Save',
				press: function() {
					var signaturePath = oCtrl.getSignature(); 
					if (signaturePath !== ' ') {

						var oEntry = {}; // instantiating the object
						oEntry.Name = sap.ui.getCore().byId("nameValue").getValue();	//Name
						oEntry.Signurl = signaturePath;									//SVG path
						var sServiceUrl = "/sap/opu/odata/sap/ZSVG_SIGNATURES_SRV/";
						var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl, false);
						oModel.create("/SigntureSet()", oEntry, null, function(response) {"Success! Data is saved");
						}, function(error) {"Error!");


			// Adding display button
			var Display = new sap.m.Button({
				text: 'Display',
				enabled: true,
				// Displaying signature based on input		
				press: function() {
					var Name = sap.ui.getCore().byId("nameValue").getValue(); //getting input value

					var sServiceUrl = "/sap/opu/odata/sap/ZSVG_SIGNATURES_SRV/";
					var oModel = new sap.ui.model.odata.ODataModel(sServiceUrl, false);
					//reading details based on name"/SigntureSet(Name='" + Name + "')", null, null, false, function(oData, oResponse) {
						prevSignature = oData.Signurl;
						//Calling set signatuer method from custom controller


My view looks as follows:

When a name and signature is provided and hit save, the name and SVG path will get saved to the backend system.

In order to display the signature provide the name and click on display. The result is as follows.

Thank you..!! 🙂 🙂



To report this post you need to login first.

1 Comment

You must be Logged on to comment or reply to a post.

  1. Prabhakaran Palanisamy

    That’s one interesting topic! Thanks for sharing.

    Is this signature captured through FIRST PHONES/ Pin Pad?  (or)

    What is the phone or touch device through which this signature is captured?


    Kind Regards,



Leave a Reply