I created two entities User (that contains email, password, username) and Profile(avatar...)
in the UserType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('username')
->add('password', 'password')
->add('email', 'email')
;
}
and in the ProfileType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('avatar')
->add('city')
->add('country', 'country')
->add('firstName')
->add('lastName')
->add('address')
->add('mobile')
->add('phone')
->add('user', new UserType($this->get('security.context')->getToken()->getUser()))
;
}
Is there is a way to not display the password in the profile when the user want to edit his/her infos ?
PS: Is it a great way to separate the User entity from the Profile ?
You can achieve this via FormEvents. Something like this:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$user = $this->user;
$builder
->add('username')
->add('password', 'password')
->add('email', 'email');
$builder->addEventListener(FormEvents::POST_SET_DATA, function(FormEvent, $event) use ($user){
$data = $event->getData(); // NULL or an instance of User object
if ( $data && $data->getId() == $user->getId()){
$event->getForm()->remove('password');
}
});
}
If you want to read more about dynamic forms, you could kind a lot of information in official docs.
Related
Three entities exists; Topic, Meta and User.
Topic OneToMany Meta ManyToOne User
How can this be created using Symfony Forms?
Originally this was a ManyToMany relationship between Topic and User but this has been altered to allow additional information about the relationship to be stored in Meta.
Original form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('users')
;
}
Modified form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('users', EntityType::class, [
'multiple' => true,
'class' => 'FooBarBundle:User',
'choice_label' => 'username',
])
;
}
This renders a form with Title and a multi select for User. The problem is User doesn't map to Meta and so the User data won't be persisted. Is mapped=false and using the controller to attach the Meta entity to Thread the correct way to handle this relationship? Or is there a way to use a DataTransformer to convert the Users to Metas?
--- UPDATE ---
public function setUsers($users) {
foreach($users AS $user) {
$meta = new Meta();
$meta
->setUser($user)
->setThread($this);
$this->addMeta($meta);
}
return $this;
}
Or is using the call from within Form::handleRequest to Thread::setUsers the right place to convert a User to a Meta?
I have a form as below:
class AdminEmployerForm extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('firstName', 'text')
->add('user', new AdminUserForm());
}
}
class AdminUserForm extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('username', 'text')
->add('email', 'text');
}
}
I am calling AdminEmployerForm in controller and I want to remove email field of AdminUserForm from AdminEmployerForm:
$form = $this->createForm(new AdminEmployerForm, $employer);
//i want to do something like $form->remove('email')
how can i do use $form->remove() to remove field in embedded form? Is it possible to remove a field of embedded form from controller?
You'll have to get the embedded form type to remove a field from it.
$form = $this->createForm(new AdminEmployerForm, $employer);
// Get the embedded form...
$adminUserForm = $form->get('user');
// ... remove its email field.
$adminUserForm->remove('email');
Not sure of your exact use-case, but you may consider leveraging form events as it may be more ideal than handling this in the controller.
I'm trying to build a product page that will contain a form with a dynamic number of "options" (either select boxes or input fields) depending on the product. After reading the documentation, I can't see how to create a form entity that would work when building this form. I feel like I'm missing something obvious.
What you need to do is basically create form field of collection type, which will be your collection of select boxes, input fields, whatever.
Check documentation and read about embeding forms, it is described pretty well ther
Your parent form:
class ParentType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('id', 'hidden')
->add('name')
->add('yourCollection', 'collection', array(
'type' => new ChildType(),
'label' => 'Label for your child form',
));
}
}
Your child form:
class ChildType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('id', 'hidden')
->add('category', 'choice')
;
}
}
I have 2 Entities User and Member
The User has all of the normal stuff associated (username, password, email)
The Member has some other fields, including, First Name, Last Name, Age etc
I'm trying to create a new Member and to display a form with both the User fields and the Member fields.
I currently have the following:
User.php
$protected $username;
$protected $email;
/**
* #ORM\OneToMany(targetEntity="BM\UserBundle\Entity\Member", mappedBy="user")
*/
protected $member;
Member.php
/**
* #ORM\ManyToOne(targetEntity="BM\UserBundle\Entity\User", inversedBy="member")
*/
protected $user;
I have 2 form types as well:
MemberType.php
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('user', new UserType())
->add('firstname')
->add('lastname')
->add('age')
;
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'BM\UserBundle\Entity\User'
);
}
UserType.php
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('username')
->add('email')
->add('password')
;
}
public function getName()
{
return 'user';
}
When I refresh the page where the form is rendered, I get the following error:
Catchable Fatal Error: Argument 1 passed to BM\UserBundle\Entity\Member::setUser() must be an instance of BM\UserBundle\Entity\User, array given, called in /var/www/proj/vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php on line 345 and defined in /var/www/proj/src/BM/UserBundle/Entity/Member.php line 259
Line 259 is:
public function setUser(\BM\UserBundle\Entity\User $user = null)
Am I approaching this the right way?
EDIT:
MemberController.php
$member = new Member();
$form = $this->createForm(new MemberType(), $member);
if($request->isMethod('post')) {
$form->submit($request);
if ($form->isValid()) {
$em->persist($member);
$em->flush();
$request->getSession()->getFlashBag()->add('success', 'Member has been saved');
} else {
$request->getSession()->getFlashBag()->add('error', 'Could not save the member');
}
}
Try in this way
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('user', new UserType())
->add('firstname')
->add('lastname')
->add('age')
;
}
public function setDefaultOptions(array $options)
{
return array(
'data_class' => 'BM\UserBundle\Entity\Member'
);
}
# UserType.php #
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('username')
->add('email')
->add('password')
;
}
public function setDefaultOptions(array $options)
{
return array(
'data_class' => 'BM\UserBundle\Entity\User'
);
}
Take a look the documentation: http://symfony.com/doc/current/cookbook/form/form_collections.html
How could i change the label of a form field after a submit of them?
Example form
class TestType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('test', 'number')
->add($options['data']->getId() > 0 ? 'save' : 'add', 'submit')
;
}
public function finishView(FormView $view, FormInterface $form, array $options)
{
if($form->has('add'))
{
$form->remove('add');
$form->add('add', 'submit', array('label' => 'save'));
}
}
public function getName()
{
return '';
}
}
The form is completely generated with "{{ form(form) }}".
I only use the FormType.
There is a add button if the data['id'] is lower as 1. if the id is higher as 0 there is a save button.
After the first submit of a new form, the entity is saved and after finished page load i see the "add" field instead the "save" field.
If i reload the complete page manually, i see the save button...
You don't need the finishView method to achieve what you want. You're removing and re-adding the add button in there. This does not make any sense.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$buttonName = $options['data']->getId() > 0 ? 'save' : 'add';
$builder
->add( /* ... */)
->add($buttonName, 'submit', array('label' => $buttonName))
;
}