Symfony Add bootstrap form-control class - php

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' } ) }}

Related

Symfony 3 - Add style to FormType (Entity::class => choiceLabels)

I have a formType that contains an EntityType :: class.
This is a list of possible types of users to choose from in a form.
->add('typeUser',EntityType::class, array(
'required' => true,
'class'=>'Site\PagesBundle\Entity\TypeUser',
'choice_label'=>'typeUtilisateur',
'expanded'=>true,
'multiple'=>true,
'empty_data' => 'Veuillez sélectionner au moins 1 type',
));
I wish I could give a "style" to these choices. For example, I would like them to be some distance from the checkbox.
So, I have to add style (margin-left by example) to :
'choice_label'=>'typeUtilisateur',
Is it possible in FormType ?
Or I should make that on my twig file ? In this case, how can I do it ?
Thanks for your help !
EDIT:
->add('typeUser',EntityType::class, array(
'required' => true,
'class'=>'Site\PagesBundle\Entity\TypeUser',
'choice_label'=>('typeUtilisateur' => 'attr' => array( 'style' => 'margin-left:15px')) ,
'expanded'=>true,
'multiple'=>true,
'empty_data' => 'Veuillez sélectionner au moins 1 type',
));
There are a few ways you can style your form fields. See a few of them below:
Option 1: Add a class attribute to the field in the form builder
$builder
->add('example', EntityType::class, [
'class' => FooBar::class,
'attr' => [
'class' => 'my-example-class'
]
])
Option 2: Specify a class in the form template
{{ form_widget(form.fooBar, {'attr': {'class': 'form-control'}}) }}
You can be specific to the choices, see this link here which shows adding a class attribute to choices.
I think that the right way is to use the attr key with which you could set a custom class="" for your field
->add('typeUser',EntityType::class, array(
'attr' => [
'class' => 'YOUR_CHOICE_CLASS',
],
'required' => true,
'class'=>'Site\PagesBundle\Entity\TypeUser',
'expanded'=>true,
'multiple'=>true,
'empty_data' => 'Veuillez sélectionner au moins 1 type',
));
Then, can define the styles that you want in your CSS file

Symfony "This value should not be blank." while submitting form

I'm trying to submit a user form. But the form does not contain all database fields because I want to set the password later (when submitting form).
But now I'm getting the error that the field 'password' should not be blank. Removing the form validation is not working and adding them as HiddenType is also not working.
I'm getting this error after the $form->isValid() check
EDIT:
FormBuilder
$form = $this->createFormBuilder($user)
->add('email', TextType::class, array(
'label' => 'Email adres',
'attr' => array(
'class' => 'input-field'
)
))
->add('first_name', TextType::class, array(
'attr' => array(
'label' => 'Voornaam',
'class' => 'input-field'
)
))
->add('middle_name', TextType::class, array(
'label' => 'Tussenvoegsel (optioneel)',
'required' => false,
'attr' => array(
'class' => 'input-field'
)
))
->add('last_name', TextType::class, array(
'label' => 'Achternaam',
'attr' => array(
'class' => 'input-field'
)
))
->add('date_of_birth', DateType::class, array(
'label' => 'Geboortedatum',
'attr' => array(
'class' => 'input-field'
)
))
->add('save', SubmitType::class, array(
'label' => 'Gebruiker Opslaan',
'attr' => array(
'class' => 'form-submit-btn'
)
))
->getForm();
Submitting the form:
$form->handleRequest($request);
if($form->isSubmitted()){
if($form->isValid()){
dump($user);
exit;
}
}
EDIT:
Doing $user->setPassword('123'); before validation is not working
Can you post your User Entity?
You may get the Error because an argument is not allowed to be blank.
Take a look at any #Assert\NotBlank or nullable = false Annotations.
Can you show your User class? May be implements UserInterface? So, there is this validation.

Symfony 4 Remove a default set constraint (notBlank) on a RepeatedType Password field

