Unterschriftenfeld in HTML-Formular

Dank dem Canvas-Element sind komplexe Zeichnungen und Zeichenfunktionen in HTML-Seiten möglich. Für Formulare ergeben sich somit neue Möglichkeiten, wie die Umsetzung einer Unterschriftenfunktion.

In unserem Beispiel wollen wir ein Formular erstellen, welches dem Benutzer erlaubt eine Unterschrift (oder jede beliebige andere Zeichnung) zu erstellen. Wahlweise mit Maus oder auf mobilen Geräten mit Touch-Funktionen.

Das Formular wird anschließend von einem PHP-Script verarbeitet. Unser Beispiel wird so aussehen:


Software zum Erstellen eines Unterschriftenfeld
Wie man bereits am Screenshot sehen kann, wollen wir das Rad nicht komplett neu erfinden, sondern verwenden eine Open-Source-Komponente für die Basisfunktionen. Die Komponente verwendet unterschiedliche Strichstärken beim Zeichnen, so dass der Eindruck eines echten Stiftes bzw. Unterschrift entsteht.

Legen wir los. Das gesamte Beispiel gibt es am Ende als Download. Im ersten Schritt legen wir uns eine HTML-Datei an. Dort fügen wir kurz dem schließenden Body-Tag die Java-Script Bibliothek für die Unterschrift ein:

<script src="signature_pad.js"></script>

Anschließend definieren wir in unserem Formular die Elemente für unter Unterschriftenfeld:

<div id="signature-pad" class="m-signature-pad">
    <div class="m-signature-pad--body">
        <canvas></canvas>
        <input type="hidden" name="signature" id="signature" value="">
    </div>
</div>

Wir sehen hier ein leeres Canvas, welches später mal unser Unterschriftfeld realisieren wird. Auch ein verstecktes Formularfeld, dieses verwenden wir zum übermitteln der Daten an unser PHP-Script.

Für die Festlegung unseres Designs verwenden wir etwas CSS-Code:

<style type="text/css">
    .m-signature-pad--body canvas {
        position: relative;
        left: 0;
        top: 0;
        width: 100%;
        height: 250px;
        border: 1px solid #CCCCCC;
    }
</style>

Hier können wir Breite, Höhe und Rahmenfarbe festlegen. Nun müssen wir das Canvas noch mit den entsprechenden Funktionen verdrahten:

var wrapper = document.getElementById("signature-pad"),
    canvas = wrapper.querySelector("canvas"),
    signaturePad;

var signaturePad = new SignaturePad(canvas);
signaturePad.minWidth = 1; //minimale Breite des Stiftes
signaturePad.maxWidth = 5; //maximale Breite des Stiftes
signaturePad.penColor = "#000000"; //Stiftfarbe
signaturePad.backgroundColor = "#FFFFFF"; //Hintergrundfarbe

Dies verbindet unser Canvas mit dem Java-Script der Komponente und erlaubt nun ein Zeichnen in den Canvas. Außerdem können wir gleich verschiedene Eigenschaften, wie Farben, Stiftstärken und Hintergrundfarbe festlegen.

Nun funktioniert das Zeichnen schon mal, reagiert aber nicht optimal auf Größenänderungen des Browsers. Daher müssen wir die Behandlung von Größenänderungen des Browsers noch implementieren:

function resizeCanvas() {
    var oldContent = signaturePad.toData();
    var ratio = Math.max(window.devicePixelRatio || 1, 1);
    canvas.width = canvas.offsetWidth * ratio;
    canvas.height = canvas.offsetHeight * ratio;
    canvas.getContext("2d").scale(ratio, ratio);
    signaturePad.clear();
    signaturePad.fromData(oldContent);
}

Diese Funktion weisen wir dem Event des Browserfensters zu und rufen die Methode auch gleich beim ersten Aufruf einmal auf:

window.onresize = resizeCanvas;
resizeCanvas();

Wozu das Ganze? Bei Größenänderungen des Browsers verändert sich der Inhalt des Canvas, wird u.U. sogar gelöscht, gestaucht etc. Daher speichern wir den Originalinhalt, ermitteln die neue Größe und setzen den alten Inhalt in das vergrößerte oder verkleinerte Canvas.

Was nun noch fehlt ist die Übermittlung der Unterschrift an ein verarbeitendes PHP-Script. Das Canvas-Element wird nicht übertragen, wenn man das Formular abschickt. Daher speichern wir den Inhalt im Data-URL-Format in das versteckte Feld:

function submitForm() {
    //Unterschrift in verstecktes Feld übernehmen
    document.getElementById('signature').value = signaturePad.toDataURL();
}

Die Komponente hat praktischerweise eine Funktion, mit welcher wir den Bildinhalt direkt als Data-URL zurückbekommen. Diese Funktion müssen wir nun noch vor dem Versand des Formulars aufrufen, dies können über das Entsprechende Event des Formulars erledigen:

<form class="w3-container" action="process.php" method="POST" 
name="DAFORM" onSubmit="submitForm();" enctype="multipart/form-data" target="_self">

Fertig. Beim Absenden wir die Unterschrift, bzw. das Bild im ASCII-Format in das versteckte Feld gespeichert. Dort finden wir im PHP-Script dann z.B. folgenden Inhalt vor:

data:image/png;base64,iVBORw0KGgoAAAAN…

Der Vorteil des Data-URL-Formats? Nun wir können den Inhalt direkt verwenden um das Bild in einem Image-Tag darzustellen:

<img src="data:image/png;base64,iVBORw0KGgoAAAAN...">

