I have list developer, not all developer, developer who have some parameters by filter and I need create check box for this some developer and post developer in another action, in this action identification developer who have true checkbox, I try this but have null check develoepr
class SelectByIdentityType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('id', 'entity', array(
'required' => false,
'class' => 'ArtelProfileBundle:Developer',
'property' => 'id',
'property_path' => '[id]', # in square brackets!
'multiple' => true,
'expanded' => true
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => null,
'csrf_protection' => false
));
}
/**
* #return string
*/
public function getName()
{
return 'select';
}
}
and action where I visible my developers
/**
* Finds and displays a Project entity.
*
* #Route("/{id}/show", name="admin_project_show")
* #Method({"GET", "POST"})
* #Template()
* #ParamConverter("entity", class="ArtelProfileBundle:Project")
*/
public function showAction($entity, Request $request)
{
//some logic
$developers = $profileRepository->findBySkillsAndTag($developer, $skill_form);
$form = $this
->createForm(
new SelectByIdentityType(),
$developers
)
->createView()
return array(
'entity' => $entity,
'form' => $form,
'developers' => $developers,
);
}
and if I check developer click SEND and then in the controller action which receives the POSTed data:
/**
* Send email for Developers.
*
* #Route("/{id}/send", name="admin_project_send_email")
* #Method({"GET", "POST"})
* #Template()
* #ParamConverter("entity", class="ArtelProfileBundle:Project")
*/
public function sendAction($entity, Request $request)
{
$em = $this->getDoctrine()->getManager();
$developer = $request->getSession()->get('developer');
$form = $this
->createForm(new SelectByIdentityType())
;
$form->bind($request);
if ($form->isValid()) {
$data = $form->getData();//$data['id'] I have 0
$ids = array();
foreach ($data['id'] as $developer) {
$ids[] = $entity->getId();
}
$request->getSession()->set('admin/foo_list/batch', $ids);
}
Why in $data['id'] I have 0 ??
and my template
{% for entity in developers %}
<tr>
<td>{{ form_widget(form.id[entity.id]) }}</td>
Any ideas ??
You can filter the entities displayed in an entity field by using the query_builder option. That way you can just normally render the whole form and you get a checkbox list of only the entities that your query returns. If you need to display it in a special way, you can override the form templates.
Unfortunately, as far as I know you can't use DQL or repository methods in the query_builder option. You have to write the query-builder code directly into the form definition.
An example:
$builder->add('id', 'entity', array(
'required' => false,
'class' => 'ArtelProfileBundle:Developer',
'multiple' => true,
'expanded' => true
'query_builder' => function($repo)
{
return $repo->createQueryBuilder('d')
->where('x = y');
}
));
Related
I have a problem with my search form. It is possible that my select contains nothing.
This is why I would like to display a default message when it is empty.
However when I set my 'empty_data' attribute, nothing happens, always my empty select.
My FormType :
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('organisation',ChoiceType::class,array(
'choices' => $options['distributeurs'],
'choice_label' => function ($value, $key, $index) {
return $value->getOrganisation();
},
'choice_value' => 'id',
'empty_data' => 'No distributor found'
));
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'distributeurs' => 'ProjectBundle\Entity\Organisation\Organisation',
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'projectbundle_organisation_search';
}
And at the level of the controller :
$distributeurs = $em->getRepository('ProjectBundle:Organisation\Organisation')->createQueryBuilder('a')
->where('a.id IN (:distributeurs)')->setParameter('distributeurs',$organisationDistriId)->getQuery()->execute();
$form = $this->createForm('ProjectBundle\Form\Organisation\OrganisationDistributeurType', null, array(
'distributeurs' => $distributeurs,
'action' => $this->generateUrl('admin_organisations_index'),
'method' => 'GET',
));
The form and information work correctly, there is just the 'empty_data' attribute that is not displayed.
The 'placeholder' attribute works but that's not what I want.
Do you have an idea ?
Thanks !
Try to post your code next time and not a picture because that is not clear.
In your Form Builder try to create the select in this way (Placeholder is implemented from version 2.6):
$builder->add('organisation', ChoiceType::class, array(
'placeholder' => 'Choose an option',
));
I'm using the FOSUserBundle and I'm trying to customize a user registration form with an is_admin option. I'm at a loss as to why the option value is not passed from the createForm() function call to the buildForm() function.
Below is the corresponding code in the controller:
$has_admin_rights = $this->get('security.authorization_checker')
->isGranted('ROLE_SUPER_ADMIN');
/** #var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->get('fos_user.registration.form.factory');
/** #var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->get('fos_user.user_manager');
$user = $userManager->createUser();
...
$form = $formFactory->createForm(
new RegistrationFormType(), $user, array('is_admin' => $has_admin_rights));
Below is the custom form class which should, in theory, resolve the is_admin option. However it seems like the option is not properly passed.
class RegistrationFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
if($options['is_admin'] === true)
{
$builder->add('uniqueRole', 'choice', array(
'choices' => array('ROLE_ADMIN' => 'user.role.admin',
'ROLE_TEACHER' => 'user.role.teacher',
'ROLE_STUDENT' => 'user.role.student'),
'label' => 'form.label.role',
'expanded' => false,
'multiple' => false,
'mapped' => false
));
$builder->remove('plainPassword')->add('plainPassword', 'hidden', array('data' => 'defaultPwd'));
} else {
// Default value is indeed set,
// and options[is_admin] always equals to false
if (array_key_exists("is_admin", $options)){
echo 'Set!';
} else {
echo 'Not Set!';
}
}
$builder->add('save', 'submit', array('label' => 'actions.add'));
}
protected function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired(array(
'is_admin'));
$resolver->setDefaults(array(
'is_admin' => false,
'data_class' => 'VMB\UserBundle\Entity\User',
'intention' => 'registration',
));
}
// BC for SF < 2.7
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$this->configureOptions($resolver);
}
public function getParent()
{
return 'fos_user_registration';
}
public function getName()
{
return 'vmb_user_registration';
}
}
I've also tried passing the parameter to a constructor this way
$form = $formFactory->createForm(new RegistrationFormType($has_admin_rights), $user);
however the symfony2 appCache initializes the form object without the proper param value (which falls back to defined null default value).
What am I doing wrong?
I think it's just a matter of invoking the wrong service.
You obtained the instance of FormFactory through:
$formFactory = $this->get('fos_user.registration.form.factory');
but this is not Symfony's FormFactory. In the matter of fact if you look at it's source here, you will see this:
public function createForm()
{
return $this->formFactory->createNamed($this->name, $this->type, null, array('validation_groups' => $this->validationGroups));
}
Basically, createForm does not expect any arguments at all.
So, instead, you should use Symfony's own form.factory (source):
$has_admin_rights = $this->get('security.authorization_checker')->isGranted('ROLE_SUPER_ADMIN');
/** #var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->get('form.factory');
/** #var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->get('fos_user.user_manager');
$user = $userManager->createUser();
$form = $formFactory
->createBuilder(new RegistrationFormType(), $user, array('is_admin' => $has_admin_rights))
->getForm();
Hope this helps...
I have three entity for a project : Book, Author and Theme. For information, Author and Theme are linked with Book in Many to One/One to Many. A book has one or more author and one or more themes.
And I have generated crud about theses for basics functions (add, edit and delete) and default views/form.
But I need to do some functions search, three exactly:
Search Book with part of the Title
Search Book with one Author
Search Book with one or more Theme.
I coded the three functions and working good but I have a problem about the fields used in search forms.
The first one is correct, it show a input field where we put the title and the book list as result is correct but the two others …
Because of the relationship the field are drop list where the user choose a item and search it, the result is correct but I wish for the second to have an input field for search the author name and the last to display checkbox so I’ve made research but I can’t understand why in my forms type, I can’t change the kind of field I want.
Here my two Forms Type :
Search with one Author : I just want to display an input field and not a list but get error each time
<?php namespace Projet\BibliothequeBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class BookByAuthorType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('authors')
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Projet\BibliothequeBundle\Entity\Book'
));
}
/**
* #return string
*/
public function getName()
{
return 'authors';
}
}
Search Book with one or more Theme : I tried to display chechbox by link the 'themes' array to result of checkbox but don't work too.
<?php namespace Projet\BibliothequeBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class BookByThemeType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
// $themes = array();
// $themes=$builder->add('themes');
$builder
->add('themes', 'choice', [
'choices' => 'themes',
'multiple' => true,
'expanded' => true
])
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Projet\BibliothequeBundle\Entity\Book'
));
}
/**
* #return string
*/
public function getName()
{
return 'themes';
}
}
UPDATE : My BookController functions maybe it's the origin of my problems.
// AUTHOR SEARCH FUNCTIONS
public function SearchByAuthorAction() {
$entity = new Book();
$form = $this->CreateSearchAuthorForm($entity);
return $this->render('ProjetBibliothequeBundle:Book:searchbyauthor.html.twig', array(
'form' => $form->createView(),
));
}
private function CreateSearchAuthorForm(Book $entity) {
$form = $this->createForm(new BookByAuthorType(), $entity, array(
'action' => $this->generateUrl('book_submit_search_by_author'),
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Search'));
return $form;
}
public function SubmitSearchByAuthorAction(Request $request) {
$entity = new Book();
$form = $this->CreateSearchAuthorForm($entity);
$form->handleRequest($request);
$author = $form->get('authors')->getData();
$repository = $this->getDoctrine()
->getEntityManager()
->getRepository('ProjetBibliothequeBundle:Book');
$Booklist = $repository->findByAuthor($author);
return $this->render('ProjetBibliothequeBundle:Book:resultbyauthor.html.twig',
array('Booklist' => $Booklist));
}
//THEME SEARCH FUNCTIONS
public function SearchByThemeAction() {
$entity = new Book();
$form = $this->CreateSearchThemeForm($entity);
return $this->render('ProjetBibliothequeBundle:Book:searchbytheme.html.twig', array(
'form' => $form->createView(),
));
}
private function CreateSearchThemeForm(Livre $entity) {
$entities = $this->getDoctrine()->getManager()->getRepository('ProjetBibliothequeBundle:Book')->findAll();
$form = $this->createForm(new BookByThemeType(), $entity, array(
'action' => $this->generateUrl('book_submit_search_by_theme'),
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Search'));
return $form;
}
public function SubmitSearchByThemeAction(Request $request) {
$entity = new Book();
$form = $this->CreateSearchThemeForm($entity);
$form->handleRequest($request);
$theme = $form->get('themes')->getData();
$repository = $this->getDoctrine()
->getEntityManager()
->getRepository('ProjetBibliothequeBundle:Book');
$Booklist = $repository->findByTheme($theme);
return $this->render('ProjetBibliothequeBundle:Book:resultbytheme.html.twig',
array('Booklist' => $Booklist));
}
There is no need to set data_class for GET operations. Just create a basic form, may be like this:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('themes', 'choice', [
'choices' => 'themes',
'multiple' => true,
'expanded' => true
])
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(['method' => 'GET', 'csrf_protection' => false]);
}
in your action catch values from URL, pass them to findBy method or manually build you query:
public function someAction(Request $request)
{
...
$form->createForm(new FORM_TYPE, null);
....
$filters = $request->query->get($form->getName());
$result = $entityManager->getRepository(REPOSITORY)->findBy($filters, $orderBy, $limit, $offset);
...
}
still getting to grips with Symfony so please excuse me if this is already asked. I don't quite understand how to send data to forms to be processed properly so am need of a bit of guidance.
My issue is i wish to save my logged in user's ID into the database when they are creating a new gecko (so that this gecko's profile shows for only this user logged in). I am using FOSUserBundle by the way.
I know i can get the current user's id by using something like $user = $this->getUser()->getId(); However, i would like to save this into the database.
createAction:
public function createAction(Request $request)
{
$entity = new Gecko();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('gecko_show', array('name' => $entity->getName())));
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
GeckoType:
<?php
namespace Breedr\GeckoBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class GeckoType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('aquisitionDate')
->add('morph')
->add('sex', 'choice', array(
'choices' => array(
'Male' => 'Male',
'Female' => 'Female'
)
))
->add('genetics')
->add('bio')
->add('bred', 'checkbox', array(
'required' => false
))
->add('hatchling', 'checkbox', array(
'required' => false
))
->add('clutch', 'text', array(
'data' => 0,
'required' => false
))
->add('imageFile', 'file', array(
'required' => false
))
->add('user_id', 'hidden', array(
'data' => $user,
))
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Breedr\GeckoBundle\Entity\Gecko'
));
}
/**
* #return string
*/
public function getName()
{
return 'breedr_geckobundle_gecko';
}
}
I would really appreciate any help with this. I just can't understand how the data is used/sent. Thanks in advance :)
Andy
Firstly sorry if you know this, but you'll need correct relationships set up between your Gecko and User entities.
Note your #ORM annotation may be different from mine (or you could be using YAML or whatever). My use is:
use Doctrine\ORM\Mapping as ORM;
This should be in your Gecko entity
/**
* #ORM\ManyToOne(targetEntity="Your\NameSpace\Entity\User", inversedBy="geckos")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $user;
This should be in your User entity
/**
* #ORM\OneToMany(targetEntity="Your\NameSpace\Entity\Gecko",mappedBy="user")
*/
protected $geckos;
Note you'll need to generate getters & setters etc.
To save your new Gecko:
$gecko = new Gecko();
$gecko->setUser($this->getUser());
$form = $this->createForm(new GeckoType(), $gecko);
$entityManager = $this->getDoctrine()->getManager();
if ($request->isMethod('POST')) {
$form->submit($request);
if ($form->isValid()) {
$entityManager->persist($gecko);
$entityManager->flush();
// do something with success
} else {
// show errors by flash message or whatever
}
}
I'd suggest you read up on the symfony forms documentation & the databases & doctrine documentation as that has most of the information you need for getting started.
Example below works fine when I try to create a new car in database. If I leave brands select box blank in the webform, I get "The Brand field is required" error after submitting which is perfectly fine and as expected.
Problem:
If I repeat exactly same steps like described above when trying to update a selected record, I should still get "The Brand field is required" error after submitting, instead I'm getting "ContextErrorException: Catchable Fatal Error: Argument 1 passed to Car\BrandBundle\Entity\Cars::setBrands() must be an instance of Car\BrandBundle\Entity\Brands, null given, called in .... line on public function setBrands(\Car\BrandBundle\Entity\Brands $brands)"
Any reason why or any solution?
CAR UPDATE CONTROLLER (DOESN'T WORK)
private function getForm($car, $id)
{
return $this->createForm(new CarsType(), $car,
array('action' => $this->generateUrl('cars_independent_update_process',
array('id' => $id))));
}
public function processAction(Request $request, $id)
{
$repo = $this->getDoctrine()->getRepository('CarBrandBundle:Cars');
$car = $repo->findOneBy(array('id' => $id));
if (! $car)
{
return new Response('There is no such car in database');
}
$form = $this->getForm($car, $id);
$form->handleRequest($request);
if ($form->isValid() !== true)
{
return $this->render('CarBrandBundle:Independent:cars_update.html.twig',
array('page' => 'Cars Update Independent', 'form' => $form->createView()));
}
exit('FINE');
}
CAR CREATE CONTROLLER (WORKS FINE)
class CarsCreateController extends Controller
{
private function getForm()
{
return $this->createForm(new CarsType(), new Cars(),
array('action' => $this->generateUrl('cars_independent_create_process')));
}
public function processAction(Request $request)
{
$form = $this->getForm();
$form->handleRequest($request);
if ($form->isValid() !== true)
{
return $this->render('CarBrandBundle:Independent:cars_update.html.twig',
array('page' => 'Cars Update Independent', 'form' => $form->createView()));
}
exit('FINE');
}
ENTITY
class Cars
{
/**
* #ORM\ManyToOne(targetEntity="Brands", inversedBy="cars")
* #ORM\JoinColumn(name="brands_id", referencedColumnName="id", nullable=false)
* #Assert\NotBlank(message="The Brand field is required.")
*/
protected $brands;
/**
* #param \Car\BrandBundle\Entity\Brands $brands
*/
public function setBrands(\Car\BrandBundle\Entity\Brands $brands)
{
$this->brands = $brands;
return $this;
}
/**
* #return \Car\BrandBundle\Entity\Brands
*/
public function getBrands()
{
return $this->brands;
}
}
FORM TYPE
class CarsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->setAction($options['action'])
->setMethod('POST')
->add('brands', 'entity',
array(
'error_bubbling' => true,
'class' => 'CarBrandBundle:Brands',
'property' => 'name',
'multiple' => false,
'expanded' => false,
'empty_value' => '',
'query_builder' => function (EntityRepository $repo)
{
return $repo->createQueryBuilder('b')
->orderBy('b.name', 'ASC');
}
))
->add('model', 'text', array('label' => 'Model', 'error_bubbling' => true))
->add('year', 'date', array('label' => 'Year', 'error_bubbling' => true))
->add('button', 'submit', array('label' => 'Submit'))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array('data_class' => 'Car\BrandBundle\Entity\Cars'));
}
public function getName()
{
return 'cars';
}
}
In your update version you don't transmit the id when you generate your route for the form action. Will be something like that :
private function getForm($car)
{
return $this->createForm(new CarsType(), $car,
array('action' => $this->generateUrl('cars_independent_update_process', array('id' => $car->getId()))));
}
Problem was related to Constraint so I added it to the class and it work fine now.
/**
* Class Cars
*
* #ORM\Entity
* #ORM\HasLifecycleCallbacks
* #ORM\Table(name="cars", uniqueConstraints={#ORM\UniqueConstraint(columns={"model", "brands_id"})})
* #UniqueEntity(fields={"model","brands"}, message="The Model and the Brand combination already exists in database.")
*/
class Cars
{
/**
* #var object
* #ORM\ManyToOne(targetEntity="Brands", inversedBy="cars")
* #ORM\JoinColumn(name="brands_id", referencedColumnName="id", onDelete="CASCADE", nullable=false)
* #Assert\NotBlank(message="The Brand field is required.")
*/
protected $brands;