fp/jsformvalidator-bundle
Symfony bundle that adds client-side JavaScript validation to forms. It generates rules from Symfony form constraints, supports AJAX checks, and helps keep front-end and back-end validation consistent while reducing unnecessary server requests.
The bundle exists to give you a single source of truth for validation: the constraints you already declare on entities/DTOs (or in the constraints option of a form field) are serialized into the page, and the bundle's JavaScript enforces them in the browser. You stop hand-writing required, minlength, and regex checks that drift away from the server.
Minimal steps:
composer require fp/jsformvalidator-bundle:"^1.8" — 1.8.0 is the first stable release of the Symfony 8 baseline branch: PHP 8.4+, symfony/* ^8.0, Twig 3, PHPUnit 13. It will not install on Symfony 5.4/6.4/7.x; those apps must stay on the 1.7 line (which is still beta-flavoured). Check composer.json before assuming it drops into your project.Fp\JsFormValidatorBundle\FpJsFormValidatorBundle::class => ['all' => true] in config/bundles.php.Resources/public (classic bin/console assets:install --symlink path) and a modern entry point; pick whichever matches your AssetMapper/Encore setup. The single most common "it doesn't work" cause is a 404 on that script — confirm the global (a jsfv-style object) exists in the browser console before debugging anything else.config/packages/fp_js_form_validator.yaml — the config class in DependencyInjection/Configuration.php is the authoritative list of keys for your installed version, so read it rather than copying blog snippets.First use case: a registration form. Add NotBlank, Email, Length constraints to the model, render the form exactly as you do today, and submit garbage. You should get inline errors with no network round-trip. Then disable JS and confirm the server rejects the same input — if it doesn't, stop and fix that before going further. A good second case is a payment/checkout field: Luhn is now mirrored client-side (new in 1.8.0), so credit card numbers, SIRET and similar checksummed values validate without a round-trip.
Where to look first: README.md for the minimal wiring, the test fixtures (they enumerate exactly which constraints are supported and produce the expected rule shapes), and src/Resources/public/js for the extension API.
constraints array; both paths feed the same metadata. Forms that build rules ad hoc in JS are the ones that rot.Luhn (added in 1.8.0) mirrors Symfony's LuhnValidator and is a drop-in for card numbers, SIRET/SIREN and similar. Combine it with a Regex for the digit-group format, since Luhn alone accepts any checksum-valid digit string.Form/Extension). Use it for forms with heavy custom JS, third-party widgets, or upload fields where client-side rules just get in the way.Constraint + ConstraintValidator; client side you register a matching validator via the bundle's addConstraint/addValidator API. Write a test for each side — they drift silently.message and the request locale, so they match server output — provided the payload is generated per request (see caching gotcha below).WebTestCase, assert the rendered payload contains a rule per constraint (catches silent regressions when a constraint is renamed), and keep one JS-less functional test asserting server rejection. The repo's own Cypress suite is a good template for the browser side; it now runs on Cypress 15.20.x with coverage gates.Luhn, the parent-form queue fix, or the CI/static-analysis hardening. Plan multi-app estates accordingly.Expression, Callback, UniqueEntity, Entity, File/Image, and anything with a service dependency can't be translated to JS. Expect a meaningful slice of your constraints to fall back to server-side only — budget for that instead of being surprised by it. (The supported list grows slowly; Luhn is the 1.8.0 addition.)\p{L}, possessive quantifiers, or PCRE-only constructs will either fail to compile or behave differently in RegExp. Keep Regex constraints in the browser to simple character classes, and test the boundary cases.<script>, a strict Content-Security-Policy will block it silently apart from a console violation. Either allow a nonce or render the assets/init yourself.required/maxlength/pattern for some constraints. Add novalidate to the form so the browser's bubble doesn't compete with the bundle's error rendering.^1.8, keep custom validators small and isolated so they survive an upgrade or a swap to hand-written validation, and be prepared to own fixes.How can I help you explore Laravel packages today?