I'm trying to figure out how to set the class (or any attribute really) on a Symfony2 form created via FormBuilder. I am aware that you can do this via the template for the form itself, but I would still like to know how to do it via $this->createFormBuilder() in the controller.
My code is below. I've tried the setAttribute() method as you can see in my code, but it has no effect. I initially thought I messed up as I overwrote the default twig form_div_layout.html.twig file, but this was not the case.
private function createResolvedForm($id) {
return $this->createFormBuilder()
->setAction($this->generateUrl('system_announcement_resolve', array('id' => $id)))
->setMethod('PUT')
->setAttribute('class', 'resolved-form exempt-from-default-ajax')
->add('submit', 'submit', array(
'label' => 'Mark As Resolved',
'attr' => array(
'class' => 'btn btn-success btn-xs',
'data-toggle' => 'tooltip',
'data-placement' => 'top',
'title' => 'Resolve Issue #' . $id,
)
))
->getForm();
}
To be clear, I'm not having an issue setting the class on the submit button I'm passing in, but rather the actual form itself.
Thanks for any help!
The createFormBuilder method has two input parameters
public FormBuilder createFormBuilder(mixed $data = null, array $options = array())
So in your example you could use the second parameter to set the class on the whole form
private function createResolvedForm($id) {
return $this->createFormBuilder(null, array('attr' => array('class' => 'resolved-form exempt-from-default-ajax')))
->setAction($this->generateUrl('system_announcement_resolve', array('id' => $id)))
->setMethod('PUT')
->setAttribute('class', 'resolved-form exempt-from-default-ajax')
->add('submit', 'submit', array(
'label' => 'Mark As Resolved',
'attr' => array(
'class' => 'btn btn-success btn-xs',
'data-toggle' => 'tooltip',
'data-placement' => 'top',
'title' => 'Resolve Issue #' . $id,
)
))
->getForm();
}
Related
I'm using symfony 2.8, I have created one registration form, I want to add bootstrap form-control class to both password and repeat password form fields.
$builder
->add('name', TextType::class,array(
'attr' => array(
'class' => 'form-control'
)
))
-> add('plainPassword', RepeatedType::class, array(
'type' => PasswordType::class,
'first_options' => array('label' => 'Password'),
'second_options' => array('label' => 'Repeat Password'),
'attr' => array('class' => 'form-control')
));
Incase of 'name' field its working BUT for password fields the class is not adding.
How can I add 'form-control' class for password fields.
Any help is much appreciated.
Thanks.
There are two ways of doing this. The first is to use options, which will pass the options down to each of the underlying fields:
->add('plainPassword', RepeatedType::class, array(
'type' => PasswordType::class,
'first_options' => array('label' => 'Password'),
'second_options' => array('label' => 'Repeat Password'),
'options' => array('attr' => array('class' => 'form-control'))
));
You can also add the class in the first_options and second_options field, like so. This would be useful if you had options that were specific to each field or you wanted to override something from the main options.
->add('plainPassword', RepeatedType::class, array(
'type' => PasswordType::class,
'first_options' => array(
'label' => 'Password',
'attr' => array('class' => 'form-control')
),
'second_options' => array(
'label' => 'Password',
'attr' => array('class' => 'form-control-override')
),
'attr' => array('class' => 'form-control')
));
Also, as of Symfony 2.6 it has has built-in Bootstrap form theme support to where you shouldn't have to be adding these classes to all of your fields manually.
Some guys from the Symfony development team, suggest that you should use the boostrap's classes directly in html (here, if you want to see the suggestion). And the suggestion makes perfect sens to me, as Symfony is for backend development, and not frontend. So the ideal way of solving this is to create your two fields in the Type class, and when rendering the form, add something like:
{{ form_row(name, { attr: { 'class': 'form-control' } ) }}
{{ form_row(password, { attr: { 'class': 'form-control' } ) }}
{{ form_row(plainPassword, { attr: { 'class': 'form-control' } ) }}
I have a form that has to contain a choice field which displays its content from another entity (not the entity used in the form), so this is how I tried to create it:
$user = new user();
$profils=$rep->findAll();
$form2 = $this->createFormBuilder($user,array('csrf_protection' => false))
->add('id', 'text',array('attr'=>array("autocomplete" => "off",'name'=>'login_user','required'=>'required',
'maxlength'=>'255','placeholder'=>'Matricule')))
->add('password', 'password',array('attr'=>array('autocomplete' => 'off','placeholder'=>'Mot de passe','required'=>'required')))
->add('profils', 'choice',[
'choices' => [$profils]],array('attr'=>array('mapped'=>false,'required'=>'required')))
->add('Ajouter', 'submit', array('attr' => array('class' => 'btn btn-primary btn-block rounded_btn', 'id' => 'login_btn',
'style' => "width:6vw;height:5vh;padding:0px 0px; position:relative;left:5vmin;top:1vmin;font-size:2vmin;")))
->getForm();
Pleaaaase help me, as I'm new with symfony, I may be stuck in problems you may consider stupid, I'm sorry but i couldn't find a solution myself.
I fixed it by changing the place of "'mapped'=>false" and it worked:
$form2 = $this->createFormBuilder($user,array('csrf_protection' => false))
->add('id', 'text',array('attr'=>array("autocomplete" => "off",'name'=>'login_user','required'=>'required',
'maxlength'=>'255','placeholder'=>'Matricule')))
->add('password', 'password',array('attr'=>array('autocomplete' => 'off','placeholder'=>'Mot de passe','required'=>'required')))
->add('profils', 'choice'
,array( 'choices' => array('Profils' => $profArr),'mapped'=>false),
array('attr'=>array('required'=>'required')))
->add('Ajouter', 'submit', array('attr' => array('class' => 'btn btn-primary btn-block rounded_btn', 'id' => 'login_btn',
'style' => "width:6vw;height:5vh;padding:0px 0px; position:relative;left:5vmin;top:1vmin;font-size:2vmin;")))
->getForm();
One way of doing it is this :
In the repository of profil entity create a method eg that return an array of profils e.g
class ProfilRepository extends EntityRepository
{
public function myFindAll()
{
$queryBuilder = $this->createQueryBuilder('p');
$entites = $queryBuilder->getQuery()->getArrayResult();
return $entites;
}
}
In the controller as you are doing now,
$user = new user();
// I'm asuming that Profil is an entity
$profils = $this
->getDoctrine()
->getManager()
// this should return an array
->getRepository('SdzBlogBundle:Profil')->myFindAll()
;
$form2 = $this->createFormBuilder($user, array('csrf_protection' => false))
->add('id', 'text', array(
'attr' => array(
'autocomplete' => 'off',
'name' => 'login_user',
'required' => 'required',
'maxlength' => '255',
'placeholder' => 'Matricule'
)
))
->add('password', 'password', array(
'attr' => array(
'autocomplete' => 'off',
'placeholder' => 'Mot de passe',
'required' => 'required'
)
))
->add('profils', 'choice', array(
'choices' => $profils,
array(
'attr' => array(
'mapped' => false,
'required' => 'required'
)
)
))
->add('Ajouter', 'submit', array(
'attr' => array(
'class' => 'btn btn-primary btn-block rounded_btn',
'id' => 'login_btn',
'style' => "width:6vw;height:5vh;padding:0px 0px; position:relative;left:5vmin;top:1vmin;font-size:2vmin;"
)
))
->getForm()
;
That's all for now, Good luck.
I have the following form:
$form = $this->createFormBuilder()
->setMethod('POST')
->add('users', EntityType::class, array(
'class' => 'AppBundle:User',
'choices' => $users,
'expanded' => true,
'multiple' => false,
'choice_label' => function ($user) {
return $user->getUsername();
}
))
->add('selected', SubmitType::class, array('label' => 'select'))
->getForm();
return $this->render('default/showUsers.html.twig', array('form' => $form->createView()));
I have 2 Problems with that:
I can not customize the 'choice_label' like:
'choice_label' => function ($user) {
return ($user->getId() + " " + $user->getUsername());
}
There is not Linebreak after each choice (or after each Radio button), which gets pretty ugly with the alot of users.
How can I customize the 'choice_label's ?
How can I get a Linebreak after each Radio button ?
You can customise this to string method however you want and then remove the 'choice_label' attribute in form builder
//in user entity
public function __toString()
{
$string =$this->getId(). ' ' . $this->getUsername();
return $string;
}
To customise labels you, I would use style sheets. You can add a class using attr or choice_attr for individual radio inputs based on their values .. For example
->add('users', EntityType::class, array(
'class' => 'AppBundle:User',
'choices' => $users,
'attr' => array('class' =>'type_label'),
'choice_attr' => array(
'0' => array('class' => 'class_one'),
'1' => array('class' => 'class_two'),
),
'expanded' => true,
'multiple' => false,
))
See symfony reference for more information
I am a totally new in symfony2. I met a situation which I can't solve till now.
I have a controller, formtype and eventsubscriber in my project. The form builds by binding the entities. In that case for a particular entity I need to add a default value along with an ID in one of the form fields. My form type is
$builder->add('breed', EntityType::class, array(
'label' => 'Breed',
'class' => 'AppBundle:Masters\Breed',
'placeholder' => '----Select Breed----',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('b')
->orderBy('b.sortOrder', 'DESC');
},
'choice_label' => 'breed',
));
$builder->addEventSubscriber(new BreedSubscriber($factory));
My Event Subscriber is
private function addBreed($form, $breedmasterId) {
$form->add($this->factory->createNamed('breed',EntityType::class,null, array(
'class' => 'AppBundle:Masters\Breed',
'placeholder' => '----Select Breed--------',
'choice_label' => 'breed',
'required' => TRUE,
'mapped' => false,
'query_builder' => function (EntityRepository $repository) use ($breedmasterId) {
$qb = $repository->createQueryBuilder('bm')
->where('bm.breed = :breedmasterId')
->setParameter('breedmasterId', $breedmasterId);
return $qb;
},
'auto_initialize' => false
)));
}
I need to add a default value such as "General" along with an "id" in the addBreed subscriber and it need to be validate on formsubmission. Thanks in advance for the help.
You can add the following 'data' key in the array you configure your form:
$builder->add('breed',null, array(
'label' => 'Breed',
'data' => 'Sih Tzu'
))
I`ve got a dropdown list in my Symfony2 form like this:
$builder->add('categories','entity', array(
'class' => 'MyBundle:Myentity',
'property' => 'name',
'label' => 'Mylabel',
'expanded' => false,
'multiple' => false,
'label_attr' => array ( 'class' => 'control-label' ),
'attr' => array ( 'class' => 'form-control',
'placeholder' => 'Placeholder',
'title' => "Mytitle",
'data-toggle' => 'tooltip',
'data-myidfromDB' => '????',
'data-mynamefromDB'=>'????' etc. )));
So I am getting a list of MyBundle:Myentity objects and when I choose one I want to show all its properties (like ID, name, etc.) which are stored in my DB and described in Entity class, in different html data-* fields. If I select another one from the list I want to see all information related to my newly selected option in HTML (to change dynamically). Any ideas how to do that?
Since Symfony 2.7 you can set the option choice_attr to ChoiceType and set it a callable receiving the choice as an argument.
EntityType inherits this option and the choice in that case is the instantiated entity, so you can write something like :
$builder->add('categories','entity', array(
'class' => 'MyBundle:MyEntity',
'property' => 'name',
'label' => 'Mylabel',
'attr' => array('class' => 'form-control'),
'label_attr' => array('class' => 'control-label'),
'choice_attr' => function (\AppBundle\Entity\MyEntity $myEntity) {
return array(
'data-private-property' => $entity->getPrivateProperty(),
'data-some-value' => $entity->someMethod(),
);
},
);
You can't do that in easy way.
But you can put more information in select label.
Look on
http://symfony.com/doc/current/reference/forms/types/entity.html#choice-label
Yout can put here more field details and get it from your javascript.