This is a follow on from the earlier question Symfony2 Custom Form Type or Extension
I am trying to attach a custom field type for Product on an Order. The name field will contain the product name and the id field the product id.
I am using FormEvents::PRE_SET_DATA to try and populate the data but it throws an error, getData() returns Form\Type\ProductAutoCompleteType.
How do I correct the code?
OrderType has the following:
$builder->add('product', new Type\ProductAutoCompleteType(), array(
'data_class' => 'Acme\TestBundle\Entity\Product'
));
ProductAutoCompleteType:
class ProductAutoCompleteType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('name');
$builder
->add('id');
/* Turns out this is not needed any more
$builder->addEventListener(
FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$form = $event->getForm();
$product = $form->getData();
$form
->add('name', 'text', array('mapped' => false, 'data' => $product->getName()));
}
);
*//
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
}
public function getParent()
{
return 'form';
}
public function getName()
{
return 'productAutoComplete';
}
}
Updated
Error: FatalErrorException: Error: Call to a member function getProduct() on a non-object in /var/www/symblog/src/Acme/TestBundle/Form/Type/ProductAutoCompleteType.php line 26
Controller
$em = $this->getDoctrine()->getManager();
$order = $em->getRepository('AcmeTestBundle:Order')->find(6);
$form = $this->createForm(new OrderType(), $order);
Updated 2
After changing the field [product][id] and submitting the form I now get the following error, I assume this is because the field name is [product][id] and not [product]?
Neither the property "id" nor one of the methods "setId()", "set()" or "__call()" exist and have public access in class "Proxies__CG\Acme\TestBundle\Entity\Product".
Updated 3
I have it submitting data to the controller now, in my controller on submit I have had to add the following, it looks messy to do validation and attach the product this way, is this the right way?
$data = $request->request->get($form->getName());
if ($data['product']['id']) {
$product = $em->getRepository('AcmeTestBundle:Product')->find($data['product']['id']);
if ($product) {
if ($product->getShop()->getId() != $order->getShop()->getId()) {
$form->get('product')->get('name')->addError(new FormError('Invalid shop product'));
}
$form->getData()->setProduct($product);
} else {
$form->get('product')->get('name')->addError(new FormError('A product must be selected'));
}
}
OrderEntity?PRE_SET_DATA, I think you don't have the $order in there just yet. Try using thePOST_SET_DATAevent for this case. (I do hope I am not pushing you into a completely wrong direction when getting you implement a form listener. Could be that I don't see your complete use case.)