Atozed Forums

Full Version: Using jSignature in Intraweb and storing the signature data in an async event
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I am integrating https://github.com/brinley/jSignature to make a signature in a html page.
It's to sign a work order by a customer much like parcel delivery services uses it.

Integrating and using the library works. Now I would like to store the signature data in the database. For this I need to send the signature data to the server. First idea was to use

Code:
function sendSignature() {
  var $sigdiv = $('#signature');
 
  var signatureData = $sigdiv.jSignature("getData");
  ajaxCall("StoreSignature", "&signature="+signatureData, false);
}

The url gets too long this way. Long question short: How do I get the signature data to the server? Can I POST the data? Is there some example for this?

PS I don't mean to get the data in a compressed format like image/jSignature;base30, another export format.
Well posting my solution for anyone interested:

Create a hidden field to hold the signature data.

Code:
constructor TDlgSignature.Create(AOwner: TComponent);
begin
  inherited;
  // will be used to transfer the signature content
  HiddenFields.AddPair('signature', '');
end;

Register a callback that is called when storing the signature

Code:
RegisterCallBack('StoreSignature', StoreSignature);

Client side calls a JavaScript function to prepare the signature and send it to the server

Code:
function sendSignature() {
  var $sigdiv = $('#signature');
  var signatureData = $sigdiv.jSignature("getData");

  document.getElementById("HIDDEN_signature").value = signatureData;
  AddChangedControl("signature");
  ajaxNotify("StoreSignature");
}

$(document).ready(function(){
  // This is the part where jSignature is initialized.
  $('#signature').jSignature();
  $('#BTNSIGN').click(sendSignature);
});

Because the ‘signature’ control is marked as changed, Intraweb will perform a HTTP POST including the changed control value. 

In the callback on the server side you can read TIWForm.HiddenFields again and use the passed signatureData from the client.

Code:
procedure TDlgSignature.StoreSignature(EventParams: TStringList);
var
  FormatSignature: string;
  PngImage: TPngImage;
  StrStream: TStream;
  MemStream: TStream;
  Signature: string;
begin
  Signature := HiddenFields.Values['signature'];

  FormatSignature := 'data:image/png;base64,';
  if Signature.StartsWith(FormatSignature)
  then begin
    Delete(Signature, 1, Length(FormatSignature));

    PngImage := TPngImage.Create;
    MemStream := TMemoryStream.Create;
    StrStream := TStringStream.Create(Signature);
    try
      TNetEncoding.Base64.Decode(StrStream, MemStream);
      MemStream.Position := 0;
      PngImage.LoadFromStream(MemStream);
      IWImage1.Picture.Graphic := PngImage;
    finally
      StrStream.Free;
      MemStream.Free;
      PngImage.Free;
    end;
  end;
end;
Thanks for posting what you found. I haven't used that but it looks interesting enough to play with!

Dan
Hi Jeroen,

ServerController.SecurityOptions.ForceAjaxPost := True;

This will force Ajax POST instead of GET. Shouldn't affect anything else.

Some "security consultants" consider POST safer than GET. Although under HTTPS, both POST and GET parameters are protected.