A comprehensive signature pad integration project providing both a simple demo for testing and a complete business form integration. Choose the right implementation for your needs: simple signature testing or full CRM/business workflow integration.
- Multiple Signature Methods: Draw signatures or type names
- Multiple Export Formats: PNG, JPG, SVG support
- Complete Form Integration: Ready-to-use form with validation
- Database Storage: Secure data storage with PDO
- File Management: Automatic file naming and organization
- Responsive Design: Works on desktop and mobile devices
- Security Features: Input validation, SQL injection prevention, file validation
- Error Handling: Comprehensive error logging and user feedback
This project is organized into three main directories for different use cases:
Use this for: Testing signature functionality, proof of concepts, integrating into existing applications
signature-pad-demo.html- Interactive canvas with drawing toolscss/andjs/- Required assets for the demo- Features: Draw, clear, undo, color change, save as PNG/JPG/SVG files
Use this for: CRM integration, business workflows, standalone deployments
business-form.html- Complete form with signature integration (self-contained)- Includes: User details, signature options (draw/type), form validation
- Ready for production deployment with minimal configuration
Use this for: Processing form submissions, storing signatures and data
submit-agreement.php- Form processing script (PHP 8.1+ compatible)uploads/signatures/- File storage directory- Handles: Database operations, file conversions, validation, logging
- PHP 8.1+ with PDO MySQL extension (updated for modern PHP features)
- MySQL 5.7+ or MariaDB 10.2+
- Web server (Apache, Nginx, or similar)
- Modern web browser with HTML5 Canvas support
Clone or download this repository to your web directory. The project structure is organized as follows:
your-website/
βββ demo/
β βββ signature-pad-demo.html # Simple signature testing
β βββ css/ # Demo styling
β βββ js/ # Demo JavaScript
βββ form-integration/
β βββ business-form.html # Complete business form (self-contained)
βββ backend/
β βββ submit-agreement.php # Form processing (PHP 8.1+)
β βββ uploads/signatures/ # File storage (needs write permissions)
βββ README.md
Create a new MySQL database for your application:
CREATE DATABASE signature_forms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;CREATE USER 'signature_user'@'localhost' IDENTIFIED BY 'your_secure_password';
GRANT ALL PRIVILEGES ON signature_forms.* TO 'signature_user'@'localhost';
FLUSH PRIVILEGES;The PHP script will automatically create the table, but you can create it manually if preferred:
USE signature_forms;
CREATE TABLE form_submissions (
id INT AUTO_INCREMENT PRIMARY KEY,
full_name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
company VARCHAR(255),
signature_method ENUM('drawn', 'typed') NOT NULL,
signature_data TEXT,
signature_file_png VARCHAR(255),
signature_file_jpg VARCHAR(255),
signature_file_svg VARCHAR(255),
agree_terms BOOLEAN NOT NULL DEFAULT 0,
ip_address VARCHAR(45),
user_agent TEXT,
submitted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_email (email),
INDEX idx_submitted_at (submitted_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;Open backend/submit-agreement.php and update the database configuration (lines 25-30):
// Database Configuration
$db_host = 'localhost'; // Your database host
$db_name = 'signature_forms'; // Your database name
$db_user = 'signature_user'; // Your database username
$db_pass = 'your_secure_password'; // Your database password
$db_charset = 'utf8mb4'; // Keep as utf8mb4Update the file upload configuration (lines 32-37):
// File Upload Configuration
$upload_path = 'uploads/signatures/'; // Relative path from PHP script
$max_file_size = 5 * 1024 * 1024; // 5MB max file size
$allowed_formats = ['png', 'webp', 'svg']; // Optimal formats for signatures
$default_format = 'png'; // Default format for form submissions
$save_multiple_formats = false; // Set true to save all formatsAdjust application behavior (lines 39-42):
// Application Settings
$require_signature = true; // Make signature mandatory
$log_submissions = true; // Enable logging
$debug_mode = false; // Set true for development only# Navigate to your web directory
cd /path/to/your/website
# Create upload directories (if they don't exist)
mkdir -p backend/uploads/signatures
# Set proper permissions
chmod 755 backend/uploads
chmod 755 backend/uploads/signaturesIf you can't use command line, create this PHP script temporarily:
<?php
$upload_dir = 'backend/uploads/signatures';
if (!file_exists($upload_dir)) {
if (mkdir($upload_dir, 0755, true)) {
echo "Upload directory created successfully!";
} else {
echo "Failed to create upload directory.";
}
} else {
echo "Upload directory already exists.";
}
?>- Open
demo/signature-pad-demo.htmlin your browser - Test signature drawing, color picker, undo, clear functions
- Use save buttons to download PNG, WebP, or SVG files
- No backend configuration needed for demo
-
Edit Form Submission Path In
form-integration/business-form.html, uncomment and update the fetch URL (around line 596):fetch('../backend/submit-agreement.php', { // Path is already correct for new structure method: 'POST', body: formData })
-
Test the Form
- Open
form-integration/business-form.htmlin your browser - Fill out all required fields
- Test both drawing and typing signature modes
- Open
Modify the form fields in the HTML to match your requirements:
<!-- Add, remove, or modify these fields as needed -->
<div class="form-group">
<label for="fullName">Full Name *</label>
<input type="text" class="form-control" id="fullName" name="fullName" required>
</div>
<!-- Add your custom fields here -->Create a .htaccess file in the backend/uploads directory:
# backend/uploads/.htaccess
# Prevent direct access to uploaded files
<Files "*">
Order Deny,Allow
Deny from all
</Files>
# Allow only signature image files to be accessed
<FilesMatch "\.(png|webp|svg)$">
Order Allow,Deny
Allow from all
</FilesMatch>
# Prevent PHP execution in uploads directory
php_flag engine offAdd to your Nginx configuration:
# Prevent access to uploads directory
location /backend/uploads/ {
location ~* \.(png|webp|svg)$ {
# Allow signature image files
}
location ~* \.(php|php5|phtml)$ {
deny all;
}
}Create a temporary test file:
<?php
// test-db.php
$db_host = 'localhost';
$db_name = 'signature_forms';
$db_user = 'signature_user';
$db_pass = 'your_secure_password';
try {
$pdo = new PDO("mysql:host={$db_host};dbname={$db_name}", $db_user, $db_pass);
echo "Database connection successful!";
} catch (PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
?>- Open your HTML form in a web browser
- Fill out all required fields
- Either draw a signature or type your name
- Submit the form
- Check for success message
- Verify data in database and uploaded files
Monitor these files for any issues:
# Check PHP error log
tail -f /var/log/php_errors.log
# Check custom application logs
tail -f signature_form_errors.log
tail -f signature_form_success.logModify the signature pad behavior in the HTML JavaScript:
window.signaturePad = new SignaturePad(canvas, {
backgroundColor: 'rgb(255, 255, 255)', // Background color
penColor: 'rgb(0, 0, 0)', // Pen color
minWidth: 1, // Minimum stroke width
maxWidth: 3, // Maximum stroke width
velocityFilterWeight: 0.7, // Stroke smoothing
minDistance: 5 // Minimum distance between points
});Adjust the signature canvas size in the CSS:
.signature-pad canvas {
height: 200px; /* Change this value */
width: 100%;
}Enable multiple format saving:
// In submit-agreement.php
$save_multiple_formats = true; // Saves PNG, WebP, and SVGAdd custom validation to the PHP script:
// Add to validateInput() function
if (empty($data['company']) && $require_company) {
$errors[] = "Company name is required.";
}Your final directory structure should look like:
your-website/
βββ demo/ # Demo & Testing
β βββ signature-pad-demo.html # Simple signature demo
β βββ css/
β β βββ signature-pad.css
β β βββ bootstrap-custom.css
β βββ js/
β βββ app.js
β βββ signature_pad.umd.js
βββ form-integration/ # Business Integration
β βββ business-form.html # Complete form (self-contained)
βββ backend/ # Server Processing
β βββ submit-agreement.php # Form processor (PHP 8.1+)
β βββ uploads/
β β βββ .htaccess # Security config
β β βββ signatures/ # Signature files
β β βββ signature_1_20240101123456.png
β β βββ signature_1_20240101123456.webp
β β βββ signature_1_20240101123456.svg
β βββ signature_form_errors.log # Error log (auto-created)
β βββ signature_form_success.log # Success log (auto-created)
βββ CLAUDE.md # Development guidance
βββ README.md # This file
The form submissions table structure:
| Field | Type | Description |
|---|---|---|
id |
INT (PK) | Auto-incrementing primary key |
full_name |
VARCHAR(255) | User's full name |
email |
VARCHAR(255) | User's email address |
company |
VARCHAR(255) | Company name (optional) |
signature_method |
ENUM | 'drawn' or 'typed' |
signature_data |
TEXT | Text signature data |
signature_file_png |
VARCHAR(255) | PNG filename |
signature_file_webp |
VARCHAR(255) | WebP filename |
signature_file_svg |
VARCHAR(255) | SVG filename |
agree_terms |
BOOLEAN | Terms agreement status |
ip_address |
VARCHAR(45) | User's IP address |
user_agent |
TEXT | Browser user agent |
submitted_at |
TIMESTAMP | Submission timestamp |
- File type validation: Only allows PNG, WebP, SVG formats (optimal for signatures)
- File size limits: Configurable maximum file size
- Unique filenames: Prevents file conflicts and overwrites
- Directory protection: Prevents direct file access
- No script execution: PHP execution disabled in uploads directory
- Prepared statements: Prevents SQL injection
- Input validation: Validates all user input
- Error handling: Doesn't expose sensitive information
- Use HTTPS: Always serve forms over HTTPS
- Rate limiting: Implement rate limiting for form submissions
- CSRF protection: Add CSRF tokens to forms
- File scanning: Consider virus scanning for uploaded files
- Backup strategy: Regular database and file backups
- Check database credentials in PHP script
- Verify database server is running
- Ensure PHP PDO MySQL extension is installed
- Check directory permissions (should be 755)
- Verify web server has write access
- Check available disk space
- Check internet connection (CDN dependency)
- Verify JavaScript console for errors
- Try the local fallback option
- Check upload directory permissions
- Verify file size limits
- Check error logs for detailed messages
Enable debug mode for detailed error information:
$debug_mode = true; // In submit-agreement.phpCheck these log files for troubleshooting:
signature_form_errors.log- Application errorssignature_form_success.log- Successful submissions- Server error logs (location varies by setup)
Add email functionality to the PHP script:
// After successful submission
$to = $email;
$subject = "Form Submission Confirmation";
$message = "Thank you for your submission, {$full_name}!";
$headers = "From: noreply@yoursite.com\r\n";
mail($to, $subject, $message, $headers);Create a download script for accessing signature files:
// download-signature.php
$submission_id = $_GET['id'];
$format = $_GET['format']; // png, jpg, or svg
$paths = getSignatureFilePaths($submission_id);
if (isset($paths[$format])) {
$file_path = $paths[$format];
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="signature.' . $format . '"');
readfile($file_path);
}- Place files in active theme directory
- Use WordPress database functions instead of direct PDO
- Add proper nonces for CSRF protection
- Adapt database configuration to your framework's ORM
- Use framework's validation and error handling
- Integrate with existing user authentication
This example builds upon the MIT-licensed signature_pad library. The integration code provided here is also available under the MIT license.
Feel free to submit issues, fork the repository, and create pull requests for any improvements.
For issues related to:
- Signature Pad Library: Visit the original repository
- Integration Code: Check the troubleshooting section above or create an issue
Happy coding! π¨βοΈ
