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

armetiz/form-extension-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require armetiz/form-extension-bundle:1.x-dev
    

    Enable the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 2/3):

    Armetiz\FormExtensionBundle\ArmetizFormExtensionBundle::class => ['all' => true],
    
  2. First Use Case: Replace a standard entity field with entity_ajax in your form type:

    $builder->add('owner', EntityAjaxType::class, [
        'class' => User::class,
        'property' => 'username',
        'choice_label' => 'username',
    ]);
    
  3. Frontend Integration: Pair with Chosen or Ajax Chosen for dynamic loading. Example:

    {{ form_widget(form.owner, {'attr': {'data-url': path('app_user_search')}}) }}
    

Implementation Patterns

Workflows

  1. Lazy-Loading Entities:

    • Use entity_ajax for related entities (e.g., Book.owner) to avoid loading all records upfront.
    • Ideal for large datasets or parent-child relationships (e.g., UserPost).
    • Example: Load only the current owner of a Book in the form, then fetch additional users via AJAX.
  2. Integration with Frontend Libraries:

    • Chosen/Ajax Chosen: Configure the frontend to fetch data from a custom route (e.g., /search/users).
    • Custom AJAX Endpoints: Create a controller to return filtered entities in XML/JSON:
      // src/Controller/UserSearchController.php
      public function searchAction(Request $request): Response
      {
          $query = $request->query->get('term');
          $users = $this->getDoctrine()->getRepository(User::class)
              ->createQueryBuilder('u')
              ->where('u.username LIKE :query')
              ->setParameter('query', "%$query%")
              ->getQuery()
              ->getResult();
      
          return $this->render('ArmetizFormExtensionBundle:User:search.xml.twig', [
              'users' => $users,
          ]);
      }
      
  3. Form Type Configuration:

    • Reuse all EntityType options (e.g., choice_label, query_builder).
    • Add custom options like ajax_route to specify the search endpoint:
      $builder->add('owner', EntityAjaxType::class, [
          'class' => User::class,
          'ajax_route' => 'app_user_search',
      ]);
      
  4. Validation and Submission:

    • Handle form submission as usual; entity_ajax submits data identically to entity.
    • Example:
      if ($form->isSubmitted() && $form->isValid()) {
          $book->setOwner($form->get('owner')->getData());
          $em->persist($book);
      }
      

Gotchas and Tips

Pitfalls

  1. Frontend Dependency:

    • The bundle only provides the backend logic. You must manually integrate with a frontend library (e.g., Chosen) to handle AJAX requests.
    • Without frontend JS, the field will render as a static dropdown with no dynamic loading.
  2. Route Configuration:

    • Ensure your search endpoint returns data in the expected format (XML/JSON). The example uses XML with <item> tags, but JSON is also viable with adjustments to the frontend JS.
    • Example JSON response:
      {
          "results": [
              {"id": 1, "text": "John Doe"},
              {"id": 2, "text": "Jane Smith"}
          ]
      }
      
  3. Caching:

    • If using query_builder, cache the DQL query to avoid performance issues with repeated AJAX calls.
    • Example:
      $builder->add('owner', EntityAjaxType::class, [
          'query_builder' => function (EntityManagerInterface $em) {
              return $em->getRepository(User::class)
                  ->createQueryBuilder('u')
                  ->where('u.active = :active')
                  ->setParameter('active', true);
          },
      ]);
      
  4. Symfony Version Compatibility:

    • The bundle is designed for Symfony 2.1+ but may require adjustments for newer versions (e.g., createFormBuildercreateForm in Symfony 4+).
    • Test thoroughly with your Symfony version.

Tips

  1. Debugging AJAX Responses:

    • Inspect the network tab in browser dev tools to verify the endpoint returns valid data. Mismatched formats (e.g., XML vs. JSON) will break the frontend.
    • Example debug route:
      // src/Controller/DebugController.php
      public function debugSearchAction(): Response
      {
          return $this->render('ArmetizFormExtensionBundle:User:search.xml.twig', [
              'users' => $this->getDoctrine()->getRepository(User::class)->findAll(),
          ]);
      }
      
  2. Extending the Bundle:

    • Override the EntityAjaxType class to add custom behavior (e.g., default query parameters):
      // src/Form/Extension/EntityAjaxTypeExtension.php
      use Symfony\Bridge\Doctrine\Form\Type\EntityType;
      use Armetiz\FormExtensionBundle\Form\Type\EntityAjaxType;
      
      class CustomEntityAjaxTypeExtension extends EntityAjaxType
      {
          public function configureOptions(OptionsResolver $resolver)
          {
              $resolver->setDefaults([
                  'default_query' => 'active_users',
              ]);
          }
      }
      
    • Register the extension in services.yaml:
      services:
          App\Form\Extension\CustomEntityAjaxTypeExtension:
              tags: [form.type_extension, { extended_type: 'entity_ajax', extension_type: 'form' }]
      
  3. Performance:

    • Limit the number of returned results in the AJAX endpoint to improve responsiveness:
      ->setMaxResults(20)
      
    • Use pagination for large datasets.
  4. Accessibility:

    • Ensure the frontend library (e.g., Chosen) is configured with proper ARIA attributes for accessibility.
    • Example:
      $(selector).chosen({
          search_contains: true,
          no_results_text: 'No users found',
          disable_search_threshold: 3,
          width: '100%'
      });
      
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.
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
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle