svaroh / jsformvalidator-bundle
JavaScript validation for Symfony forms.
Package info
github.com/Svaroh/JsFormValidatorBundle
Language:JavaScript
Type:symfony-bundle
pkg:composer/svaroh/jsformvalidator-bundle
Requires
- php: ^8.4
- doctrine/persistence: ^2.5 || ^3.0 || ^4.0
- psr/log: ^3.0
- symfony/config: ^8.0
- symfony/dependency-injection: ^8.0
- symfony/doctrine-bridge: ^8.0
- symfony/form: ^8.0
- symfony/http-foundation: ^8.0
- symfony/http-kernel: ^8.0
- symfony/routing: ^8.0
- symfony/translation-contracts: ^3.6
- symfony/validator: ^8.0
- twig/twig: ^3.0
Requires (Dev)
- phpstan/phpstan: ^2.1
- phpstan/phpstan-symfony: ^2.0
- phpunit/phpunit: ^13.0
- symfony/asset: ^8.0
- symfony/console: ^8.0
- symfony/dotenv: ^8.0
- symfony/framework-bundle: ^8.0
- symfony/phpunit-bridge: ^8.0
- symfony/security-csrf: ^8.0
- symfony/translation: ^8.0
- symfony/twig-bundle: ^8.0
- symfony/webpack-encore-bundle: ^1.17 || ^2.0
- symfony/yaml: ^8.0
Suggests
- doctrine/doctrine-bundle: For the UniqueEntity validation
- doctrine/orm: For the UniqueEntity validation
- symfony/framework-bundle: For registering the bundle in a Symfony application
- symfony/twig-bundle: For using the Twig helper functions
This package is auto-updated.
Last update: 2026-08-28 06:43:20 UTC
README
SvarohJsFormValidatorBundle converts Symfony form validation metadata into JavaScript validation rules and attaches client-side validators to rendered forms.
Status
This branch targets the current PHP/Symfony baseline:
- PHP 8.4+ runtime support; CI currently verifies PHP 8.4, 8.5, and 8.6 nightly
- Symfony 8.x components as declared in
composer.json - Twig 3
- PHPUnit 13
- PHPStan static analysis
- PHP and JavaScript coverage thresholds
- PSR-4 autoloading from
src/
For older Symfony applications, use the historical branches of formapro/JsFormValidatorBundle:
Installation
Install the bundle with Composer:
composer require svaroh/jsformvalidator-bundle
If you are testing before the first tagged release, require the development branch explicitly:
composer require svaroh/jsformvalidator-bundle:"dev-main"
Register the bundle in config/bundles.php:
<?php return [ // ... Svaroh\JsFormValidatorBundle\SvarohJsFormValidatorBundle::class => ['all' => true], ];
Configuration
Validation is enabled for every form by default. You can disable it globally:
# config/packages/svaroh_js_form_validator.yaml svaroh_js_form_validator: js_validation: false
Per-form and per-field disabling is documented in Disabling validation.
The browser validates a form on its own before this bundle sees the submit. You can opt into letting the bundle own that reporting:
# config/packages/svaroh_js_form_validator.yaml svaroh_js_form_validator: html5_validation: true
See HTML5 validation for what that changes.
UniqueEntity Route
If you use Symfony's Doctrine UniqueEntity constraint, import the bundle route:
# config/routes/svaroh_js_form_validator.yaml svaroh_js_form_validator: resource: '@SvarohJsFormValidatorBundle/Resources/config/routing.yaml' prefix: /svaroh_js_form_validator
Make sure your security configuration allows requests to this route.
The endpoint answers whether a matching record exists, but only for a field
combination that a UniqueEntity constraint on the named entity class actually
declares; the repository method comes from that constraint too. Everything else
is refused. For the combinations you did declare unique it is still a public,
unthrottled existence check, so restrict it in your firewall when that answer is
sensitive, or point svaroh_js_form_validator.routing.check_unique_entity at
your own controller as described in
Checking entity uniqueness.
JavaScript Assets
There are two common ways to load the JavaScript files.
Add an Encore Entry
Encore
// ...
.addEntry('app', './assets/js/app.js')
+ .addEntry(
+ 'SvarohJsFormValidator',
+ './vendor/svaroh/jsformvalidator-bundle/src/Resources/public/js/SvarohJsFormValidatorWithJqueryInit.js'
+ )
// ...
;
Then include the entry in your template:
{{ encore_entry_script_tags('SvarohJsFormValidator') }}
{{ encore_entry_script_tags('app') }}
Import From Your Main JavaScript
import $ from 'jquery'; +import '../vendor/svaroh/jsformvalidator-bundle/src/Resources/public/js/SvarohJsFormValidator'; +import '../vendor/svaroh/jsformvalidator-bundle/src/Resources/public/js/jquery.svarohjsformvalidator';
Adjust the import path to your application structure.
JavaScript Namespace
The library registers its constraints and its view transformers in a single
global object named after the Svaroh\JsFormValidatorBundle PHP namespace:
Svaroh.constraints // constraints, keyed by class name without the separators Svaroh.transformers // view transformers, keyed the same way
Register your own classes there, as shown in custom constraints and custom data transformers. The object is created by the library, so run your registrations after its script is loaded.
Every bundled constraint and transformer is still exported under its own global
name, such as window.SymfonyComponentValidatorConstraintsNotBlank, and a class
your application defines as a global is still picked up. Both are deprecated and
will be dropped in a future release.
Render Bundle Config And Form Models
After the scripts are loaded, render the generated config and queued form models:
{{ js_validator_config() }}
{{ init_js_validation() }}
If you need manual initialization for a specific form or event, see manual initialization.
Usage
After the bundle is registered, the form extension adds every enabled root form
to an internal queue. Calling init_js_validation() renders JavaScript models
for the queued forms:
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
{{ init_js_validation(form) }}
You can pass false as the second argument to avoid automatic initialization on
page load:
{{ init_js_validation(form, false) }}
Documentation
Customization
This bundle finds related DOM elements for each Symfony form element and attaches an object validator to them. The validator contains the properties and methods that define the validation process for that form element.
If your form rendering is customized, start with custom rendering notes.
- Disable validation for a specified field
- Error display
- Get validation groups from a closure
- Getters validation
- The Callback constraint
- The Choice constraint callback
- Custom constraints
- Custom data transformers
- Checking entity uniqueness
- Form submit by JavaScript
- onValidate callback
- Run validation on custom event
- Collections validation
- Localized numbers
- HTML5 validation
- The NotBlank constraint
- Comparing a field with another field
- The Range constraint on dates
- Repeated fields
- One form rendered several times
- Validation events
- File uploads
- Pluralized messages
- Forms that come and go
Development
The recommended development environment is the Nix shell:
nix develop
It provides the latest PHP available in the pinned nixpkgs input, currently
PHP 8.5, with Xdebug coverage support, Composer, Node.js 24, npm, zip/unzip,
and Cypress runtime libraries. If flakes are not enabled globally, prefix Nix
commands with nix --extra-experimental-features "nix-command flakes".
For a fresh checkout:
composer update npm install
If Cypress reports a missing binary, install it into the local cache:
npx cypress install
You can also run commands without entering the shell:
nix develop -c composer test nix develop -c npm test
Without Nix, install PHP 8.4 or newer, Composer, Node.js 24, npm, and the Cypress system dependencies locally before running the same commands.
To install vendors via Docker instead of host PHP/Composer:
docker compose build php-fpm docker compose run --rm --no-deps -u "$(id -u):$(id -g)" php-fpm composer update docker compose run --rm --no-deps -u "$(id -u):$(id -g)" php-fpm npm install
Install or refresh Composer dependencies:
composer update
Run the PHP test suite:
composer test
Run PHPStan static analysis:
composer phpstan
Run PHP coverage:
composer coverage
Run the JavaScript unit tests and Cypress browser smoke test:
npm test
Run JavaScript coverage:
npm run test:coverage
Useful local checks:
composer validate --strict git diff --check
The same maintained test, static-analysis, and coverage checks are also run by GitHub Actions on pushes and pull requests. Coverage runs generate Cobertura reports and upload them to GitHub Code Quality when workflow permissions allow.
The Docker stack uses PHP 8.5, Composer 2, and Node.js 24. It is maintained for dependency installation and ad hoc local commands; Nix remains the preferred environment for exact local parity with the documented checks.