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 Bundle Laravel Package

atoolo/form-bundle

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Install the Bundle**
   Add the package via Composer:
   ```bash
   composer require atoolo/form-bundle

Enable the bundle in config/bundles.php:

return [
    // ...
    Atoolo\FormBundle\AtooloFormBundle::class => ['all' => true],
];
  1. Configure the Bundle Define a basic configuration in config/packages/atoolo_form.yaml:

    atoolo_form:
        jsonforms:
            renderer: 'default' # or 'react' if using React-based rendering
            assets_path: '%kernel.project_dir%/public/build/jsonforms' # Path to JSON Forms assets
    
  2. First Use Case: Render a Basic Form Create a JSON form schema (e.g., config/forms/example.json):

    {
        "type": "VerticalLayout",
        "elements": [
            {
                "type": "Control",
                "scope": "#/properties/name",
                "label": "Name",
                "input": {
                    "type": "text"
                }
            }
        ]
    }
    

    Render it in a controller:

    use Atoolo\FormBundle\Controller\FormController;
    
    class ExampleController extends AbstractController
    {
        public function renderForm(FormController $formController)
        {
            return $formController->render('example', [
                'name' => 'default_value'
            ]);
        }
    }
    

    Route it in config/routes.yaml:

    app_example_form:
        path: /example-form
        controller: App\Controller\ExampleController::renderForm
    
  3. Verify the Output Visit /example-form to see the rendered form. The bundle handles both rendering and processing via JSON Forms.


Implementation Patterns

Workflow: Form Creation and Processing

  1. Define JSON Schema Store form schemas in config/forms/ (or a custom directory). Example:

    {
        "type": "Object",
        "properties": {
            "email": {
                "type": "string",
                "format": "email"
            }
        },
        "required": ["email"]
    }
    
  2. Render the Form Use the FormController to render forms dynamically:

    return $formController->render('user_registration', $initialData);
    
    • Pass $initialData to pre-fill fields.
    • Use renderAsJson() for API responses.
  3. Handle Form Submission Submit data via HTTP POST to the same endpoint. The bundle validates and processes data automatically:

    public function submitForm(Request $request, FormController $formController)
    {
        $result = $formController->process('user_registration', $request->request->all());
        if ($result->isValid()) {
            // Save data to DB or perform actions
            return $this->json(['success' => true]);
        }
        return $this->json(['errors' => $result->getErrors()], 400);
    }
    
  4. Customize Rendering Override the default renderer by implementing Atoolo\FormBundle\Renderer\RendererInterface:

    namespace App\Form\Renderer;
    
    use Atoolo\FormBundle\Renderer\RendererInterface;
    
    class CustomRenderer implements RendererInterface
    {
        public function render(array $formConfig, array $data): string
        {
            // Custom logic (e.g., Twig template)
            return $this->twig->render('forms/custom.html.twig', [
                'form' => $formConfig,
                'data' => $data
            ]);
        }
    }
    

    Register it in config/packages/atoolo_form.yaml:

    atoolo_form:
        jsonforms:
            renderer: 'custom'
    
  5. Reuse Forms Across Projects Use the bundle’s FormLoader service to load forms from external sources (e.g., database or API):

    $formLoader = $this->container->get('atoolo_form.form_loader');
    $schema = $formLoader->load('dynamic_form_key');
    

Integration Tips

  • Symfony UX Turbo/Stimulus Combine with Symfony UX for real-time updates:

    // assets/controllers/form_controller.js
    import { Controller } from '@hotwired/stimulus';
    
    export default class extends Controller {
        connect() {
            this.element.addEventListener('submit', (e) => {
                e.preventDefault();
                fetch(this.element.action, {
                    method: 'POST',
                    body: new FormData(this.element)
                })
                .then(response => response.json())
                .then(data => {
                    if (data.success) Turbo.visit('/thank-you');
                });
            });
        }
    }
    
  • Validation Customization Extend validation rules by implementing Atoolo\FormBundle\Validator\ConstraintValidatorInterface:

    namespace App\Form\Validator;
    
    use Atoolo\FormBundle\Validator\ConstraintValidatorInterface;
    use Symfony\Component\Validator\Constraint;
    use Symfony\Component\Validator\ConstraintValidator;
    
    class CustomValidator implements ConstraintValidatorInterface
    {
        public function validate($value, Constraint $constraint)
        {
            if (!preg_match('/^[A-Z]+$/', $value)) {
                $this->context->buildViolation('Must be uppercase.')
                    ->addViolation();
            }
        }
    }
    

    Register it in services.yaml:

    services:
        App\Form\Validator\CustomValidator:
            tags: ['atoolo_form.validator']
    
  • Localization Support multiple languages by configuring the translator in atoolo_form.yaml:

    atoolo_form:
        jsonforms:
            translator: 'app.translator' # Custom translator service
    

Gotchas and Tips

Pitfalls

  1. Asset Path Configuration

    • Issue: Forms may fail to render if assets_path in atoolo_form.yaml is incorrect.
    • Fix: Ensure the path points to the directory containing JSON Forms assets (e.g., node_modules/@jsonforms/core/dist/). For production, use a build step (e.g., Webpack Encore) to copy assets to public/build/jsonforms.
  2. CORS for API Usage

    • Issue: If using the bundle for API-driven forms, CORS may block requests.
    • Fix: Configure CORS in config/packages/nelmio_cors.yaml:
      nelmio_cors:
          paths:
              '^/api/form/':
                  allow_origin: ['*']
                  allow_methods: ['POST']
                  allow_headers: ['Content-Type']
      
  3. Validation Overrides

    • Issue: Custom validators may not trigger if not properly tagged.
    • Fix: Ensure validators implement ConstraintValidatorInterface and are tagged in services.yaml:
      tags: ['atoolo_form.validator']
      
  4. Data Binding

    • Issue: Nested data structures may not bind correctly.
    • Fix: Use dot notation for nested paths in JSON Forms:
      {
          "type": "Control",
          "scope": "#/properties/user/address/street"
      }
      
  5. Performance with Large Forms

    • Issue: Complex forms may slow down rendering.
    • Fix: Lazy-load form schemas or use caching:
      framework:
          cache:
              pools:
                  atoolo_form.cache_pool:
                      adapter: cache.adapter.apcu
      

Debugging Tips

  1. Enable Debug Mode Set atoolo_form.debug: true in config/packages/atoolo_form.yaml to log form processing details:

    atoolo_form:
        debug: true
    
  2. Validate JSON Schema Use tools like JSON Schema Validator to test schemas before integration.

  3. Check Browser Console For frontend issues, inspect the network tab for failed asset loads or 404s on JSON Forms JS/CSS.

  4. Log Form Data Add a subscriber to log processed data:

    namespace App\EventSubscriber;
    
    use Atoolo\FormBundle\Event\FormProcessedEvent;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    class FormLoggerSubscriber implements EventSubscriberInterface
    {
        public static function getSubscribedEvents()
        {
            return [
                FormProcessedEvent::class => 'onFormProcessed',
            ];
        }
    
        public function onFormProcessed(FormProcessedEvent $event)
        {
            \Log::info('Form processed:', [
                'form' => $event->getFormName(),
                'data' => $event->getData(),
                'errors' => $event->getErrors()
            ]);
        }
    }
    

Extension Points

  1. Custom Renderers Extend the renderer to support:

    • Twig templates.
    • React/Vue components (via Symfony UX).
    • Headless APIs (return raw JSON).
  2. Dynamic Form Loading Implement Atoolo\FormBundle\Loader\FormLoaderInterface to fetch schemas from

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.
anousss007/vigilance
supportpal/eloquent-model
ardenexal/fhir-models
laravel-at/laravel-image-sanitize
romalytar/yammi-audit-log-laravel
ardenexal/fhir-validation
arshaviras/weather-widget
laravel-chronicle/core
sunchayn/nimbus
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon