#44 Capturing Signatures with Signature Pad


Using the Javascript Library, Signature Pad, learn how to capture user signatures and store them within your Ruby on Rails application.
rails javascript view 8:14


application.js.erb//= require signature_pad
signature.jsfunction resizeCanvas(canvas) {
    var ratio =  Math.max(window.devicePixelRatio || 1, 1);
    canvas.width = canvas.offsetWidth * ratio;
    canvas.height = canvas.offsetHeight * ratio;
    canvas.getContext("2d").scale(ratio, ratio);

$(document).on('turbolinks:load', function() {
  var canvas = document.querySelector("canvas");
  if (canvas){
    canvas.height = canvas.offsetHeight;
    canvas.width = canvas.offsetWidth;
    window.onresize = resizeCanvas(canvas);
    signature_pad = new SignaturePad(canvas);
    $('.signature_pad_clear').click(function() { signature_pad.clear() });
    $('.signature_pad_save').click(function(event) { 
      if (signature_pad.isEmpty()){
        alert('You must sign to accept the Terms and Conditions');
      } else {
application.css.signature_pad {
  width: 700px;
  height: 400px;
  margin: 0 auto;

.signature_pad_body canvas {
  width: 100%;
  height: 100%;
  border: dotted #444;
  background: #CCCCCC;
application_controller.rbclass ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :verify_terms_acceptance 


  def verify_terms_acceptance
    unless user_signed_in? && current_user.document
      redirect_to new_document_path, alert: 'You must first accept terms and conditions before performing any actions.'
documents_controller.rbclass DocumentsController < ApplicationController
  before_action :authenticate_user!
  skip_before_action :verify_terms_acceptance

  def new
    @document = current_user.build_document

  def create
    @document = current_user.build_document(document_params)
    @document.signed_on = DateTime.now
    if @document.save
      redirect_to root_url, notice: 'Terms and Conditions accepted.'
      render :new


    def document_params

On controllers and/or specific actions which should not require the user to accept the Terms and Conditions, make sure that you add

controllerskip_before_action :verify_terms_acceptance

Adding this override should also apply to the authentication controllers.


<%= simple_form_for @document do |f| %>   <%= f.input_field :signature, as: :hidden, class: 'signature_pad_input' %>   <div class="signature_pad text-center">     <div class="signature_pad_body">       <canvas></canvas>     </div>     <div class="signature_pad_footer">       <div class="text-muted">Sign above</div>       <button type="button" class="btn btn-default signature_pad_clear">Clear</button>       <%= f.button :submit, 'Save', class: 'btn btn-success signature_pad_save'  %>     </div>   </div> <% end %>

visitors/private_content.html.erb<%= image_tag current_user.document.signature %>

RailsCod3rFuture said 9 months ago:

Greetings, I enjoyed watching your tutorial on signature pad. What I was wondering is how do you convert the signature into a PNG and store it alongside the form? I found some code below, but I was wondering if you had a better solution that I can use or is this good enough? Since I am running a SaaS company, I need the optimal way of implementing this feature. If possible, can you post the solution in the comments? Thank you

Controller File

@yourmodel.signature = tempfileend
  input.puts instructions
Open3.popen3("convert -size 600x100 xc:transparent -stroke blue -draw @- #{tempfile.path}") do |input, output, error|
tempfile = Tempfile.new(["signature", '.png'])
instructions = JSON.parse(params[:output]).map { |h| "line #{h['mx'].to_i},#{h['my'].to_i} #{h['lx'].to_i},#{h['ly'].to_i}" } * ' '


rails generate uploader Signature

mount_uploader :signature, SignatureUploader

kobaltz PRO said 9 months ago:

It really depends on the situation. I wouldn't necessarily jump to converting the signature over to an image and store it separately (more so than it already is). If you will be displaying the signature often, you could look into Fragment Caching as a possible solution for the areas where you're displaying the image. Converting and storing the signature as an image seems like unnecessary overhead as well as an added complication.

However, if this is the route you need, you could create an attr_accessor for the signature and convert it to an image and upload it like you're describing.

frank004 said 5 months ago:

Will love to see a converting signature and  store it like a img

Login to Comment