I have a problem with a simple form. I have a class called JurisdictionUser() and my class form is JurisdictionUserNewType().
If I put the next code, its work fine:
$jurisdiction_user = new JurisdictionUser();
$form = $this->createFormBuilder($jurisdiction_user)
->add('name', 'text')
->add('email', 'text', array('required' => false))
->add('save', 'submit')
->getForm();
but, if I put the next code:
$jurisdiction_user = new JurisdictionUser();
$form = $this->createFormBuilder(new JurisdictionUserNewType(), $jurisdiction_user);
It give me the next error:
ContextErrorException: Catchable Fatal Error: Argument 2 passed to Symfony\Bundle\FrameworkBundle\Controller\Controller::createFormBuilder() must be of the type array, object given, called in /home/sierra/dev_env/iyc-open010/src/Radmas/BackofficeAdminBundle/Controller/UserAdminController.php on line 119 and defined in /home/sierra/dev_env/iyc-open010/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php line 175
I need help xD. My class JurisdictionUserNewType().
<?php
/**
* Created by PhpStorm.
* User: diego
* Date: 15/01/14
* Time: 16:21
*/
namespace Radmas\BackofficeAdminBundle\Form\Type;
use Radmas\BackofficeAdminBundle\Form\Transformer\CapitalToSmallLetterTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class JurisdictionUserNewType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$transformer = new CapitalToSmallLetterTransformer();
$builder
->add('name', 'text');
$builder->add(
$builder->create('email', 'text', array('required' => false))
->addModelTransformer($transformer)
);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Radmas\Open010Bundle\Document\JurisdictionUser'
));
}
public function getName()
{
return 'jurisdictionUserNew';
}
}
You should use
$this->createForm(new JurisdictionUserNewType(), $jurisdiction_user)
in controller, instead of createFormBuilder.
Related
How to call the Service Container object from form events?
I created a form where the webmaster can create books. I want to create a Sylius Product when an Book is created through this form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', TextType::class, array(
'attr' => array('class'=>'block1')
))
->addEventListener(
FormEvents::PRE_SET_DATA,
array($this, 'onPreSetData')
)
;
}
public function onPreSetData(FormEvent $event)
{
$book = $event->getData();
$form = $event->getForm();
$productFactory = $this->container->get('sylius.factory.product');
}
For that purpose, I need to reach 'sylius.factory.product' service as explained there: http://docs.sylius.org/en/latest/book/products/products.html
$productFactory = $this->container->get('sylius.factory.product');
I can access it from any Controller, but unfortunately I can't access it from the BookType class I defined.
Here is the error returned by Symfony when I try to access it from the buildForm() or onPreSetData() function:
Notice: Undefined property: FrontendBundle\Form\BookType::$container
Pass the service, to the form, via the options
Actually this process is very well explained in Symfony Documentation: http://symfony.com/doc/current/form/form_dependencies.html
So I updated the way I was calling my form like that:
$editForm = $this->createForm($form, $item, array( //WITH SYLIUS
'sylius_factory_product' => $this->get('sylius.factory.product')
));
Instead:
$editForm = $this->createForm($form, $item); //WIHOUT SYLIUS
Plus, I adapted the configureOptions function like that:
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setDefaults(array(
'data_class' => 'FrontendBundle\Entity\Book'
))
->setRequired('sylius_factory_product')
;
}
Instead:
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setDefaults(array(
'data_class' => 'FrontendBundle\Entity\Book'
))
;
}
You can now access your service in the buildForm function like so:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$productFactory = $options['sylius_factory_product'];
//...
}
I would like to overload a form of the bundle FOSComment. I would like to know i have to create a new bundle Comment or if i can do it from my working/main bundle ?
Sorry for my english.
Thank you,
David
namespace FOS\CommentBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class CommentType extends AbstractType
{
private $commentClass;
public function __construct($commentClass)
{
$this->commentClass = $commentClass;
}
/**
* Configures a Comment form.
*
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('body', 'textarea')
->add('lien', 'text', array('required' => false,
'empty_data' => null));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
parent::setDefaultOptions($resolver);
$resolver->setDefaults(array(
'data_class' => $this->commentClass,
));
}
public function getName()
{
return "fos_comment_comment";
}
}
For the moment i put my field lien directly in the vendor file which i know is not the good way.
i think all you need to do is override the service definition of the form you want to overload:
e.g. (if you have a services.yml)
fos_comment.form_type.comment.default
class: Project/MyBundle/Form/CustomFormType
arguments:[%fos_comment.model.comment.class%]
tags:
- { name: form.type, alias: fos_comment_comment }
I have a form which works fine. It persists data to two entities (News and Illustration). In fact, it will be possible, in a near future, that the user can add multiple illustrations to the news. BUT, not now :)...
So i've the backend ready for this and when I run the action which calls the formbuilder which builds the form with two FormTypes:
class NewsType extends AbstractType
{
public function buildForm( FormBuilderInterface $builder, array $options )
{
$builder
->add('date', 'date')
->add('titre', 'text')
->add('contenu', 'textarea')
->add('publication', 'checkbox', array('required' => false))
->add('illustrations', 'collection', array(
'type' => new IllustrationType(),
'allow_add' => false,
'required' => false
));
}
public function getName()
{
return 'News';
}
}
class IllustrationType extends AbstractType
{
public function buildForm( FormBuilderInterface $builder, array $options )
{
$builder
->add('file', 'file');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Fcbg\NewsBundle\Entity\Illustration',
'cascade_validation' => true,
));
}
public function getName()
{
return 'Illustration';
}
}
The form output renders something like that:
Some idea why I have the "illustrations: 0" ? XD
Thx a lot
You see this because you didn't say how many Illustration you want to display (1? 2? 0? 100?). In doubt, Symfony chose to display none.
Either you allow the user to create one or several new Illustration by setting 'allow_add' => true, (what you don't want to do yet, I understood), or you manually create one (or even several) Illustration in your NewsController.php:
public function addAction()
{
$news = new News();
$Illustration = new Illustration();
$news->addIllustration($illustration);
// create your form and display it
}
I cannot get $this->generateUrl() work, but it's work from my controller, or should I define 'setAction' using another way ?
class UserLoginType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->setMethod('POST')
->setAction($this->generateUrl('fos_user_security_check'))
->add('username', 'text')
->add('password', 'password')
->add('save', 'submit');
}
public function getName()
{
return 'user_login';
}
}
If you are building your form in a separate class and not in your controller, you should pass the action to the form type like this:
// In your controller
$form = $this->createForm(new FormType(), $object, array(
'action' => $this->generateUrl('target_route'),
'method' => 'POST',
));
The AbstractType does not contain any method generateUrl(), that's why you can't set the action in the type directly. You can find details here: http://symfony.com/doc/current/book/forms.html#changing-the-action-and-method-of-a-form
Yes, in the Form class, function buildForm , put this:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->setMethod('POST')
->setAction( $options["data"]["action"])
->add('name', TextType::class, array('label' => 'Nombre'))
;
}
I've defined a Form that only have one 'collection' type field:
<?php
namespace GMC\AccesoSistemaBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use GMC\AccesoSistemaBundle\Form\FuncionType;
class FuncionesType Extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('funciones', 'collection', array(
'type' => new FuncionType(),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false));
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => null
));
}
public function getName() {
return 'gmc_accesosistemabundle_funcionestype';
}
Then I create a form in my controller:
public function mostrarFuncionesAction() {
$em = $this->getDoctrine()->getManager();
$funciones = $em->getRepository('AccesoSistemaBundle:Funcion')->findAll();
$formulario = $this->createForm(new FuncionesType(), $funciones);
return $this->render(
'AccesoSistemaBundle:Default:funciones.html.twig',
array('formulario' => $formulario->createView())
);
}
But even when $funciones has two records, the 'funciones' collection of the form is empty, why? Am I missing anything?
As you can see I'm a complete newbbie with Symfony2 so please be patient with me.
Thanks in advance for your help!
What Symfony is doing with your current code is :
take the $functiones object (instance of Function class)
look for an attribute called functiones in Function class
hydrate your form with data found in this attribute
If you want to use an entity mappin, you have to name your form field (with $builder->add('<name_here>')) as an attribute of your Function class, which is the collection of Function.
Else, you can try to hydrate your form with an array, giving :
$formulario = $this->createForm(new FuncionesType(), array('functiones' => $funciones));