0

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();
             }
           });
Micha
  • 383
  • 3
  • 14
  • Try adding this to your
    tag. enctype="multipart/form-data". See here for further info https://stackoverflow.com/questions/4526273/what-does-enctype-multipart-form-data-mean
    – bumperbox Feb 11 '18 at 06:58

2 Answers2

1

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.

Micha
  • 383
  • 3
  • 14
0

Please try file_uploads = On in php.ini file of your project.

Pratik Khadka
  • 908
  • 8
  • 20
  • file_uploads is already set to on. It was one of the first things checked – Micha Feb 11 '18 at 06:08
  • Ok, Then try adding file = true in your form tag your code looks fine . – Pratik Khadka Feb 11 '18 at 06:13
  • I'm not familiar with the "file" attribute for the
    tag unless you may be referring to something else possibly?
    – Micha Feb 11 '18 at 06:22
  • No it hasnt been solved Pratik. The js is correct and is generating a data string when i put an alert to test on submission. this string is used in a test variable to see if the php writes the it to a file and that works too. what is happening now is when i submit the form sending the data string the browser gets a connection reset error. the data string isnt even getting to the php code. it has been a nightmare to to figure out what is happening – Micha Feb 12 '18 at 08:49
  • Hello @Micha I know its really late to ask this you probably have finished the project by now .But I just want to know about the issue. It might help me figure out things in future :D – Pratik Khadka Mar 22 '18 at 05:10
  • Yes it is done. Here is what fixed the issue. Before submitting the `dataURL()` i trimmed off base64,image/jpg at the beginning of the string. I came to this conclusion during testing as all other submittions where working fine. The original code of mine was correct. Just a simple trim before submittion was all. I will post the final code as an answer to the question – Micha Mar 23 '18 at 05:55
  • I elaborated on the code I used a little to help you. If this works for you Pratik mark the answer as correct. – Micha Mar 23 '18 at 06:42
  • I actually work on laravel frame works so I dont face much issue related .I was just curious about your problem . Cheees – Pratik Khadka Mar 23 '18 at 07:12