简体   繁体   中英

Symfony FormType, get Dropdown from Arraycollection

i have my Entity Product with an Arraycollection of featureTypes (ManytoMany) Class Product:

/**
 * @var FeatureType
 *
 * @ORM\ManyToMany(targetEntity="AppBundle\Entity\FeatureType", mappedBy="products")
 */
private $featureTypes;

public function __construct()
{
    $this->variants = new ArrayCollection();
    $this->featureTypes = new ArrayCollection();
}

Class FeatureType:

/**
 * @var Product[]|ArrayCollection
 *
 * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Product", inversedBy="featureTypes")
 * @ORM\JoinTable(name="products_featureTypes")
 */
private $products;

Now i want to create a form which render me a dropdown of all available featureTypes. I want to select one and submit it.

I tried it like this in my addFeatureTypeToProductType:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('featureTypes', EntityType::class, [
            'class' => FeatureType::class,
            'choice_label' => 'name',
        ])
        ->add('submit', SubmitType::class)
        ->getForm();
}

The output is the Dropdown with all available FeatureTypes. But when I submit the selected featureType, i get an error: "Could not determine access type for property 'featureType'".

Then I tried this way:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('featureTypes', CollectionType::class, [
            'entry_type' => FeatureType::class,
            'allow_add' => true,
        ])
        ->add('submit', SubmitType::class)
        ->getForm();
}

But this does not work

My Controller:

public function addFeatureTypeAction(Request $request, Product $product)
{
    $form = $this->createForm(AddFeatureTypeToProductType::class, $product, [
        'action' => $this->generateUrl('admin_products_add_featureTypes', [
            'product' => $product->getId()
        ])
    ]);

    $form->handleRequest($request);


    if($form->isSubmitted() && $form->isValid()) {
        $featureType = $form->get('featureTypes');
        $product->addFeatureTypes($featureType);
        $em = $this->getDoctrine()->getManager();
        $em->persist($product);
        $em->flush();

        return $this->redirectToRoute('admin_products_list_all');
    }

    return [
        'form' => $form->createView()
    ];
}

Sorry for my english :S

EDIT: Here are my adder/remover and setter/getter:

/**
 * @return FeatureType
 */
public function getFeatureTypes()
{
    return $this->featureTypes;
}

/**
 * @param FeatureType $featureTypes
 */
public function setFeatureTypes($featureTypes)
{
    $this->featureTypes = $featureTypes;
}


/**
 * Add new FeatureType
 *
 * @param FeatureType $featureType
 *
 * @return Product
 */
public function addFeatureTypes($featureType)
{
    if (!$this->featureTypes->contains($featureType)) {
        $this->featureTypes->add($featureType);
    }

    return $this;
}

/**
 * @param FeatureType $featureType
 *
 * @return Product
 */
public function removeFeatureTypes($featureType)
{
    if ($this->featureTypes->contains($featureType)) {
        $this->featureTypes->remove($featureType);
    }

    return $this;
}

EDIT 2: I tried it again with the first way of my form. But i get a new Error now. I don' know why my entity "FeatureType" don't knows the contains method. It uses the Symfony Arraycollection

Error: Attempted to call an undefined method named "contains" of class "AppBundle\\Entity\\FeatureType".

Debugging stops in addFeatureTypes($featureType)

Im one step further now. Now, I uses the collectionType.

 public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('featureTypes', CollectionType::class, [
            'entry_type' => FeatureTypeType::class,
            'allow_add' => true,
        ])
        ->add('submit', SubmitType::class)
        ->getForm();
}

My frontend form shows all featureTypes, which my product already has. But i don't know, how too add a new one...

The annotation of my properties were wrong. Class Product:

/**
 * @var FeatureType[]|ArrayCollection
 *
 * @ORM\ManyToMany(targetEntity="AppBundle\Entity\FeatureType", inversedBy="products", cascade={"persist"})
 * @ORM\JoinTable(name="products_featureTypes")
 */
private $featureTypes;

Class FeatureType:

/**
 * @var Product[]|ArrayCollection
 *
 * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Product", mappedBy="featureTypes", cascade={"persist"})
 *
 */
private $products;

My Form:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('featureTypeToAdd', EntityType::class, [
            'class'        => FeatureType::class,
            'choice_label' => 'name',
            'mapped'       => false,
        ])
        ->add('submit', SubmitType::class)
        ->getForm();
}

And my Controller:

 public function addFeatureTypeAction(Request $request, Product $product)
{
    $form = $this->createForm(AddFeatureTypeToProductType::class, $product, [
        'action' => $this->generateUrl('admin_products_add_featureTypes', [
            'product' => $product->getId(),
        ]),
    ]);

    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $featureType = $form->get('featureTypeToAdd')->getData();
        $em = $this->getDoctrine()->getManager();
        $product->addFeatureTypes($featureType);
        $em->persist($product);
        $em->flush();

        return $this->redirectToRoute('admin_products_list_all');
    }

    return [
        'form' => $form->createView(),
    ];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM