title: CANVAS drawing and toDataURL()
body: <p>I am trying to implement <a href="https://github.com/szimek/signature_pad" rel="nofollow">this signature pad plugin</a> into my ColdFusion application. However, I am struggling on figuring out how to set my canvas drawing to a ColdFusion variable using the <code>todataURL()</code> funtion. </p>
  
  <p>From what I can tell, the JS plugin has a <code>toDataURL()</code> function that converts the image into a base64 string. My JS knowledge is lacking and I cannot wrap my head around how I can set a ColdFusion form variable to this base64 string to use on my action page. </p>
  
  <p>What I believe would work in this scenario is to grab the base64 image on my action page, using the built-in <code>toDataURL()</code>. Then convert it to an actual image and save it using ColdFusion's <code>ImageReadBase64()</code> function.</p>
  
  <p>Here is my form with my canvas element:</p>
  
  <pre><code>&lt;form action="signature_action.cfm?  ticketID=#url.ticketID#&amp;TT=#url.TT#&amp;techID=#url.techID#&amp;device=ipad" method="post" NAME="SigForm" id="SigForm"&gt;
  &lt;div id="body" &gt;
  &lt;div id="signature-pad" class="m-signature-pad"&gt;
     &lt;div id="format" align="center" style=" padding-bottom: 15px; margin-top:5px;"&gt;
        &lt;input class="check1" type="checkbox" id="check1" name="equipment_dropped_off" value="equipment_dropped_off"/&gt;
        &lt;label for="check1"&gt;&lt;span class="style1"&gt;Equipment Dropped Off &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/label&gt;
        &lt;span class="style1"&gt;                                
        &lt;input class="check2" type="checkbox" id="check2" name="work" value="work"/&gt;
        &lt;label for="check2"&gt;Work performed &amp;nbsp; &amp;nbsp; &lt;/label&gt;
        &lt;input class="check3" id="check3" type="checkbox" name="payment" value="payment" /&gt;
        &lt;label for="check3"&gt;Payment Recieved &amp;nbsp; &amp;nbsp; &lt;/label&gt;
        &lt;input class="check4" name="equipment_picked_up" id="check4" type="checkbox" value="equipment_picked_up" /&gt;
        &lt;label for="check4"&gt;Equipment Picked Up&lt;/label&gt;
        &lt;/span&gt;&lt;br /&gt;
        &lt;input name="tech_name" type="hidden" value="#url.tech_name#"&gt;
     &lt;/div&gt;
     &lt;div class="m-signature-pad--body"&gt;
        &lt;canvas id="canvas"&gt;&lt;/canvas&gt;
     &lt;/div&gt;
     &lt;div class="m-signature-pad--footer"&gt;
        &lt;div class="description"&gt;Sign above&lt;/div&gt;
        &lt;button type="button" class="button clear" data-action="clear"&gt;Clear&lt;/button&gt;
        &lt;input class="button save" type="submit" id="submit" name="submit" class='btn-style-mobile' value="Click Here To Accept Signature" disabled&gt; 
     &lt;/div&gt;
  &lt;/div&gt;
  &lt;script src="../scripts/signature_pad.js"&gt;&lt;/script&gt;
  &lt;script src="../scripts/app.js"&gt;&lt;/scrip&gt;
  &lt;/div&gt;   
  &lt;/form&gt;
  </code></pre>
  
  <p>Here is my attempt to set my hidden form field to the base64 image:</p>
  
  <pre><code>// JavaScript Document
  var wrapper = document.getElementById("signature-pad"),
  clearButton = wrapper.querySelector("[data-action=clear]"),
  saveButton = document.getElementById('submit'),
  canvas = wrapper.querySelector("canvas"),
  signaturePad;
  
  // Adjust canvas coordinate space taking into account pixel ratio,
  // to make it look crisp on mobile devices.
  // This also causes canvas to be cleared.
  function resizeCanvas() {
     // When zoomed out to less than 100%, for some very strange reason,
     // some browsers report devicePixelRatio as less than 1
     // and only part of the canvas is cleared then.
     var ratio =  Math.max(window.devicePixelRatio || 1, 1);
     canvas.width = canvas.offsetWidth * ratio;
     canvas.height = canvas.offsetHeight * ratio;
     canvas.getContext("2d").scale(ratio, ratio);
  }
  
  window.onresize = resizeCanvas;
  resizeCanvas();
  
  signaturePad = new SignaturePad(canvas);
  
  clearButton.addEventListener("click", function (event) {
     signaturePad.clear();
  });
  
  saveButton.addEventListener("click", function (event) {
     if (signaturePad.isEmpty()) {
         alert("Please provide signature first.");
     } else {
         window.open(signaturePad.toDataURL());
         //document.getElementById('base64').value = 'signaturePad.toDataURL()';
     }
  });
  </code></pre>
  
  <p>In the example code on Github, they have the form submit button outputting the drawing to a new browser window using the following javascript:</p>
  
  <pre><code>saveButton.addEventListener("click", function (event) {
     if (signaturePad.isEmpty()) {
         alert("Please provide signature first.");
     } else {
         window.open(signaturePad.toDataURL());
     }
  });
  </code></pre>
  
  <p>I think I should be able to use this similar JS code to set a hidden form variable to <code>signaturePad.toDataURL()</code> and then use CFIMAGE and <code>ImageReadBase64</code> on my action page to create an actual image from that, correct? Or is there a batter way to do this?</p>
  
  <p>Can anyone she some light on how this process should work? </p>
  
  <p>===========================================================
  UPDATE: Working JS Code:</p>
  
  <pre><code>    // JavaScript Document
  var wrapper = document.getElementById("signature-pad"),
      clearButton = wrapper.querySelector("[data-action=clear]"),
      saveButton = document.getElementById('submit'),
      canvas = wrapper.querySelector("canvas"),
      signaturePad;
  
  // Adjust canvas coordinate space taking into account pixel ratio,
  // to make it look crisp on mobile devices.
  // This also causes canvas to be cleared.
  function resizeCanvas() {
      // When zoomed out to less than 100%, for some very strange reason,
      // some browsers report devicePixelRatio as less than 1
      // and only part of the canvas is cleared then.
      var ratio =  Math.max(window.devicePixelRatio || 1, 1);
      canvas.width = canvas.offsetWidth * ratio;
      canvas.height = canvas.offsetHeight * ratio;
      canvas.getContext("2d").scale(ratio, ratio);
  }
  
  window.onresize = resizeCanvas;
  resizeCanvas();
  
  signaturePad = new SignaturePad(canvas);
  
  clearButton.addEventListener("click", function (event) {
      signaturePad.clear();
  });
  
      saveButton.addEventListener("click", function (event) {
      if (signaturePad.isEmpty()) {
          alert("Please provide signature first.");
      } else {
          //window.open(signaturePad.toDataURL());
          document.getElementById('base64').value = signaturePad.toDataURL();
      }
      });
  </code></pre>
  
  <p>Here is my working ActionPage code:</p>
  
  <pre><code>&lt;!---write image to file and disk ---&gt;  
      &lt;cfset imageData = #form.base64#&gt;
      &lt;cfoutput&gt;#form.base64#&lt;/cfoutput&gt;
      &lt;cfset myImage = ImageReadBase64("#form.base64#")&gt; 
      &lt;cfimage
      action="write"
      destination="C:\Inetpub\wwwroot\signatures\#fullfilename#.png"
      source="#myImage#"
      overwrite="yes"
      isBase64="yes"
      style="border: 3px dashed ##000000 ;"
      /&gt;
  </code></pre>