2017-09-22 7 views
0

Je souhaite filtrer une liste déroulante en fonction des choix que j'ai faits dans les 4 listes déroulantes précédentes. Mon type de formulaire ressemble à ce que:Symfony modifier les valeurs déroulantes avec le générateur de requête après l'envoi du formulaire

class DocumentDeactivationType extends AbstractType { 

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

    $builder 
    ->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', 'required' => false, 
     'translation_domain' => 'Documents')) 

    -> add('status', 'entity', array(
     'class' => 'DocumentBundle:Status', 'property' => 'name', 
     'choice_label' => 'translationkey', 'label' => 'Status', 
     'expanded' => false, 'multiple' => true, 'required' => false, 
     'translation_domain' => 'Documents', 
     'choice_translation_domain' => 'Documents',)) 


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

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

    ->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')); 

    $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($builder) 
     { 
     $form = $event->getForm(); 
     $data = $event->getData(); 
     $markets = $data['markets']; 
     $status = $data['status']; 
     $type = $data['type']; 
     $airlines = $data['airlines']; 
    $builder 
    ->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', 

     'query_builder' => function (EntityRepository $er) use ($markets, $status, $type, $airlines){ 
     return $er->createQueryBuilder('e') 
     ->where('e.markets IN (:markets)') 
     ->andWhere('e.status IN (:status)') 
     ->andWhere('e.airlines IN (:airlines)') 
     ->andWhere('e.products IN (:products)') 
     ->setParameter('markets', $markets) 
     ->setParameter('status', $status) 
     ->setParameter('airlines', $airlines) 
     ->setParameter('type', $type); 
     }, 
    )); 
    }); 
} 
    public function getName() 
    { 
     return 'document_deactivation'; 

    } 
    } 

Je ne sais pas s'il est évident: le menu déroulant de « DocumentList » est déjà là avec toutes les valeurs de l'entité document et ce que je tente de réaliser grâce à l'PRE_SUBMIT EventListener est sorte de mettre à jour ses valeurs en fonction des choix des 4 autres listes déroulantes. Il y a un bouton "Appliquer" pour les 4 listes déroulantes, donc je ne devrais pas avoir besoin d'une requête ajax mais des évènements Post/PreSubmit je suppose? Mes problèmes:

  1. Lors de la sélection de certaines valeurs dans les listes déroulantes "Filtre", mais par ex. en omettant les «marchés», j'obtiens l'erreur «indice indéfini pour les marchés» qui est probablement à cause de la ligne $ markets = $ data ['markets'] -> alors ce que je veux ici c'est de pouvoir filtrer seulement sur certains des types et ne pas être obligé de tous les sélectionner.
  2. La mise à jour de la liste déroulante de la liste de documents ne fonctionne pas du tout. Je ne pense même pas, le constructeur de requête fait n'importe quoi. Mais je ne suis pas sûr si cela a quelque chose à voir avec mon FormEvent ou peut-être la façon dont j'ajoute la liste déroulante au formulaire.

comment tout est rendu dans mon dossier brindille:

{% block filterContent %} 
    {{ form_start(form) }} 
    {{ form_row(form.type) }} 
    {{ form_row(form.status) }} 
    {{ form_row(form.markets)}} 
    {{ form_row(form.airlines)}} 
    <input type="submit" class="btn-primary btn btn-xs" value="Apply Filter" /> 

    <br clear="all" /> 
{% endblock %} 

{% block content %} 

{{ form_label(form.documentlist) }} 
{{ form_widget(form.documentlist) }} 
{{ form_end(form) }} </br> 

<div class="row"> 
    {% include 'AppBundle::HelpSubmitButton.html.twig' with { 'buttonName': 'label.submit'|trans } %} 
</div> 
{% endblock content %} 
+0

2) Je crois que vous aurez besoin de mettre à jour la liste via AJAX car 'PRE_SUBMIT' arrivera juste avant l'action' submit' afin qu'il utilise toutes les valeurs dans 'documentlist'. – user742736

Répondre

0

1) Ajouter une instruction if autour du marché de $

if (isset($data['markets'])) {$markets = $data['markets'];} 

Et

'query_builder' => function (EntityRepository $er) use ($markets, $status, $type, $airlines) { 
    $query = $er->createQueryBuilder('e') 
    ->where('e.status IN (:status)') 
    ->andWhere('e.airlines IN (:airlines)') 
    ->andWhere('e.products IN (:products)') 
    ->setParameter('markets', $markets) 
    ->setParameter('status', $status) 
    ->setParameter('airlines', $airlines) 
    ->setParameter('type', $type); 
    }; 

    if (isset($data['markets'])) { 
    $query->andWhere('e.markets IN (:markets)') 
    } 

2) Je crois vous aurez besoin de mettre à jour la liste via AJAX car PRE_SUBMIT se produira j Avant l'action submit, il utilisera toutes les valeurs dans documentlist.

+0

merci @ user742736, j'ai essayé de configurer une fonction ajax pour faire comme vous l'avez dit mais les données que j'envoie à mon contrôleur pour gérer la requête sont vides. pourriez-vous donner un exemple de comment cela fonctionne? – sonja