Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Form Extensions Bundle Laravel Package

fsi/form-extensions-bundle

FSi Form Extensions Bundle adds reusable extensions to Symfony's Form component, helping developers reduce boilerplate and build richer, more flexible forms. It integrates smoothly into Symfony apps and standard form workflows, with helpers designed to simplify common form customization tasks.

View on GitHub
Deep Wiki
Context7

Getting Started

Be clear about what this is before you commit any time: fsi/form-extensions-bundle is a Symfony bundle, not a Laravel package. It ships a Bundle class, a DependencyInjection extension, Twig form themes, and JS assets registered through Symfony's AssetsExtension. There is no service provider, no facade, no Blade views, and Laravel's package auto-discovery will do nothing with it. So "getting started" splits into two realistic tracks.

Track A — you're actually in a Symfony app (the intended use).

composer require fsi/form-extensions-bundle

Register the bundle in config/bundles.php:

FSi\Bundle\FormExtensionsBundle\FSiFormExtensionsBundle::class => ['all' => true],

Install the assets so the JS/CSS lands under public/bundles/fsiformextensions/:

php bin/console assets:install --symlink
php bin/console debug:form   # confirm the new types are registered

Add a first type. The fastest win is either MaskedTextType (drop-in replacement for TextType with an input mask) or a sortable collection:

$builder
    ->add('phone', MaskedTextType::class, ['mask' => '(999) 999-9999'])
    ->add('items', CollectionType::class, [
        'entry_type' => ItemType::class,
        'allow_add'  => true,
        'allow_delete' => true,
        'sortable'   => true,
    ]);

Track B — you're a Laravel developer evaluating it. The honest first step is to read the source, not install it. The bundle is small: Form/Type/*, Form/Extension/*, Resources/views/Form/*.html.twig, and Resources/public/js/*. Everything valuable is (a) a form type class that composes a widget + hidden inputs, and (b) a small vanilla/jQuery script that wires the widget. That port surface is a few hundred lines. If you want Symfony's Form component in Laravel at all, you'd be pulling symfony/form + symfony/twig-bridge and hand-wiring CSRF/session — at which point most teams pick laravel-form-builder, Filament, or Livewire instead.

Start by reading Form/Type/MapPickerType.php and Resources/public/js/form-extensions/map-picker.js — that pair is the clearest example of the bundle's whole architecture and the easiest to reimplement in Blade + Alpine.

Implementation Patterns

Form types as value objects. The bundle's types map a compound widget to a single data object. MapPickerType binds to an object exposing getLatitude()/getLongitude() (or an array with lat/lng), renders a map container, and keeps two hidden inputs in sync via JS. Pattern to copy: the PHP type declares the children and the view; the JS never owns state, it only writes into hidden fields so server-side validation stays authoritative.

Opt-in collection behaviour via type options. The real day-to-day usage is not new types but new options on CollectionType/FileType:

->add('attachments', CollectionType::class, [
    'entry_type' => FileType::class,
    'sortable'   => true,   // drag-and-drop reorder
    'stepped'    => true,   // wizard-style one-at-a-time
]);

These are implemented as FormTypeExtension classes, which means they apply to every CollectionType in the app by default and are only active when the option is truthy. That's the extension point to reuse: a type extension + a data attribute on the root element + a delegated JS listener.

Twig form theme, not per-field markup. Rendering is centralized:

{% form_theme form '@FSiFormExtensionsBundle/Form/fields.html.twig' %}

Override individual blocks (map_picker_widget, collection_sortable_widget) in your own theme rather than editing vendor templates. Note the old FSiFormExtensionsBundle:Form:fields.html.twig colon syntax appears in older docs — on Twig 3 use the @Bundle/path form.

Asset pipeline integration. In a Symfony app using Encore, don't rely on assets:install; import the sources directly:

import 'fsi/form-extensions-bundle/Resources/public/js/form-extensions/collection-sortable';

In a Laravel port, the equivalent is a Vite entry per widget, with the JS reading data-* attributes rendered by the Blade component so nothing is hardcoded.

Config toggles per environment. The DI extension exposes fsi_form_extensions: config (map provider/API key, enabling individual extensions). Keep the Google Maps key out of the bundle config and in .env, and check which extensions can be disabled so test environments aren't loading Leaflet/Maps JS during functional tests.

Porting pattern for Laravel. Mirror the type/JS split with Blade components and Alpine:

<x-form.map-picker name="location" :value="$model->location" provider="leaflet" />

The component renders <div data-map-picker> plus two hidden inputs; a single Alpine component initializes Leaflet, syncs the center marker to the hidden inputs on moveend. Same contract, no Symfony.

Gotchas and Tips

  • It will not boot in Laravel. composer require succeeds (it's just PHP), but FSiFormExtensionsBundle extends Symfony\Component\HttpKernel\Bundle\Bundle and expects framework-bundle services. If you accidentally leave it in a mixed app, remove it from config/bundles.php — Laravel won't complain about the missing register() method, but any code path touching its types will fatal on missing form.factory.
  • MapPickerType needs an API key or a non-Google backend. With no key configured you get an empty grey div and console 403s from Google — a silent failure that looks like a broken asset install. Configure the key before debugging anything else, or switch the provider.
  • Global type extensions are invisible greps. A behaviour change across every form usually means a FormTypeExtension in this bundle kicked in. bin/console debug:form App\Form\FooType shows which extensions and options are active — use it before digging through your own code.
  • Assets go stale. After composer update, public/bundles/fsiformextensions/ is not refreshed automatically. Re-run assets:install, or you'll chase a bug that only exists in the old copied JS.
  • Translations are sparse (the project is Polish-origin; expect en and pl and fallbacks to raw keys for other locales). Add your own translations/FSiFormExtensionsBundle.<locale>.yaml rather than patching vendor files — but verify the bundle actually reads the domain you're overriding.
  • Override via theme blocks, never vendor templates. Copying fields.html.twig into your app works until the next release; block-level overrides in your own theme survive upgrades.
  • Maintenance risk is real. 3 stars, 0 dependents, a single maintainer. Treat it as source to read and selectively vendor, not as a dependency to build a product on. Pin the version and keep a fork note; if you need two of the widgets, porting is cheaper than the upgrade treadmill.
  • Test your types with TypeTestCase if you're Symfony-side — Symfony\Component\Form\Test\TypeTestCase gets you form-building assertions without a kernel, which is the cheapest way to catch option regressions after a bundle bump.
  • Extend at the JS boundary, not the PHP one. If you need a new widget, adding it to the existing bundled JS build is brittle; write a separate entry that targets [data-fsi-form-extensions] elements and let the PHP type do nothing but render the hooks. This is also what makes a Laravel port straightforward.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect