Download the PHP package ramondev/formcraft without Composer

On this page you can find all versions of the php package ramondev/formcraft. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package formcraft

Formcraft — Complete Usage Guide

Formcraft is a declarative form library for Laravel. You declare a form's fields once as a PHP class, and Formcraft handles HTML rendering, server-side validation, theming (Bootstrap/Tailwind/your own), file uploads, model binding, repeated field groups, and multi-step wizards.

This guide covers everything needed to use the package day to day: install, build forms, render them, validate and save data, upload files, theme them, and wire up wizards — based on the actual package source (ramondev/formcraft).


Table of contents

  1. Installation
  2. Quick start
  3. Defining fields
  4. Field option reference
  5. Rendering a form
  6. Validating a submission
  7. Reading submitted values
  8. Saving to an Eloquent model
  9. File & image uploads
  10. Group fields (nested/repeated data)
  11. Form Sets ("add another" repeated forms)
  12. Multi-step wizards (FormWizard)
  13. Theming
  14. Customizing a form at runtime
  15. Artisan commands
  16. Full worked example
  17. Behavior notes & gotchas

1. Installation

Install Formcraft straight from Composer:

FormServiceProvider registers automatically via Laravel package auto-discovery — no manual config/app.php edit needed. After installing, php artisan list should show make:form and make:theme.

To update to a newer version later:

Requirements: PHP ^8.1, Laravel (illuminate/*) ^10–^13, and intervention/image ^4.2 (used for resizing image uploads).


2. Quick start

Every form is a class extending Formcraft\FormProcessor that implements setFields():

In a controller:

In a Blade view, just echo the form — every field renders itself:

You can also scaffold a new form with Artisan (see §15):


3. Defining fields

setFields() must return a LaravelFormTemplate, built from a closure that receives a FormFields builder and returns an associative array of field_name => $f->SomeField(...). The array key is the field's name (used for the HTML name/id, the validation key, and the model attribute on save).

Available field builders

Method Renders as Notes
InputField(type: ...) <input type="..."> Generic — set any HTML input type yourself
CharField() <input type="text"> Plain text
EmailField() <input type="email"> Adds an email validation rule automatically
PasswordField() <input type="password"> Not cached in old() by default; can auto-hash (see below)
IntegerField() <input type="number"> Adds a numeric validation rule automatically
DateField() <input type="date"> Adds a date validation rule automatically
CheckBoxField() <input type="checkbox"> Use checked/value to control state
RadioField() <input type="radio"> Render several with the same field name and different value
TextareaField() <textarea>
SelectField() <select> Pass options (see below)
FileField() <input type="file"> Handles uploads through FileManager
ImageField() <input type="file"> FileField specialised for images — restricts accept, supports resizing/thumbnails
GroupField() wraps child fields in a <fieldset> Nesting / repeating structures — see §10

4. Field option reference

Every builder above shares this common set of keyword arguments (pass only the ones you need — all have sensible defaults):

Option Type Default Purpose
required bool true Adds HTML required + a required validation rule
requiredIf callable(array $submittedData): bool null Dynamically overrides required per-submission (both the rendered attribute and the validation rule)
label string field name, prettified Visible label/legend text
showLabel bool true Set false to skip rendering a label entirely
labelAttr array [] Extra HTML attributes on the <label>/<legend> (e.g. ['class' => 'font-bold'])
attr array [] Extra HTML attributes on the input itself
value string "" A fixed value to render (overridden by cached/old input and initial values when applicable)
default mixed or callable null Fallback value used only when there's no submitted/initial value
id string field name Override the HTML id
placeholder string null Placeholder text
minLength / maxLength int null Adds minlength/maxlength HTML attrs + min:/max: validation rules
pattern string null HTML pattern attribute
autocomplete string null HTML autocomplete attribute
datalist array [] List of suggestion strings; renders a <datalist> and wires it via list=
readonly / disabled bool null HTML flags
cache bool true (false for PasswordField) Whether to repopulate the field from Laravel's old() input after a failed submission
translate bool false Runs the label/placeholder through Laravel's __() helper
widget callable(ObjectClass $fields): string null Fully custom renderer for this one field — bypasses the active theme entirely
ignore bool false Excludes the field from rendering, validation, values(), and save()
saveAs string null Model attribute (or dotted relation path, e.g. "profile.bio") to write this field's value to on save()
validate callable(ObjectClass $submittedData): true\|string null Custom validation callback; return true to pass or an error string to fail
validateRule array [] Extra Laravel validation rule strings/objects appended to the auto-generated rules
validateMessageRule array [] Custom Laravel validation messages, passed straight to Validator::make()
validateMessageAttribute string|callable null Custom :attribute name used inside validation messages. For a multiple: true field (e.g. 'photo[]' => $f->ImageField(multiple: true, ...)) a plain string covers both the field's own key and the per-item wildcard rules. Pass a fn (int $index): string instead to name each item individually — e.g. fn ($i) => 'Photo ' . ($i + 1) turns the default photo.0 into Photo 1, photo.1 into Photo 2, and so on, based on how many items were actually submitted.

Type-specific options

DateField

PasswordField

IntegerField

SelectField

FileField

ImageField

Example — a multi-photo upload capped at 4 files, 2 required minimum, each up to 2MB, with a friendly attribute name in every validation message:

The [] suffix on the field key is what tells the browser to submit multiple files under the same name; internally Formcraft strips it, so $form->values()->photo and error messages both refer to the field as photo, not photo[].

Want each photo named individually instead of one shared name (so a message reads "Photo 2 must be an image" rather than "Photos must be an image")? Pass a callable instead of a string — it's called once per submitted file with that file's index:

This turns the default photo.0 / photo.1 / ... keys Laravel would otherwise show into Photo 1 / Photo 2 / ... in every message for that item. It works the same way on an array-typed GroupField's own validateMessageAttribute (naming each row, e.g. "Row 1", "Row 2").

GroupField


5. Rendering a form

Whole form at once — a FormProcessor instance has a __toString(), so you can just echo/print it (e.g. {!! $form !!} in Blade). Each field is wrapped and rendered according to the active theme.

One field at a time — access any field as a property to get a compiled object with ->label, ->input, and ->errors:

Each of ->label, ->input also has its own __toString(), so you can echo them directly ({!! $form->email->input !!}), or read finer detail off them: $form->email->input->name, ->id, ->value, ->is_required, etc.


6. Validating a submission

If you render the form again after a failed submission (without redirecting), fields marked cache: true (the default, except PasswordField) automatically repopulate from Laravel's old() input.


7. Reading submitted values

values() resolves each field's submitted value — including matching a SelectField's stored option back to its declared value, and substituting uploaded files with their generated filenames once uploadFiles() has run.

Detecting changes against an initial value (e.g. an edit form pre-filled via initialValue()):


8. Saving to an Eloquent model

save() copies every fillable field's resolved value onto the bound model (calling ->save() on it at the end). Control exactly what gets copied:

setModelAttribute() performs the copy without calling ->save(), if you need to do more to the model first.

Passwords: a PasswordField with hashValue: true (the default) is automatically run through Hash::make() when copied onto the model.


9. File & image uploads

Basic upload

Declare the field:

Then, in your controller, explicitly trigger the upload (this is a separate step from validation/save, so you control exactly when files hit disk):

Custom filenames

By default an uploaded file gets an auto-generated unique name. Set filename to force your own instead — the original extension is appended automatically if you don't include one:

Thumbnails: separate folder, own filename, deletable, saved to the DB

Add thumbnail (the resize dimensions) to have a thumbnail generated alongside the main upload. Four more options give you full control over it:

With thumbnail set, the field's resolved value is no longer a plain filename string — it becomes ['filename' => ..., 'thumbnail' => ...], so:

thumbnailSaveAs makes save() write both filenames onto the model in one call — the main filename to the field's usual saveAs, and the thumbnail's filename to whatever attribute thumbnailSaveAs names:

If a field has thumbnail set but no thumbnailSaveAs, only the main filename is written on save — the thumbnail filename is still available via values()/getUploadedFiles() if you want to handle it yourself.

Using FileManager directly

Under the hood, uploads go through Formcraft\FileManager, which you can also use standalone (e.g. outside of a form, for an ad-hoc upload):

Every FileManager method can also be called statically, e.g. FileManager::removeFile('uploads/avatars/old.jpg').


10. Group fields (nested/repeated data)

Use GroupField to nest several fields under one key.

Plain grouping (valueType: "all", the default) — just visual/logical grouping; children behave like normal top-level fields:

Repeated/array data (valueType: "array") — for something like "add up to N line items", where the submitted HTML uses array-style names (items[0][name], items[1][name], ...) and the group's resolved value is an array of child arrays:

Here, minLength/maxLength cap the number of rows (1 to 5 items), and validateMessageAttribute renames "items"/"items.*" to "Line items" in error messages, while the name field's own validateMessageAttribute renames just "items.name" to "Item name".

Validation rules for array-typed groups are generated per index automatically (items.*.name, items.*.qty), and values()/save() flatten group children's values into the top-level result, so $form->values()->items gives you the full array of rows.

Groups can be nested inside groups; access a nested field's props at definition time via a "parent/child" path with changeProps() (see §14).


11. Form Sets ("add another" repeated forms)

FormSet builds several independent copies of a whole FormProcessor class — useful when each "row" needs its own full validation/theme rather than being one group of fields.

Key FormSet methods:

Method Purpose
set(): FormProcessor[] Every instance, ready to render (->setId/->setName populated)
getField(int $index): ?FormProcessor One specific instance
initialValue(array $values) Pre-fill each instance from $values[$index]
setTheme($theme) Apply one theme to every instance
validate(array $data, array $files = []) Splits a flat submission back out per-instance by its {label}_{index}_ name prefix
is_validated(): bool True only if every instance validates
errors(): ObjectClass ->all()/->messages()/->first()/->last(), each keyed by index; ->toListKey() flattens to "field.index" => message"
uploadFiles() Uploads files for every instance
save(): array Saves every instance, keyed by index
removeField(int $id) Drop an instance (e.g. "remove this row")
changeProps(int $index, string $key, $value) Tweak one instance's field
each(callable $callback) Run $callback($form) against every instance (e.g. to setModel() on each) — a beforeProcess() alias also exists for backward compatibility

Redisplaying errors after a failed submission

A FormSet you build to render the page (e.g. in your create() action) is a fresh set of FormProcessor instances — it has no memory of a previous failed validate() call, even one from the very same request cycle a moment ago. If you return back()->withErrors(...)->withInput() after validation fails and then redisplay the page, its errors won't show up unless you explicitly re-validate the new instances from the flashed old() input:

This mirrors what FormWizard::form() already does internally for a single step. If your view tracks a dynamic row count (an "add row" button), also flash/read that count (e.g. a hidden item_count input) so the redisplay rebuilds the same number of rows the person actually submitted.


12. Multi-step wizards (FormWizard)

FormWizard drives a sequence of FormProcessor "steps" — one submitted and validated at a time, stored in the session, with everything available once all steps are complete.

Other methods: stepKeys(), completedSteps(), goToStep($step) (jump back, un-completing that step and everything after it — stored data is kept so it still pre-fills), and reset() (clear all progress).


13. Theming

A theme controls the CSS classes injected into labels/inputs and how a field's label/input/errors are wrapped together — without you touching your field definitions.

Built-in themes

Theme Class Style
Plain (default) Formcraft\Support\PlainTheme No CSS framework — the library's original bare markup
Bootstrap 5 Formcraft\Support\BootstrapTheme .form-label/.form-control/.form-select, .form-check-* for checkboxes/radios, .invalid-feedback errors
Tailwind Formcraft\Support\TailwindTheme Utility classes directly on elements — no build step or @tailwindcss/forms plugin required
Card (example) Formcraft\Support\CardTheme A framework-free "floating card" style meant to be copied and adapted

Applying a theme

Per instance:

As a form's standing default, override defaultTheme() in your FormProcessor subclass:

A field's own widget option (§4) always wins over the theme for that one field — it bypasses theming entirely.

Writing your own theme

Implement Formcraft\Support\FormTheme (or run php artisan make:theme YourName — see §15):


14. Customizing a form at runtime

These let you tweak an already-defined form on a per-instance basis, without touching setFields():

Method Purpose
appendFields(callable $callback) Add extra fields: $form->appendFields(fn ($f) => ['extra' => $f->CharField()]);
changeProps(string $key, array $keyValue) Override one or more props on an existing field: $form->changeProps('email', ['required' => false]); — for a nested group field, use a "parent/child" path
changeFieldName(array $mapping) Rename how a field's input/data key is looked up (useful when the submitted payload uses different keys than your field names)
changeSaveKey(array $mapping) See §8 — redirect where a field's value is written on save()
setFillableAttribute / setExceptAttribute / addToExceptAttribute See §8
setDefaultAttributeValue(array $default) See §8
initialValue(object\|array $value) Pre-fill fields (and enable dirty()/isDirty()) from an existing record

15. Artisan commands

make:form — scaffold a new form class

Option Purpose
--fields="key:type,..." Pre-populate fields; recognized types: char/text, email, password, integer/int/number, date, checkbox, radio, textarea, select, file, image, group
--theme=BootstrapTheme Adds a defaultTheme() override to the generated class (accepts a short name resolved under Formcraft\Support\, or a fully-qualified class name)
--path=Forms Where under app/ to place the class (default app/Forms)
--namespace= Override the namespace instead of deriving it from --path
--force Overwrite an existing file

make:theme — scaffold a new theme class

Generates a class implementing FormTheme with all three required methods stubbed out and commented, under app/{--path} (default app/Themes).


16. Full worked example

Form definition (app/Forms/RegistrationForm.php):

Controller:

Blade view (resources/views/register.blade.php):

That's it — Formcraft renders every field with Bootstrap classes, validates on submit, uploads and resizes the avatar, hashes the password, and saves the new User.


17. Behavior notes & gotchas

A few implementation details worth knowing as you use the package:


All versions of formcraft with dependencies

PHP Build Version
Package Version
Requires php Version ^8.1
illuminate/support Version ^10.0|^11.0|^12.0|^13.0
illuminate/console Version ^10.0|^11.0|^12.0|^13.0
illuminate/validation Version ^10.0|^11.0|^12.0|^13.0
illuminate/http Version ^10.0|^11.0|^12.0|^13.0
intervention/image Version ^4.2
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package ramondev/formcraft contains the following files

Loading the files please wait ...