javascriptphptodataurlsignaturepad

Code looks fine however form submittion is not posting <canvas> to php


I have a signature pad on a php document. Everything works until I hit submit. A .png is getting written to the server however the file is unreadable and 0kb meaning there is no data. My guess is the image is not being sent correctly from the canvas and or being sent by POST for my php to catch and deal with as necessary. Any help would be appreciated. I am not the strongest when it come to javascript by any means. The signature_pad.js is to launch the signature pad to the canvas which again is working fine and the app.js contains the functions for the clear button and submit button on the form. I included the code for the app.js. I edit the app.js to send the to a hidden field so i can pick the png/canvas data up in php and save it to a server and deal with it accordingly. In my php I has used var_dump() after the hidden field has been picked up with $_POST and it just shows string(0) meaning just empty. I have set an alert in the js upon clicking on submit to see if the data string is even there as well and it is. I am stumped as to where the data is being lost.

UPDATE So the further I have dug into this it is a problem with the form using POST. Both the js and php elements work fine, however once the form is submitted everything just hangs until a connection reset error kicks out in the browser. I have spent the past day or so trying to track down what is going on and having no luck so far.

            <?php
            if (isset($_POST['GetImage'])) {

        define('UPLOAD_DIR', 'PDF_Docs/HomeownerAgreements/SigImages/');
        $img = $_POST['SaveSig'];
        $img = str_replace('data:image/png;base64,', '', $img);
        $img = str_replace(' ', '+', $img);
        $data = base64_decode($img);
        $file = UPLOAD_DIR . uniqid() . '.png';
    file_put_contents($file, $data);

             exit;
             ?>
             <html><body>
             <form id="form1" class="default-form" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']);?>" method="post">
         <input type="hidden" name="SaveSig" value="" id="SaveSig">
             <input type="hidden" name="GetImage" value="Yes" id="GetImage">
             <!-- SIGNATURE PAD : begin -->
             <div id="signature-pad" class="m-signature-pad">
             <div class="m-signature-pad--body">
             <div class="description">Sign Below</div>
             <canvas id="signature" width="750" height="150" style="border:1px solid #000000;"></canvas>
             </div>
             <div class="m-signature-pad--footer">
             <div class="form-field">
             <button type="button" class="button clear c-button" data-action="clear">Clear Signature</button></div>
             </div>                           
             <!-- SIGNATURE PAD : end -->
    <!-- SUBMIT BUTTON : begin -->
    <div class="form-field">
    <button class="submit-btn c-button" type="submit" data-label="Send Message" data-loading-label="Sending..." data-action="send-form">Submit</button>
    </div>
            <!-- SUBMIT BUTTON : end -->
    </div>
    </div>
    <p>&nbsp;</p>
    </form>
    <!-- CONTACT FORM : end -->
    <!-- SIGNATURE PAD JS : begin --> 
           <script src="SigPad/js/signature_pad.js"></script>
           <script src="SigPad/js/app.js"></script>
    <!-- SIGNATURE PAD JS : end -->
            </body></html>

And the app.js file contains this code:

           var wrapper = document.getElementById("signature-pad");
           var clearButton = wrapper.querySelector("[data-action=clear]");
           var sendFormButton = wrapper.querySelector("[data-action=send-form]");
           var canvas = wrapper.querySelector("canvas");
           var signaturePad = new SignaturePad(canvas);

           clearButton.addEventListener("click", function (event) {
           signaturePad.clear();
           });                 

           sendFormButton.addEventListener("click", function (event) {
       if (signaturePad.isEmpty()) {
        alert("Please provide signature first.");
           } else {
           document.getElementById('SaveSig').value = canvas.toDataURL('image/png');
           document.forms["form1"].submit();
             }
           });

Solution

  • Here is what fixed my issue. I came to the conclusion that i needed to remove data:image/png;base64, from the dataURL() string before sending as all other text string would send fine. Use split() to remove the image encoding and all is good. I also save the string to a hidden field in the form called "Image" and then using ajax to submit the entire contents of the form. Works flawlessly.

    //CONVERT IMAGE TO DATA URL AND
    //REMOVE data:image/png;base64, FROM STRING
    var GetImage = canvas.toDataURL();
    console.log(GetImage);
    var pngImg = GetImage.split(',')[1]; //THIS WAS WHAT FIXED IT
    
    //PUT DATA URL STRING IN 'IMAGE' HIDDEN FIELD
    document.getElementById('Image').value = pngImg;
    
    //Now send the HIDDEN "Image" FIELD USING AJAX
    

    Here is the PHP code to retrieve the image string and deal with it by saving it to a server directory

    $FileDate = date("m-d-Y", time());
    $FileName = "Your File Name";    
    
    $img = $_POST['Image'];
    
    //UPLOAD DIRECTORY FOR IMAGE
    $upload_dir = "Your Directory On Server Here";
    
    $DecodedImg = base64_decode($img);
    
    //NAME THE IMAGE
    $ImgFile = $FileName . '_' . $FileDate . ".png";
    
    //SAVE THE FILE TO THE SERVER
    $success = file_put_contents($upload_dir.$ImgFile, $DecodedImg);
    

    I hope this helps someone as I had a real pain as this was never explained to me and caused a lot of time spent figuring it out. Happy coding.