2017-09-18 1 views
1

J'ai un formulaire de filtre que j'aimerais appliquer à un menu déroulant multisélection. Il y a donc un bouton "apply" pour les filtres et en cliquant dessus, je voudrais mettre à jour les valeurs dans la liste déroulante en fonction des choix de filtres. (Il y a d'autres champs/valeurs sur mon formulaire qui ne devraient pas disparaître lors de la mise à jour des valeurs déroulantes.)Formulaire de filtre Symfony pour les valeurs déroulantes à sélection multiple

Je n'ai absolument aucune idée de comment y parvenir. Peut-être qu'une fonction AJAX mènerait à la solution mais je ne sais pas à quoi cela ressemblerait. Je serais heureux de tous les conseils! :)

Ce que j'ai jusqu'à présent:

Filtre pour dropdowns

  • marchés

  • types et

  • compagnies aériennes

Ce sont tous des listes déroulantes multisélect. Et après les avoir sélectionnés, je voudrais cliquer sur «Appliquer», puis la liste déroulante «Liste de documents» devrait être mise à jour pour que seuls les documents liés aux marchés/types sélectionnés ou aux compagnies aériennes soient affichés.

P.S. Ce que j'aime mettre en œuvre en plus, c'est une boîte de recherche pour les noms de documents et les identifiants. Pour que je ne suis pas encore près d'un je ne même pas les éléments corrects ..

<div class="panel panel-default"> 
     <div class="panel-body"> 
     {{ form_start(filterForm) }} 
     {{ form_row(filterForm.type) }} 
     {{ form_row(filterForm.markets)}} 
     {{ form_row(filterForm.airlines)}} 
    <input type="submit" class="btn-primary btn btn-xs" value="Apply Filter" /> 
     {{ form_end(filterForm) }} 
     <br clear="all" /> 
     {{ form_row(form.documentlist) }} 
     </div> 
    </div> 

mise à jour

ma forme:

public function buildForm(FormBuilderInterface $builder, array $options) 
    { 

     $builder 
      ->setAction($options['data']['url']) 
      ->setMethod('GET') 
      ->add('type', 'choice', array('choices' => array(
       'document_types.contract' => 1, 
       'document_types.general'=>2, 
       'document_types.goodwill_policy'=>3, 
       'document_types.pricesheet'=>4, 
       'document_types.yq_update'=>5, 
       'document_types.contract_addendum'=>6), 
       'choices_as_values' => true, 'label' => 'label.types', 
       'expanded' => false, 'multiple' => true, 
       'label' => 'label.type', 
       'translation_domain' => 'Documents')) 

     ; 

     $user = $this->tokenStorage->getToken()->getUser(); 

     $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($user){ 
     $form = $event->getForm(); 

     // only show specific filters based on user's context 

     $form->add('airlines', 'entity', array(
      'class' => 'AppBundle:Airline', 'property' => 'id', 
      'query_builder' => function (EntityRepository $er) use ($user) { 
      $airlines = $user->getAirlines(); 
      return $er->createQueryBuilder('a') 
       ->addOrderBy('a.id', 'ASC') 
       ->andWhere('a.id IN (?1)') 
       ->setParameter(1,$airlines); 
      }, 
      'choice_value' => 'id', 
      'choice_label' => 'id', 'label' => 'label.airlines', 
      'expanded' => false, 'multiple' => true, 
      'translation_domain' => 'Documents')); 

     $form->add('markets', 'entity', array(
      'class' => 'AppBundle:Market', 'property' => 'id', 
      'query_builder' => function (EntityRepository $er) use ($user) { 
      $markets = $user->getMarkets(); 
      return $er->createQueryBuilder('m') 
       ->addOrderBy('m.id', 'ASC'); 
       ->andWhere('m.id IN (?1)') 
       ->setParameter(1,$markets); 
      }, 
      'choice_value' => 'id', 
      'choice_label' => 'id', 'label' => 'label.markets', 
      'expanded' => false, 'multiple' => true, 
      'translation_domain' => 'Documents')) 

et c'est le menu déroulant, c'est supposé mettre à jour son contenu après que les listes déroulantes précédentes sont sélectionnées.

->add('documentlist', EntityType::class, array(
      'class' => 'DocumentBundle:Document', 
       'property' => 'name', 
       'expanded' => false, 'multiple' => true, 
       'label' => 'label.document_list', 
       'empty_value' => "Select document", 
       'required' => false, 
       'mapped' => false, 
       'translation_domain' => 'Documents'})); 
} 
+0