I have form builder in a controller
$form = $this->createFormBuilder($user)
->add('firstname',TextType::class,array(
'label' => 'First name',
'attr' => array(
'class' => 'form-control',
'value' => $user->getFirstname()
),
))
->add('surname',TextType::class,array(
'label' => 'Last name',
'attr' => array(
'class' => 'form-control',
'value' => $user->getSurname()
)
))
->add('email', EmailType::class, array(
'label' => 'Email',
'attr' => array(
'class' => 'form-control',
'value' => $user->getEmail(),
),
))
->add('plainPassword', RepeatedType::class, array(
'type' => PasswordType::class,
'invalid_message' => 'The password fields must match.',
'options' => array('attr' => array('class' =>
'password-field')),
'first_options' => array('label' => 'Password'),
'second_options' => array('label' => 'Repeat
Password'),
))
As you can see on the plainPassword field there is no constraints set. My intention was to have the user not need to fill this field if they do not want to, however when I submit the form, the NotBlank constraint gets triggered and the form doesn't get submitted. I tried setting/adding, required to FALSE, doesn't work.
I even tried adding a new Blank() constraint and still it kept holding to the default constraint.
Is there a way to remove this default notBlankconstraint ??
Screengrab of the constraint kicking in
Thanks to #AythaNzt's comment. So the Constraint asserted an an annotation on my 'user Entity' class
It was this
/**
* #Assert\NotBlank()
* #Assert\Length(max=4096)
*/
private $plainPassword;
Removed the NotBlank()
So became
/**
* #Assert\Length(max=4096)
*/
private $plainPassword;

Symfony 3 - Best practice for concating form-blocks

I'm trying to learn how to build forms in symfony 3.
Following some tutorials I have built a PersonType
class PersonType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('gender', ChoiceType::class, array('label' => 'Anrede', 'choices' => array('Herr' => 'Herr', 'Frau' => 'Frau'), 'attr' => array('class' => 'form-control')))
->add('title', TextType::class, array('label' => 'Titel', 'attr' => array('class' => 'form-control')))
->add('firstname', TextType::class, array('label' => 'Vorname', 'attr' => array('class' => 'form-control')))
->add('lastname', TextType::class, array('label' => 'Nachname', 'attr' => array('class' => 'form-control')))
->add('birthdate', DateType::class, array('label' => 'Geburtsdatum', 'attr' => array('class' => 'form-control')))
->add('street', TextType::class, array('label' => 'Straße', 'attr' => array('class' => 'form-control')))
->add('streetnumber', TextType::class, array('label' => 'Hausnummer', 'attr' => array('class' => 'form-control')))
->add('zip', TextType::class, array('label' => 'PLZ', 'attr' => array('class' => 'form-control')))
->add('city', TextType::class, array('label' => 'Stadt', 'attr' => array('class' => 'form-control')))
->add('email', TextType::class, array('label' => 'E-Mail', 'attr' => array('class' => 'form-control')));
}
public function getName() {
return 'person';
}
}
And some other types.
In the controller I have
$person = new Person();
$form = $this->createForm(PersonType::class, $person);
My question now is, how do I now concat the PersonType to some other Types to get one Form out of it? And how do I then set the submit-button?
You cannot concatenate but you can include a subset of fields in several forms.
Here you have a nice example in the Symfony documentation :
http://symfony.com/doc/current/cookbook/form/inherit_data_option.html
Recap :
Create a form with your subfields, with the option 'inherit_data' => true.
Use it in another form as field.
First of all, please note how you add fields to PersonType form, because it will be exactly the same.
->add('email', TextType::class, array('label' => 'E-Mail', 'attr' => array('class' => 'form-control')));
What you do here is adding a subform TextType. It actually contains single field, but it's still a form.
The same way you can add PersonType to any other form. That would be something like:
->add('person', PersonType::class, array(/* some options if needed*/);
And how do I then set the submit-button?
As mentioned in Best Practices for Symfony Forms, I would suggest to add them in template, not to the form object.

How to add a <hr> in Symfony2 form builder?

I am building a form using the formbuilder, where I need to add <hr/> after certain fields. How can I do that? FYI, Need to add <hr/> after the field priority and another before biography. My form builder:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', 'text',
array(
'label' => 'Name English',
))
->add('bangla_name','text',
array(
'label' => 'Name Bangla',
'required' => false
))
->add('real_name','text',
array(
'required' => false
))
->add('debut', 'text',array(
'label' => 'Debut Film',
'required' => false))
->add('birth_place','text',array(
'label'=> 'Birth Place',
'required' => false
))
->add('sex', 'choice', array(
'choices' => array('M' => 'Male', 'F' => 'Female', 'N/A' => 'N/A'),
'row_attr' => array(
'class' => 'col-sm-6 n-p-l'),
'label'=> 'Sex',
'label_attr' => array(
'class' => 'col-md-4'
),
))
->add('priority','choice', array('required' => true, 'label'=> 'Priority','attr'=> array('class'=>'col-md-2'), 'choices' => array(
'0' => '0',
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4'
), 'row_attr' => array(
'class' => 'col-sm-4'
),
'label_attr' => array(
'class' => 'col-md-6'
),
))
->add('bday','choice',
array(
'required' => true, 'choices' => $this->buildDayChoices(),'label'=> 'Birth Day',
'row_attr' => array(
'class' => 'col-sm-4 n-p-l'),
'help' => '*required',
'label_attr' => array(
'class' => 'col-md-6'
)
))
->add('bmonth','choice',
array(
'required' => true, 'choices' => $this->buildMonthChoices(),'label'=> 'Birth Month',
'row_attr' => array(
'class' => 'col-sm-4 n-p-l'),
'help' => '*required',
'label_attr' => array(
'class' => 'col-md-6'
),
))
->add('byear','choice',
array(
'required' => true, 'choices' => $this->buildYearChoices(),'label'=> 'Birth Year',
'row_attr' => array(
'class' => 'col-sm-4 n-p-l'),
'help' => '*required',
'label_attr' => array(
'class' => 'col-md-6'
),
))
->add('dod_day','choice',
array(
'required' => true, 'choices' => $this->buildDayChoices(),'label'=> 'Death Day',
'row_attr' => array(
'class' => 'col-sm-4 n-p-l'),
'help' => '*required',
'label_attr' => array(
'class' => 'col-md-6'
),
))
->add('dod_month','choice',
array(
'required' => true, 'choices' => $this->buildDayChoices(),'label'=> 'Death Month',
'row_attr' => array(
'class' => 'col-sm-4 n-p-l'),
'help' => '*required',
'label_attr' => array(
'class' => 'col-md-6'
),
))
->add('dod_year','choice',
array(
'required' => true, 'choices' => $this->buildDayChoices(),'label'=> 'Death Year',
'row_attr' => array(
'class' => 'col-sm-4 n-p-l'),
'help' => '*required',
'label_attr' => array(
'class' => 'col-md-6'
),
))
// ->add('birth','birthday', array('label' => 'Date of Birth', 'years' => range(1950, date('Y')-10)))
->add('bio_english','textarea',array(
'label'=> 'Biography - English',
))
->add('bio_bangla','textarea',array(
'label'=> 'Biography - Bangla',
))
->add('graphics', 'graphics', array(
'upload_directory' => 'uploads' . DIRECTORY_SEPARATOR . 'artist','row_attr' => array(
'class' => 'col-sm-12')
))
;
}
I don't think you can. A horizontal rule is not a form construct, and as such, has no business being defined by a FormBuilder.
This needs to be handled in the view/template
{{ form_row(form.priority) }}
<hr/>
{{ form_row(form.bday) }}
IMO, you've been a bit too liberal with your use of the HTML properties in your builder. Those should be used only if you really need them. Again, they are primarily view concerns.
EDIT
You can add this customization in the form's view, and override the form_row block to be aware of this customization
src/AppBundle/Form/YourFormType.php
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
class YourFormType extends AbstractType
{
/* ... Rest of form type ... */
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view['priority']->use_separator = true;
parent::buildView($view, $form, $options);
}
}
Then the form block
{% block form_row %}
{{ parent() }}
{% if form.use_separator is defined %}
<hr/>
{% endif %}
{% endblock %}
All right, as I said in comments, one way would be to override specific field of your form. If you are interested in the subject, you can read more here.
For the purpose of demonstrating, I've created simple form with 3 fields, as follows:
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('username', 'text');
$builder->add('email', 'email');
$builder->add('password', 'password');
}
Now, the important part here is the name of the form (it's used later when overriding)
public function getName() {
return 'myform';
}
Nothing new here, most of the magic happens in your template file.
{% form_theme form _self %}
The following line tells Symfony that you are using the same template file as a base to create a form theme. Next:
{% block _myform_email_row %}
{{ block('form_row') }}
<hr/>
{% endblock %}
This block is all you need to define at the top of your template, after {% form_theme ... %}
{% block _myform_email_row %}
_myform is the name of your form obviously.
_email is the name of the input you want to override
_row is what part of it you want to override. row stands for label, widget and block. _widget would override only the part that renders the input.
And that's all you need. Define custom block, render the default block and add <hr/> at the end of it. You can override any template part like that.
Edit - response to a comment
but can't exactly use it because I can't use {% form_theme form _self %}
You can delete the whole {% form_theme %} line and move your custom {% block _myform_... %} to separate template. Then open your config.yml, look for the section twig and include the template as a resource, like this:
twig:
debug: "%kernel.debug%"
strict_variables: "%kernel.debug%"
form:
resources:
- theme/custom.html.twig
Here my template is located in app/Resources/views/theme
This will include your template in every form you have. But since you override specific field of specific form, it should not interact with other forms. This way would save you the trouble of using {% form_theme %} block.

Categories