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

Form Laravel Package

symfony/form

Symfony Form Component helps you build, validate, and process reusable HTML forms with rich field types, data mapping, and CSRF protection. Integrates cleanly with HttpFoundation, Validator, and Twig, but can be used standalone in any PHP app.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

  1. Installation:

    composer require symfony/form
    

    Laravel developers typically use this via the Symfony Form component (often bundled with Laravel's built-in form helpers or via laravelcollective/html).

  2. First Use Case: Create a simple form in a Laravel controller:

    use Symfony\Component\Form\Extension\Core\Type\FormType;
    use Symfony\Component\Form\Extension\Core\Type\TextType;
    use Symfony\Component\Form\FormBuilderInterface;
    
    public function createForm(FormBuilderInterface $builder)
    {
        return $builder
            ->setAction($this->generateUrl('submit_form'))
            ->setMethod('POST')
            ->add('name', TextType::class, [
                'label' => 'Full Name',
                'attr' => ['class' => 'form-control'],
            ])
            ->getForm();
    }
    
  3. Where to Look First:


Implementation Patterns

1. Form Creation & Integration

  • Dynamic Forms: Use FormBuilderInterface to create reusable form types:
    $form = $this->createFormBuilder($user)
        ->add('email', EmailType::class)
        ->add('save', SubmitType::class)
        ->getForm();
    
  • Laravel Integration: Extend Laravel's FormRequest for validation:
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\Form\FormFactoryInterface;
    
    public function __construct(Request $request, FormFactoryInterface $formFactory) {
        $this->form = $formFactory->createNamedBuilder('', null, null)
            ->add('field', TextType::class)
            ->getForm();
    }
    

2. Handling Submissions

  • Processing Data:
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {
        $data = $form->getData(); // Bound to your entity
    }
    
  • Partial Submits (for collections):
    $builder->add('tags', CollectionType::class, [
        'entry_type' => TextType::class,
        'allow_add' => true,
        'allow_delete' => true,
        'prototype' => true,
    ]);
    

3. Custom Form Types

  • Extend Base Types:
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    
    class CustomType extends AbstractType {
        public function buildForm(FormBuilderInterface $builder, array $options) {
            $builder->add('custom_field', TextType::class);
        }
    }
    
  • Register in Laravel: Bind the type in AppServiceProvider:
    public function boot() {
        FormTypeExtension::defaultFormTypeExtensions([
            new CustomTypeExtension(),
        ]);
    }
    

4. Validation & Error Handling

  • Symfony Validator Integration:
    use Symfony\Component\Validator\Constraints as Assert;
    
    $builder->add('age', IntegerType::class, [
        'constraints' => [new Assert\GreaterThan(18)],
    ]);
    
  • Custom Error Messages:
    $builder->add('email', EmailType::class, [
        'error_bubbling' => true,
        'constraints' => [
            new Assert\NotBlank(['message' => 'Email is required']),
        ],
    ]);
    

5. Multistep Forms (Symfony 8+)

  • FormFlow:
    use Symfony\Component\Form\FormFlow;
    
    $flow = new FormFlow();
    $flow->addStep('step1', $step1Form);
    $flow->addStep('step2', $step2Form);
    $flow->setCurrentStep('step1');
    

Gotchas and Tips

Common Pitfalls

  1. Session Contamination:

    • Non-serializable objects in forms can corrupt session data.
    • Fix: Ensure all bound data is serializable or use handle_missing_data:
      $form = $formFactory->createBuilder()->handleRequest($request, true)->getForm();
      
  2. Collection Index Mismatches:

    • Partial submits with mismatched indices (e.g., items[0] vs items[1]) cause data loss.
    • Fix: Use by_reference: false or allow_add/allow_delete: true:
      $builder->add('items', CollectionType::class, [
          'by_reference' => false,
          'allow_add' => true,
      ]);
      
  3. Validator Duplication:

    • Instantiating ValidatorExtension multiple times causes duplicate errors.
    • Fix: Use dependency injection (Laravel's Validator service handles this).
  4. Textarea Newlines:

    • CRLF/CR are normalized to LF, which may break user input.
    • Fix: Use TextType with attr: ['rows' => 5] or custom transformers.

Debugging Tips

  • Dump Form Data:
    dd($form->getData(), $form->getErrors(true));
    
  • Check Submitted Data:
    $form->submit($request->request->all());
    
  • Enable Debug Mode: Symfony's form component logs warnings for common issues (e.g., missing CSRF tokens).

Extension Points

  1. Custom Data Transformers:

    use Symfony\Component\Form\DataTransformerInterface;
    
    class CustomTransformer implements DataTransformerInterface {
        public function transform($value) { /* ... */ }
        public function reverseTransform($value) { /* ... */ }
    }
    

    Register via FormTypeExtension:

    $builder->addModelTransformer(new CustomTransformer());
    
  2. Event Listeners:

    • Use PRE_SET_DATA, POST_SUBMIT, or PRE_SUBMIT events:
      $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
          $event->setData($event->getData() ?? new YourEntity());
      });
      
  3. Override Twig Templates:

    • Copy vendor/symfony/form/Resources/views/ to resources/views/form/ and customize.

Laravel-Specific Quirks

  • CSRF Protection: Laravel's csrf_token() must be included in forms:
    $builder->add('csrf_token', HiddenType::class, [
        'mapped' => false,
        'data' => csrf_token(),
    ]);
    
  • Form Request Binding: Use Symfony\Component\HttpFoundation\Request directly or Laravel's FormRequest:
    $form->handleRequest($request); // Laravel's Request extends Symfony's
    

Performance Tips

  • Cache Form Types:
    $formFactory->getFormType('your_type')->getConfig()->setAttribute('cache_key', 'unique_key');
    
  • Avoid Rebuilding Forms: Reuse form instances where possible (e.g., in loops).
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle