Sébastien
Sébastien

Reputation: 5453

symfony filter collection field type like entity field type

I have a form with a collection field type. I'd like to filter it as we can do for entity field types but I'm not finding the solution.

i found other similar questions but no satisfiable answer so far. Can we do something like :

$builder
    ->add('userIngredients', 'collection', array(
            'type' => new UserImportedIngredientType($this->userIngredients),
            'query_builder'=>$this->queryBuilder,
        ))
;

If not, can we use form listener event to exclude some elements based on the object property ? How ?

This collection represents userIngredients that I want the user to be able to change if they have their property isImported set to true, hence the search for the query_builder solution.

Upvotes: 2

Views: 3466

Answers (3)

metanerd
metanerd

Reputation: 742

I solved it like this in my case with additionally Sonata on top of Symfony. What I did was feeding the 'data' parameter the specifically doctrine queried array of entities result. (In Repository: return $queryBuilder->getQuery()->getResult();)

/** @var MyEntityRepository $myEntityRepository */
$myEntityRepository = $this->getEntityManager()->getRepository(MyEntity::class);
/** @var MyEntity[] $myEntities */
$myEntities = $myEntityRepository->findBySomeCriteriaFilter(
    $parameter, Constants::specificConstant
);

$formMapper->add(
    // html name=
    'myEntityProperty',
     \Symfony\Component\Form\Extension\Core\Type\CollectionType::class,
     [
         // specific form for MyEntity
         'entry_type' => new Form\MyEntity\MyEntityType(),
         'allow_add' => true,
         'label' => false,
         'entry_options' => [
             'label' => false
         ],
         // the filtered array of entities from doctrine repository query above
         'data' => $myEntities,
      ]
);

Use this instead of sonata_type_model_list, I guess. Also if you want to filter sonata_type_model, use EntityType instead and use the 'query_builder' option with a Closure and returning the queryBuilder instead of the array of entities. This is all very inconsistent, best don't use symfony and sonata at all.

Upvotes: 1

Sébastien
Sébastien

Reputation: 5453

Well, I figured I could do something as simple as build a regular form not attached to a parent entity.

In case this might help someone :

class UserImportedIngredientType extends AbstractType
{

    protected $userIngredients;
    protected $userImportedIngredients;

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        foreach ($this->userImportedIngredients as $userImportedIngredient)
        {
            /**
             * @var $userImportedIngredient UserIngredient
             */
            $builder
                ->add($userImportedIngredient->getId(), 'genemu_jqueryselect2_entity', array(
                        'query_builder'=>$this->userIngredients,
                        'class' => 'AppBundle:FoodAnalytics\UserIngredient',
                        'multiple' => false,
                        'label' => $userImportedIngredient->getName(),
                        'required'=>false,
                        'mapped' => false,
                        'data' => $userImportedIngredient
                    ))
            ;
        }
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'appbundle_foodanalytics_user_imported_ingredient';
    }

    public function __construct($userIngredients, $userImportedIngredients)
    {
        $this->userIngredients=$userIngredients;
        $this->userImportedIngredients=$userImportedIngredients;
    }
}

Upvotes: 1

Martin Fasani
Martin Fasani

Reputation: 823

As far as I know Collection does not have the query_builder option So you cannot go this way. Is hard to decipher what you are trying to do with 4 lines of formType.

Your code looks alright, except the unsuppported query_builder, and you are already passing the userIngredients to the constructor.

My though is that if you need to filter this, then you shouldn't do it in the collection Type, but in other place.

EDITED:

On a second though, you are trying to filter the collection in the wrong place. Is not on the base collection , but in :

 class  UserImportedIngredientType extends AbstractType {
  function __construct( $userIngredients ) {
   // Do your stuff
  }

  function buildForm( FormBuilderInterface $builder, array $options) {
   // Add here your entity with the query_filter option :)

  }
 }

Check the other entries in SO over Collections, there are many of them

Upvotes: 0

Related Questions