A powerful, intuitive form builder system built with Laravel 12 that enables creation, management, and analysis of dynamic forms with advanced submission tracking and export capabilities.
Features β’ Installation β’ Usage β’ Documentation β’ Contributing
- Overview
- Key Features
- Technology Stack
- System Architecture
- Installation
- Configuration
- Usage Guide
- API Reference
- Security Features
- Advanced Features
- Database Schema
- Troubleshooting
- Testing
- Contributing
- License
The Laravel Dynamic Form Builder System is a comprehensive solution for creating and managing custom forms with a drag-and-drop interface. Built for organizations that need to collect data efficiently, this system offers enterprise-grade features including real-time validation, spam protection, advanced analytics, and intelligent field matching for form evolution.
- π¨ Visual Form Builder: Create complex forms without writing code
- π Real-time Analytics: Track submission patterns and insights
- π Security First: Built-in CAPTCHA and spam protection
- π Export Capabilities: Generate Excel reports with one click
- π Backward Compatibility: Intelligent field matching handles form modifications
- β‘ Auto-save: Never lose your work with automatic draft saving
- π± Responsive Design: Perfect experience on all devices
- π¨ Drag-and-Drop Interface: Intuitive visual form builder with live preview
- π Multiple Field Types:
- Short text input
- Long text (textarea)
- Dropdown select
- Radio buttons
- Checkboxes
- File uploads
- Email validation
- Number input
- Date picker
- π¨ Theme Customization: 6 color themes (Blue, Green, Purple, Red, Yellow, Indigo)
- βοΈ Field Configuration:
- Required/optional fields
- Custom labels
- Option management for select/radio/checkbox
- File type restrictions and size limits
- Drag-to-reorder fields
- π Dashboard Overview: Real-time statistics and recent forms
- π Search & Filter: Find forms quickly with advanced search
- π€ Publish/Unpublish: Control form visibility and access
- π Custom URLs: SEO-friendly slugs for each form
- ποΈ Safe Deletion: Automatic cleanup of associated files and submissions
- β° Auto-save: Changes saved automatically every few seconds
- π‘οΈ Cloudflare Turnstile: Bot protection for all public forms
- π₯ File Upload Support: Secure file storage with validation
- π IP Tracking: Record submitter information for analytics
- πΈ Field Snapshots: Maintain historical accuracy when forms change
- π Detailed View: Examine individual submissions with full context
- π Submission Analytics:
- Total submissions count
- Today's submissions
- Weekly trends
- Time-based charts
- π Paginated Results: Easy navigation through large datasets
- π Search Submissions: Find specific responses quickly
- π Excel Export: One-click export with:
- Professional formatting
- Clickable file links
- Auto-sized columns
- Color-coded headers
- Required field indicators
- π Admin Authentication: Environment-based secure login
- π‘οΈ CSRF Protection: Laravel's built-in security
- π€ Bot Prevention: Cloudflare Turnstile integration
- π Hidden Admin Panel: Obscured URL path (
/hidden-admin) - π Audit Trail: IP and user agent logging
- π« Status Controls: Active/inactive form states
- π Backward Compatibility: Intelligent field matching for form modifications
- π οΈ Artisan Commands: CLI tools for maintenance
- π¦ Modular Architecture: Clean, maintainable code structure
- π― RESTful API: JSON responses for all operations
- π§ͺ Testing Ready: PHPUnit configured and ready
- π Well Documented: Comprehensive inline documentation
- Laravel 12.0 - PHP framework with latest features
- PHP 8.2+ - Modern PHP with improved performance
- SQLite - Default database (MySQL/PostgreSQL supported)
- Doctrine DBAL - Database abstraction layer
- Maatwebsite Excel - Excel export functionality
- Tailwind CSS 4.1 - Utility-first CSS framework
- Vite 7.0 - Lightning-fast frontend tooling
- Alpine.js (via Laravel) - Minimal JavaScript framework
- Axios - HTTP client for AJAX requests
- SortableJS - Drag-and-drop functionality
- Cloudflare Turnstile - Bot protection
- Laravel Vite Plugin - Asset bundling
- Concurrently - Development server management
- Laravel Pail - Real-time log viewing
- Laravel Pint - Code style fixer
- PHPUnit - Testing framework
- Faker - Test data generation
- Laravel Sail - Docker development environment
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β User Interface Layer β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Public Forms β Admin Panel (Hidden URL) β
β - Form Display β - Dashboard β
β - Submission β - Form Builder β
β - Turnstile β - Analytics β
ββββββββββββββββ¬ββββββββ΄ββββββββββββββββββ¬βββββββββββββββββββββ
β β
βΌ βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Controller Layer β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β FormController β AdminAuthController β
β - CRUD Operations β - Authentication β
β - Submissions β - Dashboard Data β
β - File Handling β - Export Management β
ββββββββββββββββ¬ββββββββ΄ββββββββββββββββββ¬βββββββββββββββββββββ
β β
βΌ βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Service Layer β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β TurnstileService β FormSubmissionsExport β
β - Bot Verification β - Excel Generation β
β - API Integration β - Data Formatting β
ββββββββββββββββ¬ββββββββ΄ββββββββββββββββββ¬βββββββββββββββββββββ
β β
βΌ βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Model Layer β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Form Model β FormField Model β FormSubmission β
β - Relationships β - Validation β - Field Snapshot β
β - Auto-slug β - Ordering β - Smart Matching β
ββββββββββββββββ¬ββββββββ΄ββββββββββββββββββββ΄βββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Database Layer β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β forms β form_fields β form_submissions β
β - Title, Slug β - Type, Label β - Data, Snapshot β
β - Status, Color β - Options β - Files, Metadata β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Ensure your system meets these requirements:
- PHP >= 8.2
- Composer >= 2.0
- Node.js >= 18.0
- NPM or Yarn
- SQLite (or MySQL/PostgreSQL)
- Git
git clone https://github.com/yourusername/laravel-form-creation-system.git
cd laravel-form-creation-systemcomposer installnpm install# Copy environment file
cp .env.example .env
# Generate application key
php artisan key:generateEdit .env file with your settings:
# Application
APP_NAME="Form Builder System"
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost:8000
# Database (SQLite by default)
DB_CONNECTION=sqlite
# Admin Credentials
ADMIN_USERNAME=admin
ADMIN_PASSWORD=your-secure-password
# Cloudflare Turnstile (Required for public forms)
TURNSTILE_SITE_KEY=your-site-key
TURNSTILE_SECRET_KEY=your-secret-key
# Session (Required for admin authentication)
SESSION_DRIVER=databaseFor SQLite (default):
touch database/database.sqliteFor MySQL:
# Create database manually
mysql -u root -p -e "CREATE DATABASE form_builder;"php artisan migratephp artisan storage:link# Development
npm run dev
# Production
npm run build# Option 1: Simple server
php artisan serve
# Option 2: Full development stack (recommended)
composer run devThe application will be available at http://localhost:8000
Cloudflare Turnstile provides free bot protection:
- Visit Cloudflare Turnstile Dashboard
- Create a new site
- Copy your Site Key and Secret Key
- Add to
.env:
TURNSTILE_SITE_KEY=1x00000000000000000000AA
TURNSTILE_SECRET_KEY=1x0000000000000000000000000000000AASet strong credentials in .env:
ADMIN_USERNAME=your-admin-username
ADMIN_PASSWORD=your-secure-password-hereImportant: In production, use a strong password with:
- Minimum 12 characters
- Mix of uppercase and lowercase
- Numbers and special characters
DB_CONNECTION=sqliteDB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=form_builder
DB_USERNAME=root
DB_PASSWORD=your-passwordDB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=form_builder
DB_USERNAME=postgres
DB_PASSWORD=your-passwordConfigure file upload limits in php.ini:
upload_max_filesize = 10M
post_max_size = 10MOr in .env for Laravel Valet:
UPLOAD_MAX_FILESIZE=10485760For better performance with file uploads:
QUEUE_CONNECTION=databaseRun queue worker:
php artisan queue:work- Navigate to
http://localhost:8000/hidden-admin - Login with credentials from
.env - You'll be redirected to the dashboard
- Click "Create New Form" on the dashboard
- Or go to
/hidden-admin/forms/create
- Title: Enter a descriptive form title
- Description: Add optional instructions
- Theme Color: Choose from 6 color schemes
Click field types from the sidebar:
- Short Text: Single-line input
- Long Text: Multi-line textarea
- Dropdown: Select from options
- Radio Buttons: Single choice from options
- Checkboxes: Multiple selections
- File Upload: Document/image uploads
- Email: Validated email input
- Number: Numeric input only
- Date: Date picker
- Label: Field name visible to users
- Required: Toggle mandatory fields
- Options: For dropdown/radio/checkbox (one per line)
- File Settings: For file uploads:
- Accepted types (comma-separated)
- Maximum size in MB
- Drag and drop fields to reorder
- Use the drag handle on the left
- Changes auto-save as drafts
- Click "Publish Form" when ready
- Choose form status:
- Active: Accepts submissions
- Inactive: Visible but locked
- Optionally customize the URL slug
Navigate to /hidden-admin/forms:
- See all forms with submission counts
- Search by title or description
- Quick actions: View, Analytics, Export, Delete
- Click form title or edit icon
- Modify fields and settings
- Changes save automatically
- Re-publish to update live version
Click "Analytics" on any form:
- Metrics: Total, today, and weekly submissions
- Submission List: Paginated with search
- Individual View: Click any submission for details
- Click "Export" button in analytics
- Downloads formatted Excel file with:
- All submission data
- Clickable file links
- Professional styling
- Timestamp information
- Shows recent submissions
- Displays preview of responses
- Click to view full details
- Complete response data
- Field labels and values
- Downloadable file attachments
- Submitter metadata (IP, user agent)
- Submission timestamp
- Form is being created/edited
- Not publicly accessible
- Can be edited freely
- Live and accepting submissions
- Publicly accessible via URL
- Protected by Turnstile
- Visible but not accepting submissions
- Shows "locked" message to users
- Admins can still view
- User visits form URL (e.g.,
/form/contact-us-abc123) - Sees branded form with SITC styling
- Fills out required fields
- Completes Turnstile verification
- Submits form
- Sees success message
- Files stored in
/storage/app/public/submissions/{form_id}/{submission_id}/ - Validated against allowed types and size
- Unique filenames prevent conflicts
All admin routes require authentication and are prefixed with /hidden-admin.
POST /hidden-admin
Content-Type: application/x-www-form-urlencoded
username=admin&password=secretPOST /hidden-admin/forms/store
Content-Type: application/json
{
"id": null,
"title": "Contact Form",
"description": "Get in touch with us",
"color": "blue",
"fields": [
{
"type": "text",
"label": "Full Name",
"required": true
},
{
"type": "email",
"label": "Email Address",
"required": true
}
]
}Response:
{
"success": true,
"form_id": 1,
"message": "Form saved successfully"
}POST /hidden-admin/forms/{id}/publish
Content-Type: application/json
{
"slug": "contact-us",
"form_status": "active"
}Response:
{
"success": true,
"slug": "contact-us-abc123",
"url": "http://localhost:8000/form/contact-us-abc123"
}GET /hidden-admin/forms/{id}/dataResponse:
{
"success": true,
"form": {
"id": 1,
"title": "Contact Form",
"fields": [...]
}
}DELETE /hidden-admin/forms/{id}GET /form/{slug}POST /form/{slug}/submit
Content-Type: multipart/form-data
field_1=John+Doe&
field_2=john@example.com&
cf-turnstile-response=tokenResponse:
{
"success": true,
"message": "Form submitted successfully!"
}- Session-based admin authentication
- Environment variables for credentials
- Hidden admin URL to prevent discovery
- CSRF protection on all forms
- Cloudflare Turnstile on all public forms
- Server-side token verification
- IP address logging
- Rate limiting capable
- Type validation (whitelist approach)
- Size restrictions per field
- Unique storage paths
- Automatic cleanup on deletion
- SQL injection prevention via Eloquent ORM
- XSS protection via Blade templating
- Mass assignment protection via
$fillable - Input validation on all endpoints
- Environment-based configuration
- Secure session handling
- Regular security updates
- Error logging without exposure
The most sophisticated feature enabling backward compatibility:
When a form is modified after receiving submissions:
- Field IDs change
- Field order changes
- Fields are added/removed
- Old submissions become unreadable
Field Snapshots - Every submission stores the form structure at submission time:
{
"field_snapshot": [
{
"id": 1,
"type": "text",
"label": "Full Name",
"order": 0,
"required": true
},
{
"id": 2,
"type": "email",
"label": "Email",
"order": 1,
"required": true
}
]
}When displaying old submissions, the system uses a scoring algorithm:
Score Components:
- Label Match (60%): Exact or similar text
- Type Match (20%): Same field type
- Position Match (10%): Same order in form
- Required Status (5%): Same required flag
- Options Similarity (5%): For select/radio/checkboxExample: If "Full Name" field is later renamed to "Name", the system:
- Calculates similarity: 75% match
- Confidence threshold: 50%
- Result: Successfully matches and displays data
For existing installations without snapshots:
# Preview changes
php artisan submissions:backfill-snapshots --dry-run
# Apply changes
php artisan submissions:backfill-snapshotsForms save automatically while building:
- Frequency: Every 5 seconds of inactivity
- Status: Visual indicator shows save state
- Draft Mode: All changes saved as drafts
- No Data Loss: Continue where you left off
Professional exports with:
- Formatted Headers: Bold, colored background
- Auto-sized Columns: Perfect width for content
- Clickable Links: File uploads become hyperlinks
- Required Indicators: Asterisk (*) on required fields
- Metadata: Submission ID, date, time, IP, user agent
- Custom Styling: Professional appearance
Three-tier status system:
Draft β Published (Active) β Published (Inactive)
β β β
Hidden Accepting Visible but
Submissions Locked
Benefits:
- Draft: Work in progress, private
- Active: Fully operational
- Inactive: Temporarily disable without unpublishing
ββββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββββ
β forms β β form_fields β β form_submissions β
ββββββββββββββββββββ€ ββββββββββββββββββββ€ βββββββββββββββββββββ€
β id ββββββ β id β βββββ id β
β title β β β form_id βββββββ β form_id β
β description β ββββββ type β ββ β submission_data β
β color β β label β ββ β field_snapshot β
β slug (unique) β β required β ββ β files β
β status β β options β ββ β ip_address β
β form_status β β file_settings β ββ β user_agent β
β settings β β order β ββ β submitted_at β
β timestamps β β timestamps β ββ β timestamps β
ββββββββββββββββββββ ββββββββββββββββββββ ββ βββββββββββββββββββββ
β² ββ
βββββββββββββββββββββ
β
Form has many ββββββ
submissions| Column | Type | Description |
|---|---|---|
id |
bigint | Primary key |
title |
varchar(255) | Form display name |
description |
text | Optional form instructions |
color |
varchar(50) | Theme color (blue, green, etc.) |
slug |
varchar(255) | Unique URL identifier |
status |
enum | draft or published |
form_status |
enum | active or inactive |
settings |
json | Additional configuration |
created_at |
timestamp | Creation date |
updated_at |
timestamp | Last modified date |
| Column | Type | Description |
|---|---|---|
id |
bigint | Primary key |
form_id |
bigint | Foreign key to forms |
type |
varchar(50) | Field type (text, email, etc.) |
label |
varchar(255) | Field display name |
required |
boolean | Mandatory field flag |
options |
json | Options for select/radio/checkbox |
file_settings |
json | Upload restrictions |
order |
integer | Display position |
created_at |
timestamp | Creation date |
updated_at |
timestamp | Last modified date |
| Column | Type | Description |
|---|---|---|
id |
bigint | Primary key |
form_id |
bigint | Foreign key to forms |
submission_data |
json | All field responses |
field_snapshot |
json | Form structure at submission |
files |
json | Uploaded file paths |
ip_address |
varchar(45) | Submitter IP |
user_agent |
text | Browser information |
submitted_at |
timestamp | Submission date/time |
created_at |
timestamp | Record creation |
updated_at |
timestamp | Last modified |
// Form Model
public function fields(): HasMany
public function submissions(): HasMany
// FormField Model
public function form(): BelongsTo
// FormSubmission Model
public function form(): BelongsToSolution: Clear configuration cache
php artisan config:clear
php artisan cache:clearSolution: Build frontend assets
npm run buildSolution: Create storage link
php artisan storage:link
chmod -R 775 storageSolution: Check environment variables
# Verify .env has correct values
grep "ADMIN_" .env
# Clear session data
php artisan session:flushSolution:
- Verify keys in
.envare correct - Check domain is allowed in Cloudflare dashboard
- Test with different IP (some IPs may be blocked)
- Check logs:
storage/logs/laravel.log
Solution:
# Check permissions
chmod -R 775 storage/app/public
# Verify storage link exists
ls -la public/storage
# Check PHP upload limits
php -i | grep upload_max_filesizeSolution:
# For SQLite
touch database/database.sqlite
chmod 664 database/database.sqlite
# For MySQL
php artisan migrate:freshEnable detailed error messages:
APP_DEBUG=true
LOG_LEVEL=debugView real-time logs:
php artisan pailphp artisan optimize
php artisan config:cache
php artisan route:cache
php artisan view:cachephp artisan optimize:clear# Run all tests
php artisan test
# Run specific test file
php artisan test --filter FormControllerTest
# Run with coverage
php artisan test --coverage# Generate test class
php artisan make:test FormSubmissionTestExample test:
public function test_form_can_be_created()
{
$response = $this->post('/hidden-admin/forms/store', [
'title' => 'Test Form',
'color' => 'blue',
'fields' => [
['type' => 'text', 'label' => 'Name', 'required' => true]
]
]);
$response->assertStatus(200);
$this->assertDatabaseHas('forms', ['title' => 'Test Form']);
}We welcome contributions! Here's how you can help:
- Fork the repository
- Clone your fork
git clone https://github.com/yourusername/laravel-form-creation-system.git- Create a feature branch
git checkout -b feature/amazing-feature- Commit your changes
git commit -m 'Add amazing feature'- Push to the branch
git push origin feature/amazing-feature- Open a Pull Request
- Follow PSR-12 coding standard
- Use Laravel best practices
- Write meaningful commit messages
- Add tests for new features
- Update documentation as needed
./vendor/bin/pint- π Bug fixes
- β¨ New field types
- π Translations
- π Documentation improvements
- π¨ UI/UX enhancements
- β‘ Performance optimizations
- π§ͺ Additional tests
- Clearly describe the problem and solution
- Include relevant issue numbers
- Update README if needed
- Ensure tests pass
- Follow existing code style
This project is licensed under the MIT License - see the LICENSE file for details.
MIT License
Copyright (c) 2025 Laravel Form Builder System
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions...
- Codezela Technologies - System architecture and implementation
- Laravel Team - For the amazing framework
- Cloudflare - For Turnstile bot protection
- Tailwind CSS - For the utility-first CSS framework
- SortableJS - For drag-and-drop functionality
- Open Source Community - For inspiration and tools
- Issues: GitHub Issues
- Discussions: GitHub Discussions
If this project helped you, please consider giving it a βοΈ!
Current Version: 1.0.0
Last Updated: December 2025
Built with β€οΈ using Laravel