Laravel - Generate a PDF from a form , including also the user's signature

5.4k views Asked by At

I have a big chalenge for my level.

The title is self explanatory : Generate a PDF from a form , including also the user's signature, using Laravel.

My laravel and general php level is basic. I know how to make a basic blog on laravel (like all guys who have followed laracasts or similar) but this one I find it tough cause I see there are many concepts from different places going on at the same time and I have many gaps of knowledge.

It would be at least very helpful to know which packages are the best ones to do all this. I have been trying with DOMPDF and https://github.com/szimek/signature_pad. But I have read that with DOMPDF I can't use active forms ... I have also checked MPDF.

What I would mainly need is a view , where there is a form , where there is a signature pad for the user to sign after the form , and this, after submitting generates a pdf.

Any starting points on what to read, study, focus ?

Already how to mix the image of the signature, which the script is on js, with the data of the form seems like the everest to me.

What I can't neither imagine is how to deal with the different controllers ..

1

There are 1 answers

1
Namoshek On

Hats off for accepting that you lack the knowledge to do this on your own. It is no shame to ask and I guess it will make your life a lot easier after all as well.

My advice is to split the whole task into suitable sub-tasks that you are able to handle. In my opinion that are:

  1. Create an absolutely normal HTML form that you can submit.
    You'll need one controller with two functions for this. One function will display the form and the other one will handle the submitted data once the form gets submitted.

    class MyFormController
    {
        public function getForm()
        {
            return view('my.form');
        }
    
        public function postForm(Request $request)
        {
            // do something with the form data in $request
        }
    }
    

    I guess you know how to put together a proper HTML form.

  2. Generate the PDF with the submitted form data.
    The way most pdf generator packages of Laravel work is by using a blade template view. For you that is actually quite beneficial, because you already know how to put together an HTML view!

    So if we translate this into code based on the barryvdh/laravel-dompdf package, we get something like this:

    public function postForm(Request $request)
    {
        $pdf = PDF::loadView('my.pdf', [
            'name' => $request->input('name'),
            'address' => $request->input('address'),
            // ... and more data if you like
        ]);
    
        return $pdf->download('signed_form.pdf');
    }
    

    Of course we will also need a blade template. According to the name it will have the path and file name resources/views/my/pdf.blade.php:

    <table>
      <tr>
        <th>Name:</th>
        <td>{{ $name }}</td>
      </tr>
      <tr>
        <th>Address:</th>
        <td>{{ $address }}</td>
      </tr>
    </table>
    
  3. Now, as we do have the form and PDF generation itself, we can go on to the signature.
    To be fair, I've never done anything similar myself so far. But after a very quick search I came across the JavaScript package szimek/signature_pad, which looks incredibly promising. I think the setup is quite self explanatory, but here is what I understood so far:

    • Add the script tag (<script src="...">) given in the documentation to your form view.
    • Add a hidden input field to your form (<input type="hidden" name="sig" id="sig">).
    • Add a <canvas> HTML element to your form view. Give it an identifier: <canvas id="signature">.
    • Add another script tag but with custom JavaScript code below the one you already added. Something like this:

      <script type="text/javascript">
          var canvas = document.getElementById('signature');
          var signaturePad = new SignaturePad(canvas);
      
          function onFormSubmit()
          {
              document.getElementById('sig').value = signaturePad.toDataURL();
          }
      </script>
      
    • You'll now also have to add onsubmit="onFormSubmit()" to your <form ...> tag. What this script does is to first initialize the signature pad but then also to set the value of the hidden input field to the contents of the signature pad.

    • Last thing you'll want to do is to add the submitted sig value to the view that is used to generate the pdf. And in the view itself you'll have to use the submitted sig data in a new image element: <img src="{{ $sig }}">

And if you are lucky, all of what I just wrote straight out of my mind (without any testing anything of it) works right out of the box. If not, you should at least have an idea what the steps are to achieve your goal.

By the way, of course you can make all the views look fancy. But be aware that PDFs cannot display as much information as HTML can. So you will definitely lose information and styling at some points when you convert a view to pdf.