I just update Symfony2 from 2.4 to 2.7. Besides a lot of deprecated calls, I have found one weird problem.
I have a "select" tag within a form and I get the options from database. In database are stored the translation keys, and always has worked fine, symfony showed the correct language in the form. But not now.
Some code and screenshots:
Form:
->add('category', 'entity', array(
'empty_value' => 'Event.form.label.category_empty',
'class' => 'EventBundle:Category',
'choice_label' => 'name',
'error_bubbling' => true,
'constraints' => array(
new NotBlank(array('message' => 'Event.form.error.category.notblank'))
)
))
->add('subcategory', 'entity', array(
'class' => 'EventBundle:Subcategory',
'choice_label' => 'name',
'error_bubbling' => true,
'constraints' => array(
new NotBlank(array('message' => 'Event.form.error.subcategory.notblank'))
)
))
Template:
<div class="form-group col-sm-6 input-group">
<label for="event_category" class="input-group-addon">{{ 'Event.form.label.category' | trans }}</label>
{{ form_widget(form.category, { 'attr': { 'data-ott-subcaturl' : path('get_subcategories') , 'class' : 'form-control ev-category'} }) }}
</div>
<div class="form-group col-sm-6 input-group">
<label for="event_subcategory" class="input-group-addon">{{ 'Event.form.label.subcategory' | trans }}</label>
{{ form_widget(form.subcategory, { 'attr': { 'class' : 'form-control ev-subcategory'} }) }}
</div>
Form result with Symfony2.4:
Form result with Symfony2.7:
As you see, the empty_value key is translated in both cases. And the option values keys does not appear in debugger, as if there were. I think is because translations load before doctrine, but I don't know how fix it.
Thanks.
I found the solution:
In 2.7 was introduced the choice_translation_domain to avoid translating options.
http://symfony.com/blog/new-in-symfony-2-7-form-and-validator-updates#added-choice-translation-domain-domain-to-avoid-translating-options for more details
->add('category', 'entity', array(
'choice_translation_domain' => true,
));
Related
I have an issue with the constrains-check of my form and the correct display of errors.
describtion of problem
The form has three checkboxes and two of them are mandatory to be checked by the user (accepting Terms and Conditions stuff).
if only one of the mandatory checkboxes (either the first or the secound) is not checked, the error is displayed correctly
if both mandatory checkboxes are not checked, no error is displayed at all
analysis already done
looping through errors link show that there is really no error
if i add an additional textfield to the form, the above problem disappears (but I don't want that field).
BookingTermsAndConditionsFormType.php
class BookingTermsAndConditionsFormType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('checkbox1', CheckboxType::class, [
'label' => 'accept Terms and Conditions.*',
'label_html' => true,
'label_attr' => ['class' => 'switch-custom'],
'constraints' => [
new IsTrue([
'message' => 'Accepting Terms and Conditions are mandatory.',
]),
],
])
->add('checkbox2', CheckboxType::class, [
'label' => 'accept privacy policy*',
'label_html' => true,
'label_attr' => ['class' => 'switch-custom'],
'constraints' => [
new IsTrue([
'message' => 'Accepting privacy policy is mandatory.',
]),
],
])
->add('checkbox3', CheckboxType::class, [
'label' => 'I want the newsletter.',
'label_html' => true,
'label_attr' => ['class' => 'switch-custom'],
]);
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults([]);
}
}
_formTermsAndConditions.html.twig
{{ form_start(bookingTermsAndConditionsForm, {
attr: {
class: 'form-general',
novalidate: 'novalidate',
id: 'form_booking_terms_and_conditions'
}
}) }}
<div class="row">
<div class="col-10 offset-2">
<div>
{{ form_row(bookingTermsAndConditionsForm.checkbox1) }}
{{ form_row(bookingTermsAndConditionsForm.checkbox2) }}
{{ form_row(bookingTermsAndConditionsForm.checkbox3) }}
</div>
</div>
</div>
{{ form_end(bookingTermsAndConditionsForm) }}
Question
What is wrong here?
Please find here my workaround.
I have added an additional field and used the HiddenType for it. This made the form-errors work correctly. Don't ask me why...
BookingTermsAndConditionsFormType.php
[...]
$builder
->add('dummy', HiddenType::class, [
'label' => 'i am stupid and only needed because constrain-errors are not
displayed correctly without me (e.g. in the case both mandatory
checkboxes are not checked).'
])
[...]
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' } ) }}
Issue: Multiple dropdown just hands over a string not an array.
I tried to use a multiple dropdown in the formbuilder:
->add('options', 'choice', array(
'choices' => $printerOptionsDropdown,
'empty_value' => 'Optionen wählen',
'label' => 'Optionen',
'attr' => array(
'class' => 'form-control selectpicker',
'data-live-search' => true,
'multiple' => true),
'required' => false
))
With this twig template:
<form action="{{ path('<form>_create', { 'id' : entity.id }) }}" name="<formForm>" id="<formForm>" method="POST" class="form-horizontal" role="form" >
<div class="form-group">
<label for="<formbuildertag>_options" class="col-sm-2 control-label">{{ form_label(form.options) }}</label>
<div class="col-sm-4">
{{ form_widget(form.options) }}{{ form_errors(form.options) }}
</div>
</div>
And everything looks fine. I can select multiple options.
But when I submit the form it only hands over a string not an array.
<formbuildertag>[options]:"Value1"
<formbuildertag>[options]:"Value2"
The output of the post request is just a string of Value2. It gets overwritten because it's not an array. I got that. But why does the formbuilder not even create an array for the form.
I already tried to overwrite the full_name
form_widget(form.options, `enter code here`'full_name' => '<formbuldertag>[options][]')
but it didn't work.
Any ideas?
You must have multiple option defined as true. You have it in attr. change it as below :
->add('options', 'choice', array(
'choices' => $printerOptionsDropdown,
'empty_value' => 'Optionen wählen',
'label' => 'Optionen',
'attr' => array(
'class' => 'form-control selectpicker',
'data-live-search' => true,
'required' => false,
'multiple' => true
))
Hope this helps!
I'm using a collectionType that render a multiple select inputs, I want to add the select2 css class to my form but it just doesn't works.
This is the Form that has the collection.
->add('arrayDiagnosticos', 'collection', [
'type' => 'entity',
'label' => 'Diagnósticos dinámicos',
'allow_add' => true,
'allow_delete' => true,
'attr' => [
'class' => 'select2',
],
'options' => [
'empty_value' => 'Seleccionar Diagnóstico',
'class' => 'AppBundle:Diagnostico',
'required' => true,
'label' => 'Buscador de Diagnósticos',
'attr' => [
'class' => 'select2',
],
],
])
The twig is
<ul class="tags" data-prototype="{{ form_widget(form.arrayDiagnosticos.vars.prototype)|e }}">
{# iterate over each existing tag and render its only field: name #}
{% for diagnostico in form.arrayDiagnosticos %}
<li>
{{ form_row(diagnostico.nombreDiagnostico) }}
</li>
{% endfor %}
</ul>
It should render a select input like this:
1
But it renders like a regular select input
2
This is the output html
<div class="form-group"><label class="control-label required">Diagnósticos dinámicos</label>
<div id="paciente_form_arrayDiagnosticos" class="select2" data-prototype="<div class="row"><div class="col-xs-9"><select id="paciente_form_arrayDiagnosticos___name__" name="paciente_form[arrayDiagnosticos][__name__]" required="required" class="select2 form-control"><option value="" selected="selected">Seleccionar Diagnóstico</option> <option value="1" >se siente mal</option> <option value="2" >asfd</option> <option value="3" >YOLO</option></select></div><div class="col-xs-3"><a href="#" class="btn btn-danger btn-sm" data-removefield="collection" data-field="__id__">Eliminar Diagnóstico</a></div></div>" data-prototype-name="__name__"><ul class="bc-collection list-unstyled"></ul>Agregar Diagnóstico</div></div>
I also tried to do it via jQuery and no luck
<script>
$(function(){
$('#paciente_form_arrayDiagnosticos').addClass('select2')});
</script>
How do I properly attach the select2 css class?
Try this:
->add('arrayDiagnosticos', 'collection', [
'type' => new PreDiagnosticoType(),
'label' => ' ',
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'by_reference' => false,
'attr' => array(
'class' => 'select2',
),
])
Since your <selects /> are created dinamically, you have to set up a listener to apply the select2 function when each select element is created.
Somthing like this might work:
$('body').on('DOMNodeInserted', '.select2', function() {
$(this).select2();
});
I'm developping a website for a small business and I'm facing an unknown problem ...
In the admin panel, I can manage my menus, contents etc...
For menus management, I succeeded
$form = $this->createFormBuilder($menu)
->add('nom', 'text', array(
"attr" => array(
'placeholder' => "Nom du menu",
'class' => 'input-small'
)
))
->add('ordre', 'integer', array(
"attr" => array(
'placeholder' => "Ordre",
"class" => 'input-small'
)
))
->add('parent', 'choice', array(
'placeholder' => '-',
'choices' => $parents,
'required' => false
))
->add('save', 'submit', array(
'label'=>'Ajouter',
'attr' => array(
'class' => 'btn'
)
))
->getForm();
I handle it correctly and it works. But now, I try it with another content to manage :
$blocInfoNew = new AccueilModif();
$formNewInfo = $this->createFormBuilder($blocInfoNew)
->add('titreBloc', 'text')
->add('save', 'submit', array(
"label" => "Save"
))
->getForm();
[...]
return $this->render("[...]:page_accueil.html.twig", array(
'page' => "Administration - Modifier la page d'accueil",
[...]
'formNewInfo' => $formNewInfo->createView()
));
With a simple HTML form to test :
<div class="modal hide fade" id="blocAddInfo">
{{ form_start(formNewInfo) }}
<p class="f_legend">Ajouter une info</p>
{{ form_widget(formNewInfo.titreBloc) }}
{{ form_widget(formNewInfo.save) }}
{{ form_end(formNewInfo) }}
</div>
All works fine, until I send the form to the controller...
The identifier id is missing for a query of [...]\AdminBundle\Entity\AccueilModif
500 Internal Server Error - ORMException
I searched all the internet without finding a solution >< Can someone help me please ?
Usually, this happens when you misuse the find function.
->find($id)
It always has to contain a valid id, if you give it null it will throw the exception The identifier id is missing for a query...
I don't see it in your provided code but it looks like it is in:
$formNewInfo->createView()