PHPackages                             preflow/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. [Utility &amp; Helpers](/categories/utility)
4. /
5. preflow/form

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

preflow/form
============

Preflow form builder — field rendering, model binding, hypermedia integration

v0.13.1(1mo ago)04MITPHPPHP &gt;=8.4

Since Apr 17Pushed 1mo agoCompare

[ Source](https://github.com/getpreflow/form)[ Packagist](https://packagist.org/packages/preflow/form)[ RSS](/packages/preflow-form/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (3)Versions (3)Used By (0)

preflow/form
============

[](#preflowform)

Form builder for Preflow. Renders fields with labels, errors, and help text from a simple template API. Binds to models, reads `#[Validate]` attributes for type inference and required detection, and auto-enhances forms with inline validation when a hypermedia driver is active.

Installation
------------

[](#installation)

```
composer require preflow/form
```

Requires `preflow/validation` and `preflow/view`. Optionally integrates with `preflow/data` (model binding) and `preflow/htmx` (inline validation).

Quick Start
-----------

[](#quick-start)

### Plain form (no model)

[](#plain-form-no-model)

```
{% set form = form_begin({action: '/contact', csrf_token: csrf_token()}) %}
{{ form.begin()|raw }}
    {{ form.field('name')|raw }}
    {{ form.field('email', {type: 'email'})|raw }}
    {{ form.field('message', {type: 'textarea'})|raw }}
    {{ form.submit('Send')|raw }}
{{ form_end()|raw }}
```

### Model-bound form (inside a component)

[](#model-bound-form-inside-a-component)

```
{% set form = form_begin({model: game, errorBag: errors}) %}

    {{ form.field('name')|raw }}
    {{ form.select('status', {options: {draft: 'Draft', published: 'Published'}})|raw }}
    {{ form.field('description', {type: 'textarea'})|raw }}
    {{ form.submit('Save')|raw }}

```

The form builder reads `#[Validate]` attributes from the model to infer input types (`email` rule = `type="email"`), detect required fields, and populate select options from `in:` rules.

Field Methods
-------------

[](#field-methods)

MethodDescription`form.field(name, options)`Text, email, password, number, date, url, tel, hidden`form.select(name, options)`Dropdown with `options` map`form.checkbox(name, options)`Single checkbox`form.radio(name, options)`Radio group`form.file(name, options)`File upload input`form.hidden(name, value)`Hidden input (no label/wrapper)`form.submit(label, options)`Submit buttonField Options
-------------

[](#field-options)

OptionDescription`type`Input type (auto-inferred from model rules if bound)`label`Label text (auto-generated from field name if omitted)`value`Field value (falls back to old input, then model property)`required`Required indicator (auto-detected from `required` rule)`help`Help text below the field`errors`Error messages (auto-populated from ErrorBag)`attrs`Raw HTML attributes passed to the input (escape hatch)`width`Width hint for use inside groups (`'1/3'`, `'2/3'`)`options`Key-value map for select/radio fieldsField Groups
------------

[](#field-groups)

Group fields for side-by-side layout:

```
{{ form.group({class: 'form-row', label: 'Address'})|raw }}
    {{ form.field('zip', {width: '1/3'})|raw }}
    {{ form.field('city', {width: '2/3'})|raw }}
{{ form.endGroup()|raw }}
```

Auto-Generation
---------------

[](#auto-generation)

Generate fields from model `#[Validate]` attributes:

```
{# All validated fields #}
{{ form.fields()|raw }}

{# Cherry-pick #}
{{ form.fields({only: ['name', 'email']})|raw }}

{# Exclude #}
{{ form.fields({except: ['password_hash', 'created_at']})|raw }}

{# Override specific fields #}
{{ form.fields({only: ['name', 'email', 'role'], override: {role: {type: 'select', options: roles}}})|raw }}
```

Validation Scenarios
--------------------

[](#validation-scenarios)

Override rules per form for create/update differences:

```
{% set form = form_begin({
    model: user,
    rules: isEdit
        ? {password: ['nullable', 'min:8']}
        : {password: ['required', 'min:8']}
}) %}
```

Or use `on:` directives on the model:

```
#[Validate('required', 'min:8', 'on:create')]
#[Validate('nullable', 'min:8', 'on:update')]
public string $password = '';
```

```
{% set form = form_begin({model: user, scenario: 'create'}) %}
```

Hypermedia Integration
----------------------

[](#hypermedia-integration)

When inside a component with a hypermedia driver active, the form builder can auto-add inline validation attributes. The `attrs` escape hatch lets you pass any driver-specific attributes:

```
{{ form.field('email', {
    attrs: {
        'hx-post': validateUrl,
        'hx-trigger': 'blur delay:300ms',
        'hx-target': 'closest .form-group',
        'hx-swap': 'outerHTML'
    }
})|raw }}
```

License
-------

[](#license)

MIT

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance89

Actively maintained with recent releases

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity42

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 ~0 days

Total

2

Last Release

53d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/6d8b54efbc79683c32645e3fa8d3590037fa003963a16e0ed989104c6f4a2723?d=identicon)[smyr](/maintainers/smyr)

---

Top Contributors

[![smeyerme](https://avatars.githubusercontent.com/u/1925560?v=4)](https://github.com/smeyerme "smeyerme (8 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[components/highlightjs

Highlight.js highlights syntax in code examples on blogs, forums and in fact on any web pages.

102210.6k10](/packages/components-highlightjs)[dazet/data-map

Library for mapping data structures.

2024.3k](/packages/dazet-data-map)

PHPackages © 2026

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