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

Depend Select Bundle Laravel Package

ascensodigital/depend-select-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle to your composer.json:

    composer require ascensodigital/depend-select-bundle
    

    Enable the bundle in config/bundles.php:

    return [
        // ...
        AscensoDigital\ADDependSelectBundle\AscensoDigitalDependSelectBundle::class => ['all' => true],
    ];
    
  2. Basic Usage Register the type in your form builder:

    use AscensoDigital\ADDependSelectBundle\Form\Type\DependSelectType;
    
    $builder->add('fieldName', DependSelectType::class, [
        'choices' => $choices, // Array of choices (e.g., ['id' => 'label'])
        'depends_on' => 'parentField', // Field whose value triggers dependency
        'ajax_url' => '/path/to/ajax-endpoint', // URL to fetch dependent choices
        'placeholder' => 'Select an option...',
    ]);
    
  3. First Use Case Create a cascading dropdown (e.g., country → state → city):

    $builder->add('country', EntityType::class, ['class' => Country::class])
            ->add('state', DependSelectType::class, [
                'depends_on' => 'country',
                'ajax_url' => '/api/states-by-country',
            ]);
    

Implementation Patterns

Workflow Integration

  1. Frontend Integration

    • Ensure friendsofsymfony/jsrouting-bundle is configured for AJAX routes.
    • Use Twig to render the form with JS dependencies:
      {{ form_widget(form) }}
      {{ form_rest(form) }}
      <script src="{{ asset('bundles/dependselect/js/dependselect.js') }}"></script>
      
  2. Backend Logic

    • Implement an AJAX endpoint (e.g., StateController::getStatesByCountryAction):
      public function getStatesByCountryAction(Request $request)
      {
          $countryId = $request->request->get('country_id');
          $states = $this->stateRepository->findBy(['country_id' => $countryId]);
          return $this->json(array_map(fn($s) => ['id' => $s->id, 'label' => $s->name], $states));
      }
      
  3. Dynamic Dependencies

    • Chain multiple dependent fields:
      $builder->add('country', EntityType::class)
              ->add('state', DependSelectType::class, [
                  'depends_on' => 'country',
                  'ajax_url' => '/api/states',
              ])
              ->add('city', DependSelectType::class, [
                  'depends_on' => 'state',
                  'ajax_url' => '/api/cities',
              ]);
      
  4. Validation

    • Validate dependent fields in the form type:
      public function buildForm(FormBuilderInterface $builder, array $options)
      {
          $builder->add('parentField', ...)
                  ->add('childField', DependSelectType::class, [
                      'depends_on' => 'parentField',
                      'constraints' => [new NotBlank()],
                  ]);
      }
      

Gotchas and Tips

Pitfalls

  1. AJAX Route Configuration

    • Forgetting to annotate the AJAX endpoint with @Route or YamlRoute will break dependency loading.
    • Fix: Use friendsofsymfony/jsrouting-bundle to generate JS routes:
      # config/routing.yml
      api_states:
          path: /api/states
          defaults: { _controller: App\Controller\StateController::getStatesAction }
          methods: [GET]
      
  2. CSRF Token Mismatch

    • AJAX requests may fail with CSRF token not found if the form is not properly configured.
    • Fix: Include the CSRF token in the AJAX request payload or use same-origin requests.
  3. Choice Format Mismatch

    • The bundle expects choices in ['id' => 'label'] format. Incorrect formats (e.g., objects) will break rendering.
    • Fix: Normalize choices in the AJAX response:
      return $this->json(array_map(fn($item) => ['id' => $item->id, 'label' => $item->name], $items));
      
  4. JavaScript Conflicts

    • If dependselect.js is not loaded or conflicts with other JS (e.g., jQuery), dependencies won’t trigger.
    • Fix: Load the script after jQuery and before form initialization:
      <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
      <script src="{{ asset('bundles/dependselect/js/dependselect.js') }}"></script>
      

Debugging Tips

  1. Check Network Requests

    • Open DevTools (F12) → Network tab to verify AJAX calls to ajax_url are firing and returning valid JSON.
  2. Log AJAX Responses

    • Add logging in the controller to debug payloads:
      $this->logger->debug('AJAX Request', ['data' => $request->request->all()]);
      
  3. Inspect Form HTML

    • Ensure the data-depends-on and data-ajax-url attributes are rendered:
      <select data-depends-on="parentField" data-ajax-url="/api/endpoint">
      

Extension Points

  1. Custom Templates

    • Override the Twig template for the select field:
      # templates/ADDependSelect/fields.html.twig
      {% extends 'form_div_layout.html.twig' %}
      {% block widget %}
          <select {{ block('widget_attributes') }} data-depends-on="{{ depends_on }}" data-ajax-url="{{ ajax_url }}">
              {% for choice in choices %}
                  <option value="{{ choice.id }}">{{ choice.label }}</option>
              {% endfor %}
          </select>
      {% endblock %}
      
  2. Dynamic Placeholders

    • Use Twig to set dynamic placeholders based on the parent field:
      $builder->add('state', DependSelectType::class, [
          'placeholder' => 'Select state for {{ form.parentField.vars.data }}',
      ]);
      
  3. Event Listeners

    • Subscribe to form events to modify dependencies dynamically:
      $form->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
          $form = $event->getForm();
          $data = $event->getData();
          if ($data->getParentField()) {
              $form->add('childField', DependSelectType::class, [
                  'depends_on' => 'parentField',
                  'ajax_url' => '/api/dependent-choices',
              ]);
          }
      });
      
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware