I have this entity, using the query builder I get a list of options to display in a select, then I want to select one of this option. I'm using 'data' to select the option with id = 1 but it doesn't work, any idea on how to select an option?
thanks
public function buildForm(FormBuilderInterface $builder, array $options)
{
if($options['project'] instanceof Cpj\ProjectsBundle\Entity\Project){
$projectId = $options['project']->getId();
}
else{
$projectId = null;
}
if($options['sprint'] instanceof Cpj\ProjectsBundle\Entity\Sprint ){
$sprintId = $options['sprint']->getId();
}
else{
$sprintId = null;
}
$builder
->add('type', 'choice', array(
'choices' => array(
'' => '--',
'new' => 'New',
'bugfix' => 'Bugfix'
)))
->add('name', 'text')
->add('project', 'entity', array(
'class' => 'CpjProjectsBundle:Project',
'property' => 'name',
'empty_value' => '--',
'empty_data' => null,
'required' => false,
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('u')
->where("u.user = :id_user")
->setParameter('id_user', $this->user);
},
'data' => $projectId,
))
->add('sprint', 'entity', array(
'class' => 'CpjProjectsBundle:Sprint',
'property' => 'name',
'empty_value' => '--',
'empty_data' => null,
'required' => false,
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('u')
->where("u.user = :id_user")
->setParameter('id_user', $this->user);
},
'data' => $sprintId,
))
->add('importance', 'text')
->add('storypoints', 'text')
->add('description', 'textarea')
->add('howtoprove', 'textarea')
->add('save', 'submit');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'project' => null,
'sprint' => null,
));
}
public function __construct ($user)
{
$this->user = $user;
}
public function getName()
{
return 'story';
}
this is the action I'm using
public function newAction(Request $request)
{
$user = $this->getUser();
$story = new Story();
$id_project = $request->query->get('project');
$id_sprint = $request->query->get('sprint');
$form = $this->createForm(new StoryType($user), $story);
$form->getData()->getProject()->setValue($id_project);
$form->getData()->getSprint()->setValue($id_sprint);
$form->setData($form->getData());
$project = $this->getDoctrine()->getRepository('CpjProjectsBundle:Project')->findOneBy(array(
'id' => $id_project,
'user' => $user,
));
$sprint = $this->getDoctrine()->getRepository('CpjProjectsBundle:Sprint')->findOneBy(array(
'id' => $id_sprint,
'user' => $user,
));
$form = $this->createForm(new StoryType($user), $story, array(
'project' => $project,
'sprint' => $sprint,
));
$form->handleRequest($request);
if($form->isValid())
{
$story->setUser($user);
$em = $this->getDoctrine()->getManager();
$em->persist($story);
$em->flush();
return $this->redirect($this->generateUrl('cpj_stories_homepage'));
}
return $this->render('CpjProjectsBundle:Story:new.html.twig', array(
'form' => $form->createView(),
));
}
You may try just setting the project and the sprint on the new story entity before passing it to form create. Something like this:
public function newAction(Request $request)
{
$user = $this->getUser();
$story = new Story();
$id_project = $request->query->get('project');
$id_sprint = $request->query->get('sprint');
$project = $this->getDoctrine()->getRepository('CpjProjectsBundle:Project')->findOneBy(array(
'id' => $id_project,
'user' => $user,
));
$sprint = $this->getDoctrine()->getRepository('CpjProjectsBundle:Sprint')->findOneBy(array(
'id' => $id_sprint,
'user' => $user,
));
$story->setProject($project);
$story->setSprint($sprint);
$form = $this->createForm(new StoryType($user), $story);
$form->handleRequest($request);
if($form->isValid())
{
$story->setUser($user);
$em = $this->getDoctrine()->getManager();
$em->persist($story);
$em->flush();
return $this->redirect($this->generateUrl('cpj_stories_homepage'));
}
return $this->render('CpjProjectsBundle:Story:new.html.twig', array(
'form' => $form->createView(),
));
}
Then in your form would look like:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('type', 'choice', array(
'choices' => array(
'' => '--',
'new' => 'New',
'bugfix' => 'Bugfix'
)))
->add('name', 'text')
->add('project', 'entity', array(
'class' => 'CpjProjectsBundle:Project',
'property' => 'name',
'empty_value' => '--',
'empty_data' => null,
'required' => false,
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('u')
->where("u.user = :id_user")
->setParameter('id_user', $this->user);
},
))
->add('sprint', 'entity', array(
'class' => 'CpjProjectsBundle:Sprint',
'property' => 'name',
'empty_value' => '--',
'empty_data' => null,
'required' => false,
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('u')
->where("u.user = :id_user")
->setParameter('id_user', $this->user);
}
))
->add('importance', 'text')
->add('storypoints', 'text')
->add('description', 'textarea')
->add('howtoprove', 'textarea')
->add('save', 'submit');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'CpjProjectsBundle:Story'
));
}
You can also take out all of the stuff above $builder->add()... in the form
Related
How to add validation group to RepeatedType? I want to enable RepeatedType validation for specific group only (ex. 'updatePasswords') like during the constraint validation.
Here's my form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('updatePasswordCheckBox', CheckboxType::class)
->add('plainPassword', RepeatedType::class, array(
'type' => PasswordType::class,
'first_options' => array('label' => 'Password'),
'second_options' => array('label' => 'Repeat password'),
'invalid_message' => "Passwords don't match!",
'groups' => "updatePasswordChecked",
))
->add('save', SubmitType::class, array('label' => 'Save'));
}
UPDATE:
Depending on the status of the password checkbox the corresponding validation group will be triggered:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'ImmoBundle\Entity\User',
'csrf_protection' => true,
'validation_groups' => function(FormInterface $form){
$data = $form->getData();
if ($data->getUpdatePasswordCheckBox() == 1)
{
return array('Default', 'updatePasswordChecked');
}
else
{
return array('Default', 'update');
}
}
));
}
want to pre select my form in Symfony.
I do it with the Form builder. It works except of the child table is not saving.
My Invoice Type
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('invoiceNumber', 'hidden', array('label' => ''))
->add('date', 'date', array('label' => 'Field', 'data' => new \DateTime("now")))
->add('PaidPrice', 'money', array('label' => 'Bereits bezahlt', 'attr' => array('class' => '')))
->add('invoicepos', 'collection', array(
'type' => new InvoiceposType(),
'allow_add' => true,
'allow_delete' => true,
'cascade_validation' => true,
'by_reference' => true,
))
;
}
My invoicepos Type
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('pos', 'text', array('label' => '', 'attr' => array()))
->add('quantity', 'hidden')
->add('price', 'hidden')
->add('tax', 'hidden')
;
}
My Controller to start the Form
public function newAction($id) {
$em->persist($entInvoice);
//$em->flush($entInvoice); //works perfect, but i dont want to save that, just pre select for the form
$form = $this->createCreateForm($entInvoice);
return array(
'entity' => $entInvoice,
'form' => $form->createView(),
);
}
Code when i submit the form
public function createAction(Request $request) {
$entity = new Invoice();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('pspiess_letsplay_invoice_show', array('id' => $entity->getId())));
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
The data is there, but with nor relation!
What did i wrong?
Thanks for help.
Found a solution for my problem.
Before i flush i add the child entity...
foreach ($entity->getInvoicepos() as $entInvoice) {
$entity->addInvoicepos($entInvoice);
}
I asked a question here How to use Repository custom functions in a FormType but nobody anwsered, so i did a little digging and advanced a little but i still get this error:
Notice: Object of class Proxies\__CG__\Kpr\CentarZdravljaBundle\Entity\Category
could not be converted to int in /home/kprhr/public_html/CZ_Symfony/vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceList.php line 457
Now this is how my CategoryType looks like:
<?php
namespace Kpr\CentarZdravljaBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Bridge\Doctrine\RegistryInterface;
class CategoryType extends AbstractType
{
private $doctrine;
public function __construct(RegistryInterface $doctrine)
{
$this->doctrine = $doctrine;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Kpr\CentarZdravljaBundle\Entity\Category',
'catID' => null,
));
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$someId = $builder->getData()->getId();
$param = ($someId) ? $someId : 0;
$catID = $options['catID'];
$builder->add('name', 'text', array('attr' => array('class' => 'span6')));
$builder->add('file', 'file', array('image_path' => 'webPath', 'required' => false));
$builder->add('parent', 'choice', array(
'choices' => $this->getAllChildren($catID),
'required' => false,
'attr' => array('data-placeholder' => '--Izaberite Opciju--'),
));
$builder->add('tags', 'tag_selector', array(
'required' => false,
));
$builder->add('status', 'choice', array(
'choices' => array('1' => 'Aktivna', '0' => 'Neaktivna'),
'required' => true,
));
$builder->add('queue', 'text', array('attr' => array('class' => 'span3')));
}
private function getAllChildren($catID)
{
$choices = array();
$children = $this->doctrine->getRepository('KprCentarZdravljaBundle:Category')->findByParenting($catID);
foreach ($children as $child) {
$choices[$child->getId()] = $child->getName();
}
return $choices;
}
public function getName()
{
return 'category';
}
}
I am accessing the CategoryRepository function findByParenting($parent) from the CategoryType and I am getting the array populated with accurate data back from the function getAllChildren($catID) but the error is there, i think that Symfony framework is expecting an entity field instead of choice field, but dont know how to fix it.
I also changet the formCreate call in the controller giving $this->getDoctrine() as an argument to CategoryType():
$form = $this->createForm(new CategoryType($this->getDoctrine()), $cat, array('catID' => $id));
Ok i managed to resolve the dilemma. The answer was easy all I had to do is change
$builder->add('parent', 'choice', array(
'choices' => $this->getAllChildren($catID),
'required' => false,
'attr' => array('data-placeholder' => '--Izaberite Opciju--'),
));
to this:
$builder->add('parent', 'entity', array(
'class' => 'KprCentarZdravljaBundle:Category',
'choices' => $this->getAllChildren($catID),
'property' => 'name',
'required' => false,
'attr' => array('data-placeholder' => '--Izaberite Opciju--'),
));
And change the getAllChildren(..) function so that it returns objects
private function getAllChildren($catID)
{
$choices = array();
$children = $this->doctrine->getRepository('KprCentarZdravljaBundle:Category')->findByParenting($catID);
foreach ($children as $child) {
$choices[$child->getId()] = $child->getName();
}
return $choices;
}
I changed it to:
private function getAllChildren($catID)
{
$children = $this->doctrine->getRepository('KprCentarZdravljaBundle:Category')->findByParenting($catID)
return $children;
}
Lots of thanks to user redbirdo for pointing out the choices option on an entity field.
It seems like you are doing something too much complicated.
You are on the right way when you write Symfony framework is expecting an entity field instead of choice field.
To do this, replace:
$builder->add('parent', 'choice', array(
'choices' => $this->getAllChildren($catID),
'required' => false,
'attr' => array('data-placeholder' => '--Izaberite Opciju--'),
));
by:
$builder->add('users', 'entity', array(
'class' => 'KprCentarZdravljaBundle:Category',
'property' => 'name',
'query_builder' => function(EntityRepository $er) use($catID) {
return $er->findByParenting($catID);
},
'required' => false,
'empty_value' => '--Izaberite Opciju--'
));
(and you don't need getAllChildren($catID) anymore unless used somewhere else)
http://symfony.com/doc/current/reference/forms/types/entity.html
I created form EditFormType with code:
// ...
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ...
$builder->addEventSubscriber(new UnsetReadOnlyForEmailField());
}
// ...
and UnsetReadOnlyForEmailField:
// ...
public static function getSubscribedEvents()
{
return array(
FormEvents::PRE_SET_DATA => 'preSetData'
);
}
public function preSetData(FormEvent $event)
{
$form = $event->getForm();
$data = $event->getData();
if ($data === null) {
return;
}
if ($data->getId() === null) {
$form->add(
'plainPassword',
'repeated',
array(
'type' => 'password',
'options' => array('translation_domain' => 'FOSUserBundle', 'required' => true),
'first_options' => array('label' => 'form.password'),
'second_options' => array('label' => 'form.password_confirmation'),
'invalid_message' => 'fos_user.password.mismatch',
)
);
}
}
// ...
Unfortunately required for repeated field doesn't work, field is't required. Any suggestions? If I do it wrong, then please write to set the fields in the form are required or not, depending on the form to edit or add. On add form required, on edit form not required.
I think you can do it in such way:
$form->add(
'plainPassword',
'repeated',
array(
'type' => 'password',
'options' => array('translation_domain' => 'FOSUserBundle'),
'first_options' => array(
'label' => 'form.password',
'required' => true
),
'second_options' => array(
'label' => 'form.password_confirmation',
'required' => true
),
'invalid_message' => 'fos_user.password.mismatch',
)
);
I have selected an entity/record from the database and pass it to my form. The form loads correctly, but when I hit save it adds a new record instead of updating the existing one.
PlanController.php
public function editPlanAction($id, Request $request)
{
$em = $this->getDoctrine()->getManager();
$plan = $em->getRepository('etrakOnlineOrderProcessingBundle:Plan')->find($id);
if (!$plan && !$request->isMethod('POST')) {
throw $this->createNotFoundException(
'No plan found for id ' . $id
);
}
$form = $this->createForm(new PlanType(), $plan);
if ($request->isMethod('POST')) {
$form->bind($request);
if ($form->isValid()) {
$editPlan = $form->getData();
$em->flush();
}
}
return $this->render('etrakCustomerServiceBundle:Plan:edit.html.twig', array('form' => $form->createView()));
}
routing.yml
etrak_customer_service_plan_edit:
pattern: /plan/edit/{id}
defaults: { _controller: etrakCustomerServiceBundle:Plan:editPlan }
PlanType.php
namespace etrak\CustomerServiceBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class PlanType extends AbstractType
{
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'etrak\OnlineOrderProcessingBundle\Entity\Plan',
'cascade_validation' => true,
));
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$termsConditionsArray = array("NONE" => "No Contract", "1 Year Contract" => "1 Year Contract", "2 Year Contract" => "2 Year Contract");
$billingFrequencyArray = array("1" => "Monthly", "6" => "6 Months", "12" => "Yearly");
// Create the form
$builder->add('name', 'text', array('label' => 'Plan Name: ', 'required' => false));
$builder->add('description', 'text', array('label' => 'Plan Description: ', 'required' => false));
$builder->add('termsConditions', 'choice', array('choices' => $termsConditionsArray, 'label' => 'Terms & Conditions', 'required' => false));
$builder->add('amount', 'text', array('label' => 'Plan Price: ', 'required' => false));
$builder->add('affinity', 'choice', array('choices' => array('0' => 'Yes', '1' => 'No'), 'label' => 'Affinity? ', 'expanded' => true, 'required' => false));
$builder->add('deactivationFee', 'text', array('label' => "Deactivation Fee: ", 'required' => false));
$builder->add('recurringInMonths', 'choice', array('choices' => $billingFrequencyArray, 'label' => 'Billing Frequency: ', 'required' => false));
$builder->add('pricingTier', 'entity', array(
'class' => 'etrakOnlineOrderProcessingBundle:pricingTier',
'property' => 'name',
'label' => "Select Pricing Tier: "
));
$builder->add('activeStartDate', 'datetime', array('label' => "Effective Start Date: ", 'required' => false));
$builder->add('activeEndDate', 'datetime', array('label' => "Effective End Date: ", 'required' => false));
}
public function getName()
{
return 'plan';
}
}
Any help would be greatly appreciated!
The problem is that you not posting the id of the plan object. Hence a new one is being created when you do the getData. Add id as a hidden field or add it to your post url in the template. Actually, I don't think the hidden field will work. Probably need to just update the post url.
if ($form->isValid()) {
$editPlan = $form->getData();
$em->persist($editPlan);
$em->flush();
}
Maybe you forget to persist entities.