Dies machen wir uns nun auch im PHP-Script zu nutze. Hier lesen wir einfach die POST-Variable des Formulars aus und geben das Bild aus:

$image = "";
if (isset($_POST["signature"]))
{
    $image = $_POST["signature"];
    echo "";
} else {
    echo "

Kein Bild übertragen

"; }

Das Ergebnis:

Und schon haben wir ein Formular mit Unterschriften- bzw. Zeichenfunktion erstellt. Im Beispiel finden Sie noch die Möglichkeit das Feld mit einem Button zu löschen, sowie das Bild direkt im Browser als Bild herunter zu laden.

Download des Beispiels

Das komplette Beispiel gibt es hier. Download der Orignalkomponente auf Github.

Integration im DA-FormMaker

Noch ein Tipp, wem das Ganze zu viel Handarbeit ist: Die gesamte Funktionalität von Zeichnung- bzw. Unterschriftenfeld befindet sich bereits fertig integriert in unserer Software DA-FormMaker und DA-BestellFormular. Den Formularen können beliebig viele Unterschriftenfelder hinzugefügt werden. Die Konfiguration von Farben, Design, Größe werden direkt in der Software vorgenommen. Auch Überprüfungen auf leere Felder sind möglich:

Der Code wird automatisch generiert und Formular mit Unterschriftenfeld sind sofort einsetzbar. Wird das Formular abgeschickt, wird die Unterschrift inline in der HTML-E-Mail angezeigt. Zusätzlich wird die Zeichnung als PNG-Datei im Anhang eingefügt.

19 Kommentare

  1. Hallo Andy,

    vielen Dank für die ausführliche Beschreibung, das Tutorial und den Beispiel-Download.
    Es funktioniert auch alles einwandfrei….
    außer… das abspeichern der Unterschrift im IE 11 und auf iOS-Geräten.

    Habe Sie diese Problem auch? oder Wissen Sie dafür eine Lösung?

    Vielen Dank.
    LG
    Fabian

    1. Hallo Fabian,
      leider habe ich dafür keine Lösung. Der IE11 ist ja eher ein Auslaufmodell und da läuft vieles an neuen Schnickschnack nicht. Apple ist auch so ein Thema für sich. Habe leider kein IOS um das überhaupt zu testen.

      Gruß
      Andy

  2. Hallo Andy,
    Das Beispiel funktioniert ausgezeichnet. Jetzt habe ich das Problem, dass ich das „entstandene“ Bild beim Speichern nicht im Download-Ordner brauch, sondern in meiner Mysql Datenbank ablegen muß. Gibt es dafür eine nicht zu komplizierte Lösung? Leider habe ich bisher nichts dazu gefunden.
    Vielen Dank schon mal für Deine Mühe
    Detlef

  3. Gibt es die Möglichkeit eine Validierung einzubauen?
    Ich würde schon gerne überprüfen ob eine Unterschrift eingefügt worden ist und nicht nur ein leeres Feld.

    1. Hallo,

      ja das geht, unsere Software DA-FormMaker bietet dies auch an. Vielleicht einfach die Software herunterladen und schauen, wie es dort gemacht wird, die Kurzantwort:

      if (signaturePad0.isEmpty()) {
      alert(„Please enter a value in the field Draw !“);
      return false;

      Mit der „isEmpty()“ Methode kann man prüfen, ob das Unterschriftenfeld leer ist.

      Gruß
      Andy

  4. Hallo,

    ich weiß nicht, ob hier noch jemand ließt aber falls ja:
    Wenn ich die in der Datenbank abgespeicherte Unterschrift später wieder sichtbar machen will,
    lade ich es aus der Datenbank und male es mit der Javascript Funktion window.onload
    in den zum Canvas gehörigen Kontext:

    window.onload = function () {
    //alert(„Test“);
    var c = document.getElementById(„myCanvas“);
    var ctx = c.getContext(„2d“);
    var img = document.getElementById(„unterschriftImg“);
    ctx.drawImage(img, 0, 0, 350, 150);
    }

    Aber wenn jetzt de resize Funktion aufgerufen wird, verschwindet die Unterschrift. Wenn ich allerdings in den Canvas hinein male, bleibt das gemalte auch bei resize erhalten. Wie kann man das in den Griff bekommen?

    1. Ja das ist normal, dass bei Größenänderungen das Canvas leer gemacht wird, Du musst es dann neu zeichnen, hier so als grobe Idee:

      window.onload = function () {
      // Initial draw
      drawSignature();

      // Redraw on window resize
      window.addEventListener(‚resize‘, function() {
      drawSignature();
      });
      };

      function drawSignature() {
      var c = document.getElementById(„myCanvas“);
      var ctx = c.getContext(„2d“);
      var img = document.getElementById(„unterschriftImg“);

      // Clear the canvas before re-drawing
      ctx.clearRect(0, 0, c.width, c.height);

      // Draw the image on the canvas
      ctx.drawImage(img, 0, 0, 350, 150);
      }

  5. Hallo und guten Abend,
    ich nutze das Skript für ein Formular, welches am Ende nach dem Absenden in einem PDF geschrieben werden soll. Gibt es eine Lösung, die Daten aus $_POST[„signature“]; entweder in eine Datei auf den Server zu schreiben oder die Daten direkt in ein PDF einzufügen.

    Ich nutze FPDF und der Befehl $pdf->Image($_POST[„signature“];,80,267,40);
    bringt leider einen Fehler, weil die Daten in $_POST[„signature“]; nicht als Bilddaten erkannt werden.

    Was kann ich tun?
    GLG
    Sascha

    P.S.: Vielen Dank für das mega gute Script

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert