PHPackages                             litepie/form - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Caching](/categories/caching)
4. /
5. litepie/form

ActiveLibrary[Caching](/categories/caching)

litepie/form
============

A comprehensive Laravel form builder package with advanced features, caching, and modern design patterns

v1.0.18(2mo ago)0491MITPHPPHP ^8.2|^8.3

Since Aug 23Pushed 2mo agoCompare

[ Source](https://github.com/Litepie/Form)[ Packagist](https://packagist.org/packages/litepie/form)[ Docs](https://github.com/litepie/form)[ GitHub Sponsors](https://github.com/sponsors/litepie)[ RSS](/packages/litepie-form/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (1)Dependencies (11)Versions (20)Used By (1)

Litepie Form Builder
====================

[](#litepie-form-builder)

**Package**: `litepie/form` | **Type**: Laravel Form Builder | **Laravel**: 11+ &amp; 12+ | **PHP**: 8.2+
**AI Context**: See [.ai-context.md](.ai-context.md) for structured package information for AI assistants

A comprehensive, production-ready Laravel form builder package inspired by the original Litepie/Form but completely rewritten for Laravel 12 with modern design patterns and advanced features.

📋 Table of Contents
-------------------

[](#-table-of-contents)

- [Features](#-features)
- [Installation](#-installation)
- [Quick Start](#-quick-start)
- [Field Types](#-field-types)
- [Advanced Features](#-advanced-features)
- [Form Container](#-form-container---managing-multiple-forms)
- [Client-Side Integration](#-client-side-integration)
- [Validation](#-advanced-validation)
- [File Uploads](#-file-uploads)
- [Performance &amp; Caching](#-performance--caching)
- [Testing](#-testing)
- [API Reference](#-api-reference)
- [Documentation](#-documentation)
- [Contributing](#-contributing)
- [Security](#-security)
- [Support](#-support)

✨ Features
----------

[](#-features)

- **🚀 Laravel 12 Ready**: Built for Laravel 11+ with full Laravel 12 compatibility
- **🎨 Multiple UI Frameworks**: Bootstrap 5, Bootstrap 4, Tailwind CSS, and custom themes
- **📝 30+ Field Types**: Complete field library including advanced types like rich text, maps, file uploads
- **🔐 Field Visibility Control**: Permission-based, role-based, and conditional field visibility
    - Methods: `can()`, `roles()`, `visibleWhen()`, `isVisible()`
    - Integration: Works with `render()`, `toArray()`, `toJson()`
- **💾 Performance Caching**: User-scoped form caching with TTL support
    - Methods: `cache()`, `cached()`, `clearCache()`, `withoutCache()`
    - Automatic per-user cache scoping
- **🏗️ Hierarchical Organization**: Groups → Sections → Rows → Fields
    - Methods: `group()`, `section()`, `row()`, `divider()`, `endGroup()`, `endSection()`
    - Auto-assignment of fields to active group/section
- **📐 Grid Layout System**: Responsive 12-column grid with custom widths
    - Methods: `col()`, `width()`, `defaultWidth()`
    - Output includes width, row, group, section metadata
- **✅ Advanced Validation**: Real-time validation, conditional rules, custom validators
- **🔀 Conditional Logic**: Dynamic field visibility, validation, and multi-step forms
- **📁 File Management**: Drag &amp; drop uploads, image cropping, gallery management, cloud storage
- **📦 Form Container**: Manage multiple forms with tabbed, accordion, or stacked interfaces
- **♿ Accessibility**: WCAG 2.1 AA compliant with full screen reader support
- **⚡ Performance**: Optimized rendering, asset bundling, lazy loading
- **🌐 Client-Side Ready**: Full support for Vue.js, React, Angular with `toArray()` and `toJson()`
- **🧪 Well Tested**: Comprehensive test suite with 95%+ code coverage
- **🎯 Developer Friendly**: Fluent API, extensive documentation, helper functions

📦 Installation
--------------

[](#-installation)

```
composer require litepie/form
```

Publish the configuration and assets:

```
php artisan vendor:publish --provider="Litepie\Form\FormServiceProvider"
php artisan form:install
```

Include the CSS and JavaScript assets in your layout:

```

{!! form_include_assets(true, false) !!} {{-- CSS only --}}

{!! form_include_assets(false, true) !!} {{-- JS only --}}

{!! form_include_assets() !!}
```

🚀 Quick Start
-------------

[](#-quick-start)

### Creating Fields

[](#creating-fields)

The package provides multiple ways to create fields:

#### Method 1: Using Field::make() (Recommended)

[](#method-1-using-fieldmake-recommended)

```
use Litepie\Form\Field;

// Simple field
$field = Field::make('text', 'username');

// With fluent API
$field = Field::make('select', 'theme')
    ->label('Select Theme')
    ->options(['dark' => 'Dark Mode', 'light' => 'Light Mode'])
    ->required();

// With options array
$field = Field::make('email', 'contact', [
    'label' => 'Email Address',
    'required' => true,
    'placeholder' => 'you@example.com'
]);
```

#### Method 2: Using Form Builder add() method

[](#method-2-using-form-builder-add-method)

```
use Litepie\Form\Facades\Form;

$form = Form::create()
    ->add('name', 'text', ['label' => 'Name', 'required' => true])
    ->add('email', 'email', ['label' => 'Email']);
```

#### Method 3: Using Specific Field Classes

[](#method-3-using-specific-field-classes)

```
use Litepie\Form\Fields\TextField;
use Litepie\Form\Fields\SelectField;

$textField = new TextField('username');
$selectField = new SelectField('country');
```

### Basic Contact Form

[](#basic-contact-form)

```
use Litepie\Form\Facades\Form;
use Litepie\Form\Field;

$contactForm = Form::create()
    ->action('/contact')
    ->method('POST')
    ->add(Field::make('text', 'name')
        ->label('Full Name')
        ->required()
        ->placeholder('Enter your full name')
        ->rules('required|string|max:255')
    )
    ->add(Field::make('email', 'email')
        ->label('Email Address')
        ->required()
        ->rules('required|email')
    )
    ->add(Field::make('textarea', 'message')
        ->label('Message')
        ->required()
        ->setAttribute('rows', 5)
        ->rules('required|string|min:10')
    )
    ->add(Field::make('submit', 'submit')
        ->value('Send Message')
        ->addClass('btn btn-primary')
    );

// In your Blade template
{!! $contactForm->render() !!}
```

### Registration Form with File Upload

[](#registration-form-with-file-upload)

```
$registrationForm = Form::create()
    ->action('/register')
    ->method('POST')
    ->files(true)
    ->add(Field::make('image', 'avatar')
        ->label('Profile Picture')
        ->setAttribute('accept', 'image/*')
        ->setAttribute('maxSize', 5) // 5MB
        ->setAttribute('crop', true)
        ->setAttribute('aspectRatio', '1:1')
    )
    ->add(Field::make('text', 'first_name')
        ->label('First Name')
        ->required()
    )
    ->add(Field::make('text', 'last_name')
        ->label('Last Name')
        ->required()
    ])
    ->add('email', 'email', [
        'label' => 'Email',
        'required' => true,
        'validation' => 'required|email|unique:users'
    ])
    ->add('password', 'password', [
        'label' => 'Password',
        'required' => true,
        'validation' => 'required|min:8|confirmed'
    ])
    ->add('password_confirmation', 'password', [
        'label' => 'Confirm Password',
        'required' => true
    ])
    ->add('birth_date', 'date', [
        'label' => 'Date of Birth',
        'validation' => 'required|date|before:today'
    ])
    ->add('terms', 'checkbox', [
        'label' => 'I agree to the Terms of Service',
        'required' => true,
        'validation' => 'required|accepted'
    ]);
```

### Helper Functions

[](#helper-functions)

```
// Quick form creation
$quickForm = form_quick([
    'name' => 'text',
    'email' => ['type' => 'email', 'required' => true],
    'message' => 'textarea'
], [
    'action' => '/contact',
    'method' => 'POST'
]);

// Standalone field
$nameField = form_field('name', 'text', [
    'label' => 'Full Name',
    'required' => true
]);
```

### Field Visibility &amp; Permissions

[](#field-visibility--permissions)

Control field visibility based on user permissions and roles:

```
use Litepie\Form\Facades\Form;

$userForm = Form::create()
    ->action('/users')
    ->forUser(auth()->user())  // Set user for all operations

    // Basic fields - visible to everyone
    ->add(Form::text('name')->label('Name'))
    ->add(Form::email('email')->label('Email'))

    // Only visible with permission
    ->add(
        Form::number('salary')
            ->label('Salary')
            ->can('view-salary')
    )

    // Only visible to specific roles
    ->add(
        Form::select('department')
            ->label('Department')
            ->options(['sales' => 'Sales', 'engineering' => 'Engineering'])
            ->roles(['manager', 'admin'])
    )

    // Custom visibility logic
    ->add(
        Form::text('api_key')
            ->label('API Key')
            ->visibleWhen(fn($user) => $user && $user->isPremium())
    );

// Render only visible fields
echo $userForm->render();

// For client-side (Vue, React, etc.) - only visible fields included
return response()->json([
    'form' => $userForm->toArray()
]);
```

See [VISIBILITY.md](VISIBILITY.md) for complete visibility control documentation.

### Performance: Caching Form Output

[](#performance-caching-form-output)

Enable caching for forms that don't change frequently:

```
use Litepie\Form\Facades\Form;

// Enable caching with default TTL (1 hour)
$form = Form::create()
    ->forUser(auth()->user())
    ->cache()  // Enable caching
    ->add(Form::text('name'))
    ->add(Form::email('email'))
    ->add(Form::number('salary')->can('view-salary'));

// First render - generates and caches output
$html = $form->render();  // Slow

// Subsequent renders - returns cached output
$html = $form->render();  // Fast (from cache)

// Custom cache TTL (30 minutes)
$form->cache(1800);

// Cache is automatically scoped per user
$adminForm = $form->render($adminUser);    // Cached for admin
$managerForm = $form->render($managerUser); // Cached for manager

// Clear cache when needed
$form->clearCache();

// Disable caching
$form->withoutCache();
```

**Use caching for:**

- Forms with many fields and complex visibility logic
- API endpoints serving the same form to many users
- Admin panels with heavy permission checks

### Grid Layout &amp; Column Width

[](#grid-layout--column-width)

Control field widths for responsive grid layouts (works with Bootstrap, Tailwind, or any frontend):

```
use Litepie\Form\Facades\Form;

// Default: all fields are 6 columns (half width)
$form = Form::create()
    ->add(Form::text('first_name'))  // 6 columns (default)
    ->add(Form::text('last_name'));  // 6 columns (default)

// Custom column widths
$form = Form::create()
    ->add(Form::text('first_name')->col(6))   // 6/12 columns
    ->add(Form::text('last_name')->col(6))    // 6/12 columns
    ->add(Form::email('email')->col(12))      // Full width
    ->add(Form::text('city')->col(4))         // 4/12 columns
    ->add(Form::text('state')->col(4))        // 4/12 columns
    ->add(Form::text('zip')->col(4));         // 4/12 columns

// Group fields in rows (Recommended)
$form = Form::create()
    // Row 1: Two half-width fields (auto row ID: 'row1')
    ->row([
        Form::text('first_name')->col(6),
        Form::text('last_name')->col(6)
    ])

    // Row 2: Three equal fields (auto row ID: 'row2')
    ->row([
        Form::text('city')->col(4),
        Form::text('state')->col(4),
        Form::text('zip')->col(4)
    ])

    // Row 3: Custom split (auto row ID: 'row3')
    ->row([
        Form::text('field1')->col(3),
        Form::text('field2')->col(4),
        Form::text('field3')->col(5)
    ])

    // Row with custom ID
    ->row([
        Form::textarea('notes')->col(12)
    ], 'notes-row');

// Alternative: Manual row assignment
$form = Form::create()
    ->add(Form::text('first_name')->col(6)->row('contact'))
    ->add(Form::text('last_name')->col(6)->row('contact'))
    ->add(Form::text('city')->col(4)->row('address'))
    ->add(Form::text('state')->col(4)->row('address'))
    ->add(Form::text('zip')->col(4)->row('address'));

// Change default width for all fields
$form = Form::create()
    ->defaultWidth(4)  // All fields 4 columns by default
    ->row([
        Form::text('field1'),      // 4 columns (uses default)
        Form::text('field2'),      // 4 columns (uses default)
        Form::text('field3')       // 4 columns (uses default)
    ])
    ->row([
        Form::text('notes')->col(12)  // Override: full width
    ]);

// Output includes width and row for client-side rendering
$data = $form->toArray();
// Each field has: 'width' => 6, 'totalColumns' => 12, 'row' => 'row1'
```

**Frontend Implementation:**

```
// Group fields by row
const rows = {};
Object.values(fields).forEach(field => {
  const rowId = field.row || 'default';
  if (!rows[rowId]) rows[rowId] = [];
  rows[rowId].push(field);
});

// Render each row with Bootstrap
Object.entries(rows).forEach(([rowId, rowFields]) => {
  const html = `

      ${rowFields.map(field => `

          ${renderField(field)}

      `).join('')}

  `;
});

// Render each row with Tailwind
Object.entries(rows).forEach(([rowId, rowFields]) => {
  const html = `

      ${rowFields.map(field => `

          ${renderField(field)}

      `).join('')}

  `;
});
```

### Hierarchical Form Organization (Groups, Sections, Rows)

[](#hierarchical-form-organization-groups-sections-rows)

Organize complex forms with a hierarchical structure: **Form → Groups → Sections → Rows → Fields**

```
use Litepie\Form\Facades\Form;

$form = Form::create()
    ->action('/users')

    // Group 1: Basic Information
    ->group('basic_info', 'Basic Information', 'Enter your basic details')

        // Section 1.1: Personal Details
        ->section('personal', 'Personal Details')
            ->row([
                Form::text('first_name')->col(6)->label('First Name')->required(),
                Form::text('last_name')->col(6)->label('Last Name')->required()
            ])
            ->row([
                Form::email('email')->col(6)->label('Email'),
                Form::tel('phone')->col(6)->label('Phone')
            ])
        ->endSection()

        // Section 1.2: Address
        ->section('address', 'Address Information')
            ->row([
                Form::text('street')->col(12)->label('Street Address')
            ])
            ->row([
                Form::text('city')->col(4)->label('City'),
                Form::text('state')->col(4)->label('State'),
                Form::text('zip')->col(4)->label('ZIP Code')
            ])
        ->endSection()

    ->endGroup()

    // Visual separator with label
    ->divider('Additional Details')

    // Group 2: Account Settings
    ->group('account_settings', 'Account Settings')

        ->section('security', 'Security')
            ->row([
                Form::password('password')->col(6)->label('Password'),
                Form::password('password_confirmation')->col(6)->label('Confirm Password')
            ])
        ->endSection()

        ->section('preferences', 'Preferences')
            ->row([
                Form::checkbox('newsletter')->label('Subscribe to newsletter'),
                Form::checkbox('notifications')->label('Enable notifications')
            ])
        ->endSection()

    ->endGroup()

    // Divider without label (just a line)
    ->divider()

    // Fields without group/section (top-level)
    ->row([
        Form::submit('submit')->value('Save Changes')->class('btn btn-primary')
    ]);
```

**Key Features:**

- **Groups**: Top-level organization with titles and descriptions
- **Sections**: Sub-groups within groups (can have multiple sections per group)
- **Rows**: Layout containers for fields with column widths
- **Dividers**: Visual separators with optional labels
- **Auto-assignment**: Fields added after `group()` or `section()` automatically inherit the group/section
- **Flexible nesting**: Mix grouped and ungrouped fields in the same form

**Alternative Syntax (without fluent methods):**

```
$form = Form::create()
    ->group('info', 'Information')

    // Add fields - they automatically get group='info'
    ->add(Form::text('name')->col(6)->section('personal'))
    ->add(Form::email('email')->col(6)->section('personal'))

    ->add(Form::text('company')->col(6)->section('business'))
    ->add(Form::text('title')->col(6)->section('business'))

    ->endGroup();
```

**Output Structure (toArray/toJson):**

```
{
  "fields": {
    "first_name": {
      "name": "first_name",
      "type": "text",
      "label": "First Name",
      "width": 6,
      "row": "row1",
      "group": "basic_info",
      "section": "personal"
    },
    "email": {
      "name": "email",
      "type": "email",
      "width": 6,
      "row": "row2",
      "group": "basic_info",
      "section": "personal"
    }
  }
}
```

**Frontend Rendering:**

```
// Group fields by hierarchy
const structure = {};

Object.values(fields).forEach(field => {
  const groupId = field.group || 'default';
  const sectionId = field.section || 'default';
  const rowId = field.row || 'default';

  if (!structure[groupId]) {
    structure[groupId] = { sections: {} };
  }
  if (!structure[groupId].sections[sectionId]) {
    structure[groupId].sections[sectionId] = { rows: {} };
  }
  if (!structure[groupId].sections[sectionId].rows[rowId]) {
    structure[groupId].sections[sectionId].rows[rowId] = [];
  }

  structure[groupId].sections[sectionId].rows[rowId].push(field);
});

// Render with Bootstrap
Object.entries(structure).forEach(([groupId, group]) => {
  html += ``;

  Object.entries(group.sections).forEach(([sectionId, section]) => {
    html += ``;

    Object.entries(section.rows).forEach(([rowId, fields]) => {
      html += ``;
      fields.forEach(field => {
        html += `${renderField(field)}`;
      });
      html += ``;
    });

    html += ``;
  });

  html += ``;
});
```

**Divider Types:**

```
// Divider with label
->divider('Section Title')

// Plain divider (just a line)
->divider()

// Divider in specific group/section
->divider('Advanced Options', 'settings_group', 'advanced_section')
```

📝 Field Types
-------------

[](#-field-types)

```
'required' => true

```

\]);

// Form container $container = form\_container('my-container');

// Quick container creation $quickContainer = form\_container\_quick(\[ 'form1' =&gt; \[ 'fields' =&gt; \['name' =&gt; 'text', 'email' =&gt; 'email'\], 'containerOptions' =&gt; \['title' =&gt; 'Contact Info'\] \] \], \['name' =&gt; 'Multi-Form Container', 'tabbed' =&gt; true\]);

```

## 📝 Complete Field Types Reference

### 📥 Input Fields
| Field Type | Description | Key Features |
|------------|-------------|--------------|
| `text` | Standard text input | Placeholder, validation, autocomplete |
| `email` | Email input with validation | Built-in email validation, suggestions |
| `password` | Password input | Strength meter, confirmation matching |
| `number` | Numeric input | Min/max values, step increments |
| `tel` | Telephone input | International format support |
| `url` | URL input with validation | Protocol validation, link preview |
| `search` | Search input | Autocomplete, search suggestions |
| `hidden` | Hidden form field | Secure value storage |

### 📅 Date & Time Fields
| Field Type | Description | Key Features |
|------------|-------------|--------------|
| `date` | Date picker | Min/max dates, custom formats |
| `time` | Time picker | 12/24 hour format, minute steps |
| `datetime` | Date and time picker | Timezone support, combined input |
| `week` | Week picker | ISO week format |
| `month` | Month picker | Year/month selection |
| `daterange` | Date range picker | Start/end dates, presets |

### 🎯 Selection Fields
| Field Type | Description | Key Features |
|------------|-------------|--------------|
| `select` | Dropdown select | Search, grouping, multi-select |
| `radio` | Radio button group | Inline/stacked layout |
| `checkbox` | Checkbox group | Single or multiple options |
| `tags` | Tag input | Autocomplete, custom tags, suggestions |

### 📝 Text Areas & Rich Content
| Field Type | Description | Key Features |
|------------|-------------|--------------|
| `textarea` | Multi-line text input | Auto-resize, character count |
| `richtext` | WYSIWYG editor | TinyMCE integration, custom toolbar |

### 📁 File & Media Fields
| Field Type | Description | Key Features |
|------------|-------------|--------------|
| `file` | File upload | Drag & drop, progress, validation |
| `image` | Image upload | Cropping, preview, multiple formats |
| `gallery` | Multiple image upload | Sortable, bulk upload, thumbnails |

### 🎨 Visual & Interactive Fields
| Field Type | Description | Key Features |
|------------|-------------|--------------|
| `color` | Color picker | Palette, alpha support, formats |
| `range` | Range slider | Min/max, step, value display |
| `rating` | Star rating | Half stars, custom icons, readonly |
| `map` | Location picker | Google Maps, geocoding, markers |

### 🔘 Form Controls
| Field Type | Description | Key Features |
|------------|-------------|--------------|
| `submit` | Submit button | Custom styling, loading states |
| `button` | Generic button | Click handlers, custom actions |
| `reset` | Reset button | Form clearing, confirmation |

### 🏗️ Layout & Organization
| Field Type | Description | Key Features |
|------------|-------------|--------------|
| `html` | Custom HTML content | Raw HTML, dynamic content |
| `divider` | Visual separator | Different styles, text labels |
| `group` | Field grouping | Nested fields, layouts |

## ⚙️ Configuration

### Framework Selection
```php
// Bootstrap 5 (default)
Form::create()->theme('bootstrap5');

// Bootstrap 4
Form::create()->theme('bootstrap4');

// Tailwind CSS
Form::create()->theme('tailwind');

// Custom theme
Form::create()->theme('custom');

```

### Global Configuration

[](#global-configuration)

Edit `config/form.php`:

```
return [
    'default_theme' => 'bootstrap5',
    'validation' => [
        'realtime' => true,
        'debounce' => 300,
        'show_errors' => true,
    ],
    'uploads' => [
        'disk' => 'public',
        'path' => 'uploads/forms',
        'max_size' => '10MB',
        'allowed_types' => ['jpg', 'png', 'pdf', 'doc'],
    ],
    'maps' => [
        'provider' => 'google',
        'api_key' => env('GOOGLE_MAPS_API_KEY'),
        'default_zoom' => 10,
    ],
    'editor' => [
        'provider' => 'tinymce',
        'config' => [
            'height' => 300,
            'menubar' => false,
            'toolbar' => 'bold italic | link image | bullist numlist',
        ],
    ],
];
```

✅ Advanced Validation
---------------------

[](#-advanced-validation)

### Laravel Validation Rules

[](#laravel-validation-rules)

```
$form->add('email', 'email', [
    'validation' => 'required|email|unique:users,email'
]);
```

### Real-time Validation

[](#real-time-validation)

```
$form->add('username', 'text', [
    'validation' => 'required|min:3|unique:users',
    'realtime' => true,
    'debounce' => 500
]);
```

### Custom Validators

[](#custom-validators)

```
$form->add('custom_field', 'text', [
    'validation' => ['required', new CustomRule()],
    'messages' => [
        'custom_field.required' => 'This field is mandatory'
    ]
]);
```

🔀 Conditional Logic &amp; Multi-Step Forms
------------------------------------------

[](#-conditional-logic--multi-step-forms)

### Dynamic Field Visibility

[](#dynamic-field-visibility)

```
$form->add('account_type', 'select', [
    'label' => 'Account Type',
    'options' => [
        'personal' => 'Personal',
        'business' => 'Business'
    ]
])
->add('company_name', 'text', [
    'label' => 'Company Name',
    'show_if' => 'account_type:business',
    'validation' => 'required_if:account_type,business'
])
->add('tax_id', 'text', [
    'label' => 'Tax ID',
    'show_if' => 'account_type:business'
]);
```

### Multi-Step Forms

[](#multi-step-forms)

```
$multiStepForm = Form::create()
    ->multiStep(true)
    ->add('step1_name', 'text', [
        'label' => 'Name',
        'step' => 1
    ])
    ->add('step2_details', 'textarea', [
        'label' => 'Details',
        'step' => 2
    ])
    ->add('step3_confirmation', 'checkbox', [
        'label' => 'Confirm',
        'step' => 3
    ]);
```

📁 File Upload Features
----------------------

[](#-file-upload-features)

### Basic File Upload

[](#basic-file-upload)

```
$form->add('document', 'file', [
    'label' => 'Upload Document',
    'accept' => '.pdf,.doc,.docx',
    'maxSize' => '10MB',
    'required' => true
]);
```

### Image Upload with Cropping

[](#image-upload-with-cropping)

```
$form->add('profile_image', 'image', [
    'label' => 'Profile Picture',
    'crop' => true,
    'aspectRatio' => '1:1',
    'minWidth' => 400,
    'maxSize' => '5MB',
    'formats' => ['jpg', 'png', 'webp']
]);
```

### Gallery Upload

[](#gallery-upload)

```
$form->add('photos', 'gallery', [
    'label' => 'Photo Gallery',
    'maxFiles' => 10,
    'sortable' => true,
    'preview' => true,
    'uploadUrl' => '/upload/gallery'
]);
```

📦 Form Container - Managing Multiple Forms
------------------------------------------

[](#-form-container---managing-multiple-forms)

The Form Container allows you to manage multiple forms within a single interface, with support for tabbed, accordion, or stacked layouts.

### Basic Container Usage

[](#basic-container-usage)

```
use Litepie\Form\Facades\Form;

// Create a container with multiple forms
$container = Form::container('user-settings')
    ->name('User Settings')
    ->description('Manage your account settings')
    ->tabbed(true); // Use tabbed interface

// Add forms to the container
$profileForm = $container->createForm('profile', [
    'title' => 'Profile Information',
    'description' => 'Update your personal details'
]);

$profileForm
    ->add('first_name', 'text', ['label' => 'First Name', 'required' => true])
    ->add('last_name', 'text', ['label' => 'Last Name', 'required' => true])
    ->add('email', 'email', ['label' => 'Email', 'required' => true]);

$securityForm = $container->createForm('security', [
    'title' => 'Security Settings',
    'description' => 'Manage your password and security options'
]);

$securityForm
    ->add('current_password', 'password', ['label' => 'Current Password'])
    ->add('new_password', 'password', ['label' => 'New Password'])
    ->add('confirm_password', 'password', ['label' => 'Confirm Password']);

// Render the container
{!! $container->render() !!}
```

### Quick Container Creation

[](#quick-container-creation)

```
// Create multiple forms at once
$container = Form::quickContainer([
    'contact' => [
        'fields' => [
            'name' => 'text',
            'email' => ['type' => 'email', 'required' => true],
            'message' => ['type' => 'textarea', 'required' => true]
        ],
        'options' => ['action' => '/contact', 'method' => 'POST'],
        'containerOptions' => [
            'title' => 'Contact Information',
            'description' => 'Get in touch with us'
        ]
    ],
    'feedback' => [
        'fields' => [
            'rating' => ['type' => 'range', 'min' => 1, 'max' => 5],
            'suggestion' => 'textarea'
        ],
        'containerOptions' => [
            'title' => 'Feedback',
            'description' => 'Help us improve'
        ]
    ]
], [
    'name' => 'Contact & Feedback',
    'accordion' => true // Use accordion interface
]);
```

### Container Display Modes

[](#container-display-modes)

```
// Tabbed interface
$container->tabbed(true)->activeForm('step1');

// Accordion interface
$container->accordion(true);

// Stacked interface (default)
// Forms displayed one after another
```

### Container Validation Modes

[](#container-validation-modes)

```
// Individual validation (default) - each form validated separately
$container->validationMode('individual');

// Combined validation - all forms must pass
$container->validationMode('combined');

// Sequential validation - stops at first failure
$container->validationMode('sequential');
```

### Extended Container Classes

[](#extended-container-classes)

```
class RegistrationContainer extends \Litepie\Form\FormContainer
{
    public function __construct($app)
    {
        parent::__construct($app, 'registration');
        $this->setupRegistrationForms();
    }

    protected function setupRegistrationForms(): void
    {
        $this->name('User Registration')
             ->tabbed(true)
             ->validationMode('sequential');

        // Step 1: Personal Information
        $personal = $this->createForm('personal', [
            'title' => 'Personal Information',
            'icon' => 'user'
        ]);

        $personal
            ->add('first_name', 'text', ['required' => true])
            ->add('last_name', 'text', ['required' => true])
            ->add('email', 'email', ['required' => true]);

        // Step 2: Account Setup
        $account = $this->createForm('account', [
            'title' => 'Account Setup',
            'icon' => 'key'
        ]);

        $account
            ->add('password', 'password', ['required' => true])
            ->add('password_confirmation', 'password', ['required' => true]);
    }

    public function getProgress(): int
    {
        $totalSteps = $this->forms->count();
        $currentStep = array_search($this->getActiveForm(), $this->getFormKeys());
        return (int)(($currentStep + 1) / $totalSteps * 100);
    }
}

// Usage
$registrationContainer = new RegistrationContainer(app());
echo $registrationContainer->render();
```

📚 **See [doc/container-examples.md](doc/container-examples.md) for comprehensive container usage examples.**

🌐 Laravel Integration
---------------------

[](#-laravel-integration)

### Controller Example

[](#controller-example)

```
class ContactController extends Controller
{
    public function create()
    {
        $form = Form::create()
            ->action(route('contact.store'))
            ->method('POST')
            ->add('name', 'text', ['required' => true])
            ->add('email', 'email', ['required' => true])
            ->add('submit', 'submit', ['value' => 'Send']);

        return view('contact.create', compact('form'));
    }

    public function store(Request $request)
    {
        // Form validation is automatic
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|email'
        ]);

        // Process the form...

        return redirect()->back()->with('success', 'Message sent!');
    }
}
```

### Blade Template Integration

[](#blade-template-integration)

```
@extends('layouts.app')

@section('content')

    Contact Us

    @if(session('success'))

            {{ session('success') }}

    @endif

    {!! $form->render() !!}

@endsection

@push('styles')
    {!! form_include_assets(true, false) !!}
@endpush

@push('scripts')
    {!! form_include_assets(false, true) !!}
@endpush
```

🚀 Client-Side Framework Integration
-----------------------------------

[](#-client-side-framework-integration)

### Convert Forms to Arrays/JSON for Vue.js, React, Angular

[](#convert-forms-to-arraysjson-for-vuejs-react-angular)

```
// Convert existing form to array
$form = Form::create()
    ->add('name', 'text', ['required' => true])
    ->add('email', 'email', ['required' => true]);

$formArray = $form->toArray();
$formJson = $form->toJson();

// Or use helper functions
$formArray = form_array([
    'name' => ['type' => 'text', 'label' => 'Name', 'required' => true],
    'email' => ['type' => 'email', 'label' => 'Email', 'required' => true]
], [
    'action' => '/api/contact',
    'method' => 'POST'
]);

$formJson = form_json($fields, $options);
```

### API Endpoint for Client-Side

[](#api-endpoint-for-client-side)

```
// Return form schema as JSON for Vue/React/Angular
Route::get('/api/forms/contact', function() {
    return form_array([
        'name' => ['type' => 'text', 'label' => 'Name', 'required' => true],
        'email' => ['type' => 'email', 'label' => 'Email', 'required' => true],
        'message' => ['type' => 'textarea', 'label' => 'Message', 'required' => true]
    ], [
        'action' => '/api/contact',
        'method' => 'POST'
    ]);
});
```

### Vue.js Example

[](#vuejs-example)

```

      {{ field.label }}

    Submit

export default {
  data() {
    return {
      formFields: {},
      formData: {}
    }
  },
  async mounted() {
    const response = await fetch('/api/forms/contact')
    const schema = await response.json()
    this.formFields = schema.fields

    // Initialize form data
    Object.keys(this.formFields).forEach(field => {
      this.$set(this.formData, field, '')
    })
  }
}

```

📚 **See [doc/client-side-examples.md](doc/client-side-examples.md) for complete Vue.js, React, and Angular integration examples.**

🎨 Theming &amp; Customization
-----------------------------

[](#-theming--customization)

### Custom Field Templates

[](#custom-field-templates)

Create custom field templates in `resources/views/forms/`:

```

        {{ $field->getLabel() }}
        @if($field->isRequired())
            *
        @endif

    getAttributesString() !!}>

    @if($field->hasErrors())
        {{ $field->getFirstError() }}
    @endif

    @if($field->getHelp())
        {{ $field->getHelp() }}
    @endif

```

### Custom CSS Classes

[](#custom-css-classes)

```
$form->add('name', 'text', [
    'class' => 'custom-input large',
    'wrapper_class' => 'custom-wrapper',
    'label_class' => 'custom-label'
]);
```

🔧 Advanced Features
-------------------

[](#-advanced-features)

### AJAX Form Submission

[](#ajax-form-submission)

```
$form = Form::create()
    ->ajax(true)
    ->action('/api/contact')
    ->onSuccess('handleSuccess')
    ->onError('handleError')
    ->add('name', 'text', ['required' => true]);
```

### Form Validation Events

[](#form-validation-events)

```
document.addEventListener('form:validation:success', function(event) {
    console.log('Form validated successfully', event.detail);
});

document.addEventListener('form:validation:error', function(event) {
    console.log('Validation errors', event.detail.errors);
});
```

### Dynamic Field Addition

[](#dynamic-field-addition)

```
$form = Form::create()
    ->add('base_field', 'text')
    ->addIf($condition, 'conditional_field', 'text')
    ->addWhen('user_type', 'business', function($form) {
        $form->add('company_name', 'text', ['required' => true]);
        $form->add('tax_id', 'text');
    });
```

🧪 Testing
---------

[](#-testing)

The package includes comprehensive test coverage:

```
# Run all tests
composer test

# Run specific test suite
composer test -- --filter=FormBuilderTest

# Run with coverage
composer test -- --coverage-html coverage
```

### Writing Tests for Your Forms

[](#writing-tests-for-your-forms)

```
class ContactFormTest extends TestCase
{
    /** @test */
    public function it_validates_contact_form()
    {
        $form = Form::create()
            ->add('name', 'text', ['required' => true])
            ->add('email', 'email', ['required' => true]);

        $this->assertTrue($form->validate([
            'name' => 'John Doe',
            'email' => 'john@example.com'
        ]));

        $this->assertFalse($form->validate([
            'name' => '',
            'email' => 'invalid-email'
        ]));
    }
}
```

📚 API Reference
---------------

[](#-api-reference)

### FormBuilder Methods

[](#formbuilder-methods)

#### Configuration

[](#configuration)

```
$form->action(string $action)              // Set form action URL
$form->method(string $method)              // Set HTTP method (POST, GET, etc.)
$form->files(bool $enabled = true)         // Enable file uploads
$form->theme(string $theme)                // Set UI framework (bootstrap5, tailwind)
$form->ajax(bool $enabled = true)          // Enable AJAX submission
$form->multiStep(bool $enabled = true)     // Enable multi-step forms
```

#### User &amp; Permissions

[](#user--permissions)

```
$form->forUser(object $user)               // Set user for visibility checks
$form->getUser()                           // Get current user
```

#### Caching

[](#caching)

```
$form->cache(int $ttl = 3600)             // Enable caching with TTL
$form->cached()                            // Check if caching is enabled
$form->withoutCache()                      // Disable caching
$form->clearCache()                        // Clear form cache
```

#### Field Management

[](#field-management)

```
$form->add(string $name, string $type, array $options = [])  // Add field
$form->remove(string $name)                                   // Remove field
$form->has(string $name)                                      // Check if field exists
$form->get(string $name)                                      // Get field instance
```

#### Layout &amp; Organization

[](#layout--organization)

```
$form->row(array $fields, ?string $id = null)                                    // Add fields in a row
$form->group(string $id, ?string $title = null, ?string $description = null)    // Start group
$form->section(string $id, ?string $title = null, ?string $description = null)  // Start section
$form->endGroup()                                                                 // End current group
$form->endSection()                                                               // End current section
$form->divider(?string $label = null)                                            // Add divider
$form->defaultWidth(int $width)                                                   // Set default field width
```

#### Data Handling

[](#data-handling)

```
$form->populate(array $data)               // Populate form with data
$form->validate(array $data)               // Validate form data
$form->getValidationRules()                // Get all validation rules
```

#### Rendering &amp; Output

[](#rendering--output)

```
$form->render(?object $user = null)        // Render HTML (respects visibility)
$form->toArray(?object $user = null)       // Convert to array (respects visibility)
$form->toJson(?object $user = null)        // Convert to JSON (respects visibility)
$form->visibleFields(?object $user = null) // Get visible fields only
$form->renderField(string $name)           // Render single field
$form->renderErrors()                      // Render validation errors
```

### Field Options

[](#field-options)

```
[
    'label' => 'Field Label',
    'placeholder' => 'Enter value...',
    'help' => 'Help text',
    'required' => true,
    'validation' => 'required|string|max:255',
    'class' => 'custom-class',
    'attributes' => ['data-custom' => 'value'],
    'show_if' => 'other_field:value',
    'hide_if' => 'other_field:value',
    'value' => 'default value'
]
```

🤝 Contributing
--------------

[](#-contributing)

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

### Development Setup

[](#development-setup)

```
git clone https://github.com/litepie/form.git
cd form
composer install
composer test
```

### Code Style

[](#code-style)

```
composer format      # Fix code style
composer format:check # Check code style
composer analyse     # Static analysis
composer ci          # Run all checks
```

📄 License
---------

[](#-license)

The MIT License (MIT). Please see [LICENSE](LICENSE) for more information.

⚡ Performance &amp; Caching
---------------------------

[](#-performance--caching)

### Caching Support

[](#caching-support)

Form containers support comprehensive caching to improve performance:

```
// Enable caching with custom TTL
$container = Form::container('user-settings')
    ->enableCache(3600) // 1 hour
    ->cacheTags(['user_forms', 'settings']);

// Configure cache settings
$container->cache([
    'enabled' => true,
    'ttl' => 1800, // 30 minutes
    'driver' => 'redis',
    'tags' => ['forms', 'containers'],
]);

// Cache is automatically applied to:
// - render() - Caches full HTML output
// - renderSingleForm() - Caches individual form HTML
// - toArray() - Caches array representation
// - getVisibleForms() - Caches filtered collections

// Manual cache management
$container->clearCache(); // Clear all cache for this container
$container->disableCache(); // Temporarily disable caching
```

### Cache Configuration

[](#cache-configuration)

Add to your `config/form.php`:

```
'cache' => [
    'enabled' => env('FORM_CACHE_ENABLED', true),
    'ttl' => env('FORM_CACHE_TTL', 3600),
    'driver' => env('FORM_CACHE_DRIVER', 'redis'),
    'prefix' => 'form_cache',
    'tags' => ['forms', 'containers'],
    'auto_clear_on_update' => true,
],
```

### Cache Benefits

[](#cache-benefits)

- **50-90% faster rendering** for complex forms
- **Reduced server load** with cached HTML output
- **Automatic invalidation** when forms are modified
- **Tagged cache** for efficient bulk clearing
- **Multiple drivers** (file, redis, memcached)

For detailed caching documentation, see [doc/caching.md](doc/caching.md).

� Documentation
---------------

[](#-documentation)

- **[Examples](doc/examples.md)** - Comprehensive examples for all field types and features
- **[Container Examples](doc/container-examples.md)** - Multi-form container usage and patterns
- **[Client-Side Examples](doc/client-side-examples.md)** - JavaScript integration and API usage
- **[Caching Guide](doc/caching.md)** - Performance optimization with caching

�🔒 Security
-----------

[](#-security)

If you discover security vulnerabilities, please send an email to  instead of using the issue tracker.

📞 Support
---------

[](#-support)

- 📖 [Documentation](https://litepie.com/docs/form)
- 🐛 [Issue Tracker](https://github.com/Litepie/Form/issues)
- 💬 [Discussions](https://github.com/Litepie/Form/discussions)
- 📧 [Email Support](mailto:support@litepie.com)

---

🏢 About
-------

[](#-about)

This package is part of the **Litepie** ecosystem, developed by **Renfos Technologies**.

### Organization Structure

[](#organization-structure)

- **Vendor:** Litepie
- **Framework:** Lavalite
- **Company:** Renfos Technologies

### Links &amp; Resources

[](#links--resources)

- 🌐 **Website:**
- 📚 **Documentation:**
- 💼 **Company:**
- 📧 **Support:**

---

🤖 For AI Assistants
-------------------

[](#-for-ai-assistants)

**Quick Context File**: [.ai-context.md](.ai-context.md) - Comprehensive package structure and patterns
**Architecture Pattern**: Fluent Builder + Factory + Service Provider
**Key Classes**: `FormBuilder`, `Field`, `FormRenderer`, `FormValidator`
**Main Features**: Visibility Control, Caching, Hierarchical Organization, Grid Layout
**Output Formats**: HTML (`render()`), Array (`toArray()`), JSON (`toJson()`)
**Integration**: Laravel 11+/12+, Bootstrap/Tailwind, Vue/React/Angular

**Common User Requests**:

- "Create form" → `Form::create()->add()->render()`
- "Hide field from users" → `->can('permission')` or `->roles(['admin'])`
- "Improve performance" → `->cache(ttl)`
- "Responsive layout" → `->row([Field::text()->col(6), ...])`
- "Complex sections" → `->group()->section()->row()`
- "JSON for frontend" → `->toArray()` or `->toJson()`

---

**Built with ❤️ by Renfos Technologies**

*Empowering developers with robust Laravel solutions*

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance83

Actively maintained with recent releases

Popularity10

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~10 days

Total

19

Last Release

89d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1788735?v=4)[Renfos Technologies](/maintainers/Renfos)[@Renfos](https://github.com/Renfos)

---

Top Contributors

[![georgemjohn](https://avatars.githubusercontent.com/u/7950080?v=4)](https://github.com/georgemjohn "georgemjohn (23 commits)")

---

Tags

laravelvalidationuiperformancecomponentscachingtailwindbootstrapformaccessibilityform-builderform-container

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/litepie-form/health.svg)

```
[![Health](https://phpackages.com/badges/litepie-form/health.svg)](https://phpackages.com/packages/litepie-form)
```

###  Alternatives

[spatie/laravel-responsecache

Speed up a Laravel application by caching the entire response

2.8k8.2M51](/packages/spatie-laravel-responsecache)[proengsoft/laravel-jsvalidation

Validate forms transparently with Javascript reusing your Laravel Validation Rules, Messages, and FormRequest

1.1k2.3M49](/packages/proengsoft-laravel-jsvalidation)[robsontenorio/mary

Gorgeous UI components for Livewire powered by daisyUI and Tailwind

1.5k454.7k15](/packages/robsontenorio-mary)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
