How add a class to a label element with Symfony forms? - symfony-forms

I have a FormBuilderwith Symfony3 and I need you to add a class to the discount label.
How can you observe the third parameter of the add method is an array and a key is attr which has another array with the attributes of the input element, but not the label.
How can I add class to the label?
$builder
->add('note', TextareaType::class, array(
'label' => "Notes",
'required' => false
))
->add('discount', NumberType::class, array(
'required' => false,
'attr' => array(
'class' => "hidden"
)
))

You can see the label_attr parameter in symfony docs
'label'=>"Notes,array('label_attr' => array('class' => 'class_name'))"

This is what worked for me in Symfony 5.4 : 'label_attr' => ['class' => 'your-label-classes']
Example:
class YourFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('email', EmailType::class, [
'label'=>'Your label name',
'label_attr' => ['class' => 'your-label-classes', 'for'=>"email"],
'attr' => [
'class' => "your-field-classes",
'type' => "email",
],
])
...
}
...
}

Related

How to make Textarea not resizable in Zend Form

I have a Zend Form and one of it's fields is a Textarea. I have set it's default size using 'rows' and 'cols' but I want the user not to be able to change it.
I have tried adding 'resize' => false, but it did not work.
public function __construct()
{
parent::__construct('form');
$this->setAttribute('method', 'post');
$this->setAttribute('role', 'form');
$this->add([
'name' => 'feedback',
'type' => Textarea::class,
'attributes' => [
'id' => 'feedback',
'class' => 'mdc-text-field__input',
'rows' => 3,
'cols' => 4,
'required' => false,
],
'options' => [
'label' => 'Feedback',
],
]);
}
You have the choice between
attributes => [
...,
'style' => 'resize:none'
]
or use a css class
attributes => [
...,
'class' => 'notresizable'
]
and define this css class in your css file.

How can I use one form fieldset in nested collection?

I am creating page to insert data like a book. Where I'm using zend form fieldset and collection. Fieldset have only two fields heading field and content field. Heading and sub-heading have same content(fields).
Ex:
1: Heading Content
1.1: Sub Heading
Content
1.1.1: Sub Heading
Content
1.1.2: Sub Heading
Content
1.1.2.1: Sub Heading
Content
1.1.2.2: Sub Heading
Content
...
1.1.3: Sub Heading
Content
..
1.2: Sub Heading
Content
...
2: Heading Content
Note: here indexing is just to show the parent child relationship.
Code are below:
This is main form.
class BookPointlForm extends Form
{
public function __construct($name = null)
{
parent::__construct('Form');
$this->add(array(
'type' => 'Zend\Form\Element\Collection',
'name' => 'points',
'attributes' => array(
'class'=> 'point_collection '
),
'options' => array(
'label' => 'Add Book Points',
'count' => 1,
'should_create_template' => true,
'allow_add' => true,
'target_element' => array(
'type' => 'Book\Form\BookPointMainFieldset',
),
),
));
$this->add(array(
'name' => 'submit',
'type' => 'Submit',
'attributes' => array(
'value' => 'Submit',
'id' => 'submitbutton',
'class' => 'btn btn-primary pull-right',
),
));
}
}
This fieldset is called in BookPointlForm's points collection
class BookPointMainFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct($name = null)
{
// we want to ignore the name passed
parent::__construct('Fieldset');
$this->add(array(
'type' => 'Zend\Form\Element\Collection',
'name' => 'points',
'attributes' => array(
'class'=> 'point_collection '
),
'options' => array(
'label' => 'Add Book Points',
'count' => 1,
'should_create_template' => true,
'allow_add' => true,
'target_element' => array(
'type' => 'Book\Form\BookPointFieldset',
),
),
));
$this->add(array(
'name' => 'add_nested_point',
'type' => 'Button',
'attributes' => array(
'value' => 'Add nested point',
'class'=> 'add_nested_point'
),
'options' => array(
'label' => 'Add Nested Point',
),
));
$this->add(array(
'type' => 'Zend\Form\Element\Collection',
'name' => 'nested-points',
'attributes' => array(
'class'=> 'nested_point_collection '
),
'options' => array(
'label' => 'Add Book Points',
'count' => 1,
'should_create_template' => true,
'allow_add' => true,
'target_element' => array(
'type' => 'Book\Form\BookPointFieldset',
),
),
));
}
public function exchangeArray($data) {
}
public function getInputFilterSpecification()
{
return array(
'weight' => array(
'required' => true,
),
);
}
}
This is main fieldset it contents heading and heading's content
class BookHeadingFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct($name = null)
{
$kraHeadingText = '';
// we want to ignore the name passed
parent::__construct('BookHeadingFieldset');
// $this
// ->setHydrator(new ClassMethodsHydrator(false))
// ->setObject(new KraHeading())
;
$this->add(array(
'name' => 'id',
'type' => 'Hidden',
'attributes' => array(
'value' => ''
)
));
$this->add(array(
'name' => 'manualHeadingText',
'type' => 'Textarea',
'options' => array(
'label' => 'Heading',
'label_options' => [
'disable_html_escape' => true
],
),
'labelOptions' => array(
'disable_html_escape' => true,
),
'attributes' => array(
'class' => 'form-control',
'placeholder'=>"Enter heading",
'COLS'=>"150",
// 'required' => 'true',
),
));
}
public function exchangeArray($data) {
}
public function getInputFilterSpecification()
{
return array();
}
}
...

Validating Zend\Form\Element\Collection

I have a form which has 'rows' added dynamically using Zend\Form\Element\Collection. This works fine, but I am struggling to add the validation for these rows.
So far my code looks something like the following. I presume I need to pass something to InputFilter\InputFilter::add() but I can't figure out what:
<?php
class EditForm extends \Zend\Form\Form
{
public function __construct()
{
parent::__construct('edit');
$this->setUpFormElements();
$this->setupInputFilters();
}
protected function setUpFormElements()
{
$fieldset = new \Zend\Form\Fieldset;
$nameElement = new \Zend\Form\Element\Text('name');
$fieldset->add($nameElement);
$descriptionElement = new \Zend\Form\Element\Text('description');
$fieldset->add($description);
$this->add(
array(
'type' => 'Zend\Form\Element\Collection',
'name' => 'rows',
'options' => array(
'label' => 'Edit Rows',
'should_create_template' => true,
'allow_add' => true,
'target_element' => $fieldset,
)
)
);
return $this;
}
public function setupInputFilters()
{
$filter = new \Zend\InputFilter\InputFilter();
$filter->add(
array(
'name' => 'rows',
'required' => true,
'validators' => array(
// Not sure what to do here!
)
)
);
return $this;
}
}
I think you need to add the input filter to the getInputFilterSpecification method of the fieldset you are adding dynamically
class Row extends Fieldset implements InputFilterProviderInterface
{
$this->add(array(
'name' => 'yourFieldset',
'options' => array(
'label' => 'One of your fieldset elements'
),
'attributes' => array(
'required' => 'required'
)
));
$this->add(array(
'name' => 'fields',
'options' => array(
'label' => 'Another fieldset element'
),
'attributes' => array(
'required' => 'required'
)
));
public function getInputFilterSpecification()
{
return array(
'yourFieldset' => array(
'required' => true,
),
'fields' => array(
'required' => true,
'validators' => array(
array(
'name' => 'Float'
)
)
)
);
}
then in your form you need to set the validation group
class EditForm extends Form
{
public function __construct()
{
$this->add(
array(
'type' => 'Zend\Form\Element\Collection',
'name' => 'rows',
'options' => array(
'label' => 'Edit Rows',
'should_create_template' => true,
'allow_add' => true,
'target_element' => $fieldset,
)
)
);
$this->setValidationGroup(array(
'csrf',
'row' => array(
'yourFieldset',
'fields',
)
));
}
}

attribute min and max in input file Zend Framework 2

I'm trying to create a multiple uploads with ZF2. I would set the min and max attribute on the input file. I tried in every way but ZF2 ignores these 2 attributes for the input file.
How can I do?
namespace Admin\Form;
use Zend\Form\Form;
class Image extends Form
{
public function __construct()
{
parent::__construct('image');
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'image',
'type' => 'Zend\Form\Element\File',
'attributes' => array(
'multiple' => true,
'accept' => '.jpg,.png',
'id' => 'image',
'min' => 1,
'max' => 5,
)
));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'save',
'id' => 'submitbutton',
'class' => 'btn btn-success'
)
));
}
}

How To Create Custom Form Elements That Extend Doctrine Entity Select Elements

I am trying to create a custom element where I can pre-set an entity namespace say -- Application\Entity\User and easily add that element to any form. I have an issue with injecting the doctrine em in form elements -- I found this post about the form_elements key in configuration but it doesnt work -- so I figured maybe just setup the element and pass it the objectmanager from the form.
I want to do something like this.
$this->add(
array(
'name' => 'user_id',
'type' => 'Application\Form\Element\UserSelect',
'options' => array(
'label' => 'User',
'object_manager' => $this->getObjectManager(),
),
),
);
Or even better just this
$this->add(
array(
'name' => 'user_id',
'type' => 'Application\Form\Element\UserSelect',
'label' => 'User',
),
);
module.config.php
'service_manager' => array(
'aliases' => array(
'doctrine_service' => 'doctrine.entitymanager.orm_default',
),
'initializers' => array(
function ($instance, $sm) {
if ($instance instanceof DoctrineModule\Persistence\ObjectManagerAwareInterface) {
$instance->setObjectManager(
$sm->get('doctrine_service')
);
}
if ($instance instanceof Application\Form\AbstractForm) {
$instance->init();
}
},
),
),
AbstractForm.php
namespace Application\Form;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use Zend\Form\Form as ZendForm;
abstract class AbstractForm extends ZendForm implements ObjectManagerAwareInterface
{
protected $objectManager;
public function setObjectManager(ObjectManager $objectManager)
{
$this->objectManager = $objectManager;
}
public function getObjectManager()
{
return $this->objectManager;
}
}
TestForm.php
namespace Users\Form;
use Application\Form\AbstractForm;
class Login extends AbstractForm
{
public function init()
{
$this->add(
array(
'name' => 'user_id',
'type' => 'DoctrineORMModule\Form\Element\DoctrineEntity',
'options' => array(
'label' => 'User',
'object_manager' => $this->getObjectManager(),
'target_class' => 'Application\Entity\User',
'property' => 'name',
'find_method' => array(
'name' => 'findBy',
'params' => array(
'criteria' => array('is_deleted' => 0),
'orderBy' => array('name' => 'ASC'),
),
),
),
),
);
}
}
Add your initializer and invokables to the getFormElementConfig method of your Module.php:
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
...
public function getFormElementConfig()
{
return array(
'invokables' => array(
'MyForm' => 'Application\Form\MyForm',
),
'initializers' => array(
'ObjectManagerInitializer' => function ($element, $formElements) {
if ($element instanceof ObjectManagerAwareInterface) {
$services = $formElements->getServiceLocator();
$entityManager = $services->get('Doctrine\ORM\EntityManager');
$element->setObjectManager($entityManager);
}
},
),
);
}
Then use the FormElementManager to get te form:
$forms = $this->getServiceLocator()->get('FormElementManager');
$myForm = $forms->get('MyForm');
Finally add your element inside the init method - not the constructor because he will never be aware of the objectManager:
public function init()
{
$this->add(
array(
'name' => 'user_id',
'type' => 'DoctrineORMModule\Form\Element\DoctrineEntity',
'options' => array(
'label' => 'User',
'object_manager' => $this->getObjectManager(),
'target_class' => 'Application\Entity\User',
'property' => 'name',
'find_method' => array(
'name' => 'findBy',
'params' => array(
'criteria' => array('is_deleted' => 0),
'orderBy' => array('name' => 'ASC'),
),
),
),
),
);
}
See a discussion on this setup here.

Resources