I'm trying to create a form with translated labels. I'm not using an AbstractType class, I just want to declare my form in a controller :
$form = $this->createFormBuilder($user)
->add('website', 'url', array(
'required' => false,
'label' => 'profession.website.label'
));
How can I add a translation domain to my form ?
I believe you pass it as an array to the 2rd argument for createFormBuilder
$form = $this->createFormBuilder($user, [
'translation_domain' => 'comment'
])->add('website', 'url', [
'required' => false,
'label' => 'profession.website.label'
]);
First argument is the data for the form, the second is the options.
http://api.symfony.com/2.0/Symfony/Bundle/FrameworkBundle/Controller/Controller.html#method_createFormBuilder
Related
I'm not sure what's going on. I'm using Zend Form 2 with a multiselect field. When I submit the code, the values exist in post. When I run the values through zend form 2, I get no validation errors but the multiselect field is suddenly empty.
class Form extends \Zend\Form\Form
{
// input filter to set up filters and validators
protected $myInputFilter;
public function __construct()
{
// create the zend form
parent::__construct();
// make it a bootstrap form
$this->setAttribute('class', 'form-horizontal');
$this->setAttribute('role', 'form');
// set the default objects we'll use to build the form validator
$this->myInputFilter = new \Zend\InputFilter\InputFilter();
}
}
class AddPublicationForm extends Form
{
public function __construct()
{
// create the zend form
parent::__construct();
$this->setAttribute('class', 'form-horizontal');
$this->setAttribute('id', 'add-publication-form');
$this->add([
'name' => 'author[]',
'attributes' => [
'class' => 'form-control',
'data-placeholder' => 'Author',
'multiple' => 'multiple',
'placeholder' => 'Author',
],
'required' => false,
'type' => \Zend\Form\Element\Select::class,
'options' => [
'value_options' => [
'check1' => 'check1',
'check2' => 'check2',
],
],
]);
$this->myInputFilter->add([
'filters' => [],
'name' => 'author[]',
'required' => false,
'validators' => [],
]);
// attach validators and filters
$this->setInputFilter($this->myInputFilter);
// prepare the form
$this->prepare();
}
}
These are the zend form objects that I am using. I am using Slim Framework 2 as my backend. Here is the controller object:
public function addAction()
{
$request = $this->app->request;
$form = new Form\AddPublicationForm();
if ($request->isPost()) {
$params = $request->params();
// DUMP 1: exit('<pre>'.print_r($params, true).'</pre>');
$form->setData($params);
if ($form->isValid()) {
$data = $form->getData();
// DUMP 2: exit('<pre>'.print_r($data, true).'</pre>');
}
}
}
DUMP 1:
Array
(
[author] => Array
(
[0] => check1
[1] => check2
)
}
DUMP 2:
Array
(
[author[]] =>
)
I realize that I could very easily just bypass the validation here because I'm not using any validators on that field. I'm more concerned with the underlying cause though.
Why is the validated author data empty?
When you specify multiple in attributes, Zend\Form and Zend\InputFilter add []after the name. You should not do it yourself otherwise, in the html code, the element appears under the name author[][] and the setData method don't match.
To see it, replace required by true and look at the html code of the form.
$this->add([
'name' => 'author',
'attributes' => [
'class' => 'form-control',
'data-placeholder' => 'Author',
'multiple' => 'multiple',
'placeholder' => 'Author',
],
'required' => false,
'type' => \Zend\Form\Element\Select::class,
'options' => [
'value_options' => [
'check1' => 'check1',
'check2' => 'check2',
],
],
]);
$this->myInputFilter->add([
'filters' => [],
'name' => 'author',
'required' => false,
'validators' => [],
]);
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 am trying to use Symfony Form Component with Silex framework at the moment. I added some fields in buildForm method of my form type class. Also user can click on a button and add unlimited textarea element using javascript on the frontend. Now on PRE_SUBMIT event, I do the following to add these fields to the form
$data = $event->getData();
$form = $event->getForm();
foreach ($data as $key => $value) {
if (stristr($key, '_tb_') !== false) {
$id = str_ireplace('_tb_', '', $key);
$form->add('_tb_' . $id, 'hidden');
$form->add('_title_' . $id, 'text', [
'required' => false,
'label' => 'Title',
'constraints' => [
new Length(['min' => 6]),
]
]);
$form->add('_img_url_' . $id, 'text', [
'required' => false,
'label' => 'Image Url',
'constraints' => [
new Url(),
]
]);
$form->add('_img_alt_' . $id, 'text', [
'required' => false,
'label' => 'Image Alt',
'constraints' => []
]);
$form->add('_content_' . $id, 'textarea', [
'required' => true,
'attr' => [
'data-role' => '_richeditor'
],
'constraints' => [
new Length(['min' => 100]),
]
]);
}
}
I can see these fields are added to the form and populated once the form is submitted for the first time but for some reason all the constraints are ignored only for these new added fields. Is there a way to force Form to honour the constraints for the newly added elements?
The form component and validation can be tricky. A easy misconception is that the form type option "required" will imply a NotBlank validation constraint. This is not the case, the docs explain that option to be "superficial and independent from validation" only concerned with form element rendering (HTML5 required attr, label, etc).
To make things trickier, that you are specifying a minimum length constraint, one might assume that no (or zero) length would be considered invalid. This is also not the case. The length validator is only concerned with non-null / non-empty values. :-/
So! Modifying the text area field to include NotBlank() should do the trick:
$form->add('_content_' . $id, 'textarea', [
'required' => true,
'attr' => [
'data-role' => '_richeditor'
],
'constraints' => [
new NotBlank(),
new Length(['min' => 100]),
]
]);
I have a form in my ZF2 app with a CAPTCHA element as follows :
$this->add(array(
'type' => 'Zend\Form\Element\Captcha',
'name' => 'captcha',
'attributes' => array(
'class'=>'form-control',
),
'options' => array(
'label' => 'Please verify you are human.',
'captcha' => array('class' => 'Dumb')
),
));
I have an input filter attached to the form that validates the other elements in the form (name, email, message). When this is attached to the form the validation for the CAPTCHA field is ignored when checking if valid.
if ($request->isPost()) {
// set the filter
$form->setInputFilter($form->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) { ...
If i remove the input filter then the CAPTCHA field is validated correctly but obviously the other fields have no validators. What silly mistake am I making? Is there a "CAPTCHA" validator I have to set in the input filter?
The issue is because, I assume that on your form you have created a method called:
getInputFilter();
which overrides the original getInputFilter(),
there are two solutions:
rename your function on your form to be getInputFilterCustom()
and then modify also:
if ($request->isPost()) {
// set the filter
$form->setInputFilter($form->getInputFilterCustom());
or inside your current getInputFilter() add the logic to validate the captcha.
This is my code to add a captcha image control in a ZF2 form :
$this->add(array(
'name' => 'captcha',
'type' => 'Captcha',
'attributes' => array(
'id' => 'captcha',
'autocomplete' => 'off',
'required' => 'required'
),
'options' => array(
'label' => 'Captcha :',
'captcha' => new \Zend\Captcha\Image(array(
'font' => 'public/fonts/arial.ttf',
'imgDir' => 'public/img/captcha',
'imgUrl' => 'img/captcha'
))
),
));
The others form elements are using validators from the input filter, but i didn't use any validators to make it work.
I hope this can help you.
It is because you don't call the parent getInputFilter() within yours. Simply do
public function getInputFilter()
{
parent::getInputFilter();
//... your filters here
}
I have a form in my Symfony2 application that is largely used for persisting an entity, but I have added one extra non-mapped field that is used for uploading a file that is then processed and deleted. However, I can't figure out how to validate this additional field.
Here it is defined in the buildForm() method of my form class:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', 'text', array('label' => 'Name'))
// ...
->add('data', 'file', array(
'label' => 'CSV Data File',
'mapped' => false,
'required' => false,
));
}
I initially tried adding the validation for this field to the bundle's validation.yml file like so, but as this field is not part of the entity, it threw up an error saying so.
My\Bundle\Entity\MyEntity:
properties:
data:
- File:
maxSize: 1024k
mimeTypes: text/*
mimeTypesMessage: Please upload a CSV file
My next attempt was to add the constraints within the form class itself, like so, but it appears you can only validate arrays this way, not objects, which I guess is because it's mainly tied to my entity.
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$collectionConstraint = new Collection(array(
'data' => new File(array(
'maxSize' => '1024k',
'mimeTypes' => 'text/*',
'mimeTypesMessage' => 'Please upload a CSV file',
)),
));
$resolver->setDefaults(array(
'data_class' => 'My\Bundle\Entity\MyEntity',
'constraints' => $collectionConstraint,
));
}
From the documentation, it looks like I can use $this->get('validator')->validateValue(); to validate the extra field on its own, but I'd quite like to validate the whole form at once and display any errors relating to the non-mapped field with the field itself.
Does anyone have any ideas?
You can simply pass property_path=null to data form field. Property path is used to determine related entity field, by setting its value to null you tell the form to not provide field's value to an entity.
// ...
->add('data', 'file', array(
'label' => 'CSV Data File',
'mapped' => false,
'required' => false,
'property_path' => null,
));
// ...
UPD:
To validate this field id prefer create embedded form and pass data field and validation constraints:
class dataType extends AbstractType
// ...
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('data', 'file', array(
'label' => 'CSV Data File',
'required' => false,
));
}
public function getDefaultOptions(array $options)
{
$collection = new Collection(array(
'data' => new NotBlank(),
// ...
));
return array(
'validation_constraint' => $collection,
);
}
//...
And edit entity form class:
->add('data', 'file', array(
'label' => 'CSV Data File',
'mapped' => false,
'required' => false,
));
replace with:
->add('custom', new DataType(), array(
'mapped' => false,
));