Vous devez avoir plus de code que ce Sonja. Est-ce que vos filtres sont des cases à cocher? Si tel est le cas, utilisez jQuery ou Javascript pur pour détecter les cases à cocher onChange, puis mettez à jour les listes déroulantes. Sans montrer plus de votre code de formulaire, il est très difficile de donner plus de conseils. –

+0

Bien sûr, il y a plus de code! Mais je ne sais pas quelles parties vous aideraient?J'ai dit "ils sont tous des listes déroulantes multisélect" :) Donc je pourrais utiliser jQuery, je suppose mais je ne saurais pas à quoi ressemblerait la fonction onChange! – sonja

+1

ce serait bien si vous avez passé en revue certaines de vos questions précédentes et sélectionné une coche par les bonnes réponses. Je vois que vous avez seulement coché une question. –

Répondre

0

Eh bien, je suppose que vous faites une application pour les compagnies aériennes en fonction de vos messages précédents. Ci-dessous quelques exemples qui devraient vous aider:

// Your PHP Form file 
... 
->add('local_markets_bool', CheckboxType::class, array(// Show Local Markets? 
     'label' => 'Local markets:', 
     'required' => false, 
     'attr' => array(
       'onchange' => "filter('local_markets')" 
     ), 
)) 
... 

{# Your Twig file #} 
{% block javascripts %} 
    {{ parent() }} 
    <script src="{{ asset('script/filters.js') }}"></script> 
{% endblock %} 

// Your Javascript file. Example web/script/filters.js 
function filter(type){ 
    var markList = document.getElementById("form_market_list"); 
    var optSub = "<option value='' selected='selected'>Choose an option</option>"; 

    if (type == 'local_markets'){ // Local. 
     optSub += "<option value='us'>USA</option>"; 
     optSub += "<option value='ca'>Canada</option>"; 
    } 
    else if (degType == 'americas'){ // TC Degree. 
     optSub += "<option value='us'>USA</option>"; 
     optSub += "<option value='ca'>Canada</option>"; 
     optSub += "<option value='pa'>Panama</option>"; 
     optSub += "<option value='br'>Brazil</option>"; 
     optSub += "<option value='pe'>Peru</option>"; 
    } 
    ... 
    markList.innerHTML = optSub; 
} 

Ensuite, lorsque vous cliquez sur la case à cocher local_markets_bool, que les déclencheurs et événements onchange() et passe dans le paramètre local_markets puis le code ajoute les pays USA et Canada à la liste.

Vous ne voudrez peut-être pas faire comme ça, mais cela vous donne une idée. Utiliser jQuery est plus facile, mais l'exemple est tout simplement Javascript.

+0

Merci de partager! Mon problème est que, je me réfère à des entrées de doctrine et non des entrées de menu déroulant codées en dur, donc je ne peux pas vraiment relever votre code .. – sonja

+0

Bien sûr, vous pouvez. Voulez-vous dire que votre formulaire utilise [ChoiceType] (https://symfony.com/doc/current/reference/forms/types/choice.html) et que vous utilisez un callable dans la choice_value pour remplir la liste déroulante? Si oui, la liste est juste peuplée. Vous pouvez toujours le modifier. Vous ne nous avez pas vraiment dit ce que vous faites dans votre classe de formulaire? –

+0

J'utilise un EntityType car ce sont des listes déroulantes "multiselect". J'ai mis à jour le message avec le code de mon type de formulaire – sonja