Weave Code
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

Frontend Validation Bundle Laravel Package

clicktrend/frontend-validation-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require clicktrend/frontend-validation-bundle:dev-master
    

    Register the bundle in app/AppKernel.php:

    new Clicktrend\Bundle\FrontendValidationBundle\ClicktrendFrontendValidationBundle(),
    
  2. Configure Assetic Add to app/config/config.yml:

    assetic:
        assets:
            jquery_validation:
                inputs:
                    - "%kernel.root_dir%/../vendor/reactive-raven/jq-bootstrap-validation/src/jqBootstrapValidation.js"
                output: js/jqBootstrapValidation.js
    

    Include the generated JS in your layout:

    {% block javascripts %}
        {{ parent() }}
        {{ asset('js/jqBootstrapValidation.js') }}
    {% endblock %}
    
  3. First Use Case Annotate a form field in an entity (e.g., User.php):

    use Symfony\Component\Validator\Constraints as Assert;
    
    class User
    {
        /**
         * @Assert\NotBlank(groups={"registration"})
         * @Assert\Email(groups={"registration"})
         */
        protected $email;
    }
    

    Render the form with novalidate and form-horizontal classes:

    <form class="form-horizontal" action="{{ path('registration') }}" method="POST" novalidate>
        {{ form_row(form.email) }}
        <button type="submit">Submit</button>
    </form>
    

Implementation Patterns

Workflow: Form Validation Integration

  1. Entity Annotations Use Symfony’s validation constraints (NotBlank, Email, Length, Regex) on entity properties. Group constraints by logical steps (e.g., registration, profile_update):

    /**
     * @Assert\Length(
     *     min=8,
     *     max=32,
     *     groups={"registration", "profile_update"}
     * )
     */
    protected $password;
    
  2. Form Type Configuration Extend AbstractType to bind validation groups dynamically:

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'validation_groups' => function (Options $options) {
                return ['registration']; // Default group
            },
        ]);
    }
    

    Override groups per action in the controller:

    $form = $this->createForm(UserType::class, $user, [
        'validation_groups' => ['profile_update'],
    ]);
    
  3. Frontend Integration Ensure forms include:

    • class="form-horizontal" (for Bootstrap styling).
    • novalidate (to disable HTML5 validation).
    • data-validation-groups (to pass validation groups to JS):
      <form class="form-horizontal" novalidate data-validation-groups="{{ form.validation_groups|json_encode }}">
      
  4. JavaScript Initialization Initialize validation on form submission:

    $(document).ready(function() {
        $('form').jqBootstrapValidation({
            validationGroups: $('form').data('validation-groups'),
            preventSubmit: true,
            submitError: function($form, event, errors) {
                // Handle errors (e.g., show messages)
            }
        });
    });
    

Patterns for Reusability

  1. Base Form Type Create a base form type to enforce validation patterns:

    abstract class BaseFormType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
                $data = $event->getData();
                $form = $event->getForm();
                $form->add('submit', SubmitType::class, ['attr' => ['class' => 'btn btn-primary']]);
            });
        }
    }
    
  2. Dynamic Validation Groups Use a service to resolve groups based on route parameters:

    # services.yml
    services:
        app.validation_group_resolver:
            class: App\Service\ValidationGroupResolver
            arguments: ['@router']
    
    // ValidationGroupResolver.php
    public function resolve(string $routeName): array
    {
        if ($routeName === 'registration') {
            return ['registration'];
        }
        return ['default'];
    }
    
  3. Custom Error Rendering Override Twig’s error rendering to integrate with Bootstrap:

    {% macro renderErrors(form) %}
        {% for error in form.errors %}
            <div class="alert alert-danger">{{ error.message }}</div>
        {% endfor %}
    {% endmacro %}
    

Gotchas and Tips

Pitfalls

  1. Missing Validation Groups

    • Issue: Frontend validation fails silently if data-validation-groups is omitted.
    • Fix: Ensure all forms include data-validation-groups="{{ form.validation_groups|json_encode }}".
    • Debug: Check browser console for jqBootstrapValidation errors (e.g., ValidationGroups not defined).
  2. Constraint Mismatch

    • Issue: Only Email, Length, NotBlank, and Regex are supported. Other constraints (e.g., Unique) are ignored.
    • Fix: Use custom validation logic or extend the bundle (see Extension Points).
  3. Assetic Asset Paths

    • Issue: jqBootstrapValidation.js may not generate if Assetic is misconfigured.
    • Fix: Verify the inputs path in config.yml matches the vendor structure. For debugging, manually include the JS:
      {{ asset('vendor/reactive-raven/jq-bootstrap-validation/src/jqBootstrapValidation.js') }}
      
  4. Bootstrap CSS Dependency

    • Issue: Validation styles (e.g., error borders) require Bootstrap CSS.
    • Fix: Ensure bootstrap.css is loaded before jqBootstrapValidation.js.

Debugging Tips

  1. Console Logs Add debug logs to the JS initialization:

    console.log('Validation groups:', $('form').data('validation-groups'));
    
  2. Symfony Validator Test backend validation first:

    $errors = $validator->validate($entity, ['registration']);
    dump($errors); // Check for constraint issues
    
  3. Bundle Overrides If extending the bundle, override the ClicktrendFrontendValidationBundle class and redefine the loadConstraints method to support additional constraints.


Extension Points

  1. Add Custom Constraints Extend the bundle’s constraint mapper (located in DependencyInjection/ClicktrendFrontendValidationExtension.php) to support more constraints:

    // Example: Add 'Unique' constraint
    $constraints['Unique'] = [
        'field' => 'unique',
        'message' => 'form.unique',
    ];
    
  2. Custom Validation Messages Override translation keys in config.yml:

    twig:
        globals:
            form_errors:
                form.username.min_length: "Username must be at least 4 characters."
    
  3. Event Listeners Listen to form.submit to trigger validation manually:

    $('form').on('submit', function() {
        if (!$(this).jqBootstrapValidation('isValid')) {
            return false; // Prevent submission
        }
    });
    
  4. Integration with Symfony Forms Use the form_errors Twig function to render errors dynamically:

    {% for error in form_errors(form.email) %}
        <div class="text-danger">{{ error.message }}</div>
    {% endfor %}
    
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.
andydefer/laravel-cluster
aimeos/ai-admin-mcp
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor