Skip to content
This repository has been archived by the owner on Jun 14, 2023. It is now read-only.

Choose the embedded filters #107

Closed
bearsroom opened this issue Jun 10, 2014 · 2 comments
Closed

Choose the embedded filters #107

bearsroom opened this issue Jun 10, 2014 · 2 comments

Comments

@bearsroom
Copy link

Hi,
I have created 2 FilterTypes VisiteFilterType and VilleFilterType and I want to embed VilleFilterType in VisiteFilterType. The question is how could I partly embed the filter VilleFilterType because I don't need all filters in it.

Here is my code:

<?php

namespace BECFrance\BackBundle\Filter;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

use Doctrine\ORM\QueryBuilder;

use Lexik\Bundle\FormFilterBundle\Filter\FilterBuilderExecuterInterface;
use Doctrine\ORM\Query\Expr;
use Lexik\Bundle\FormFilterBundle\Filter\Extension\Type\FilterTypeSharedableInterface;

class VisiteFilterType extends AbstractType implements FilterTypeSharedableInterface{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('libelle', 'filter_text')
                ->add('ville', 'filter_entity', array('class'=>'BECFranceBackBundle:Ville', 'property'=>'nom'));

    }

    public function getName()
    {
        return 'becfrance_backbundle_filter_visite';
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'csrf_protection'   => false,
            'validation_groups' => array('filtering') // avoid NotBlank() constraint-related message
        ));
    } 

    public function addShared(FilterBuilderExecuterInterface $qbe)
    {
        $closure = function(QueryBuilder $filterBuilder, $alias, $joinAlias, Expr $expr) {
            // add the join clause to the doctrine query builder
            // the where clause for the label and color fields will be added automatically with the right alias later by the Lexik\Filter\QueryBuilderUpdater
            $filterBuilder->leftJoin($alias.'.visite', 'visite');
        };

        // then use the query builder executor to define the join, the join's alias and things to do on the doctrine query builder.
        $qbe->addOnce($qbe->getAlias().'.visite', 'visite', $closure);
    }
}

<?php

namespace BECFrance\BackBundle\Filter;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

use Doctrine\ORM\QueryBuilder;

use Lexik\Bundle\FormFilterBundle\Filter\FilterBuilderExecuterInterface;
use Lexik\Bundle\FormFilterBundle\Filter\Expr;
use Lexik\Bundle\FormFilterBundle\Filter\Extension\Type\FilterTypeSharedableInterface;


class VilleFilterType extends AbstractType implements FilterTypeSharedableInterface{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('nom', 'filter_text')
                ->add('codePostal', new CodePostalFilterType())
                //->add('codePostal', 'filter_number')
                ->add('zoneGeographique', new ZoneGeographiqueFilterType())
                ->add('pays', new PaysFilterType);

    }

    public function getName()
    {
        return 'becfrance_backbundle_filter_ville';
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'csrf_protection'   => false,
            'validation_groups' => array('filtering') // avoid NotBlank() constraint-related message
        ));
    } 

    public function addShared(FilterBuilderExecuterInterface $qbe)
    {
        $closure = function(QueryBuilder $filterBuilder, $alias, $joinAlias, Expr $expr) {
            // add the join clause to the doctrine query builder
            // the where clause for the label and color fields will be added automatically with the right alias later by the Lexik\Filter\QueryBuilderUpdater
            $filterBuilder->leftJoin($alias.'.ville', 'ville');
        };

        // then use the query builder executor to define the join, the join's alias and things to do on the doctrine query builder.
        $qbe->addOnce($qbe->getAlias().'.ville', 'ville', $closure);
    }
}

Actually I use filter_entity as filter of Ville, but I want to use the filter nom in VilleFilterType. I've tried to use new VilleFilterType instead, but it returned all the filters in VilleFilterType that there are some filters I don't need.

Any proposition?

Thanks

@cedric-g
Copy link
Collaborator

Hi, maybe you can pass an option to the VilleFilterType and add fields you need. So in your VilleFilterType you can add a "all_fields" option:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    // fields you always need
    $builder->add(...)

    // addtional fields
    if ($options['all_fileds']) {
        $builder->add(...)
    }
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        // ...
        'all_fields' => true,
    ));
} 

And then when you use your type you can do something like:
$builder->add('ville', new VilleFilterType(), array('all_fields' => false));

@bearsroom
Copy link
Author

I've found another solution: I used the apply_filter option which allow us to build a specific query like this:

class VisiteFilterType extends AbstractType implements FilterTypeSharedableInterface{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('libelle', 'filter_text')
                ->add('ville', 'filter_text', array(
                    'apply_filter' => function(QueryInterface $filterQuery, $field, $values){
                        if (!empty($values['value'])){
                            $qb = $filterQuery->getQueryBuilder();
                            $qb->andWhere('ville.nom LIKE :nom')
                               ->setParameter('nom', $values['value']);
                        }
                    }
                ));

    }

Thanks for the answer above.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants