Form reference
Auto Complete Entity
Imagine you want to write your own repository method, because the search results depend not only on a search term but also on other attributes (e.g. the User, who bought a specific Product). Let's call this method findByTermAndUser
. This is, how this method could look like:
<?php
namespace App\Repository;
use Enhavo\Bundle\ResourceBundle\Repository\EntityRepository;
class ProductRepository extends EntityRepository
{
public function findByTermAndUser($term, $userId, $limit)
{
$query = $this->createQueryBuilder('p')
->where('p.user = :userId')
->andWhere('p.title = :term')
->setParameter('userId', sprintf('%s%%', $userId))
->setParameter('title', sprintf('%s%%', $term))
;
$result = $query->getQuery()->getArrayResult();
$paginator = $this->getPaginator($query);
$paginator->setMaxPerPage($limit);
return $paginator;
}
}
That's how a standard Auto-Complete-Entity-Route
looks like:
app_product_auto_complete:
options:
expose: true
path: /app/product/auto_complete
methods: [GET]
defaults:
_controller: enhavo_form.controller.auto_complete:searchAction
_config:
class: App\Entity\Product
repository:
method: findByTerm
Maybe you have already noticed the problem. That route only works for the standard findByTerm
with the two parameters $term
and $limit
. So how can we add the $userId
?
The easiest way is to add a flexible value with the userId, we need to add a value to our path and pick that value to use it as function argument. To use this value from our route as argument for our findByTermAndUser
, the Route
must have the arguments as follows:
app_product_auto_complete:
options:
expose: true
path: /app/product/{userId}/auto_complete
methods: [GET]
defaults:
_controller: enhavo_form.controller.auto_complete:searchAction
_config:
class: App\Entity\Product
repository:
method: findByTermAndUser
arguments:
- expr:configuration.getSearchTerm()
- expr:request.get('userId')
- expr:configuration.getLimit()
We add all necessary parameters as arguments for our method and use the expr:request.get('param')
to get our last missing value. The two other values are already in our expr.configuration
and have their own Getter-Methods
.
Finally, the last question is, how we add the $userId
to our path. To solve this problem, lets add the $userId
as route_parameter
to our Auto-Complete-Entity-Type
like that:
<?php
namespace App\Form\Type;
use App\Entity\Product;
class ProductType extends AbstractType
{
use ContainerAwareTrait;
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
/** @var User $user */
$userId = $event->getData()->getId();
$form = $event->getForm();
if (!empty($userId) {
$form->add('product', AutoCompleteEntityType::class, [
'class' => Product::class,
'route' => 'app_product_auto_complete',
'route_parameters' => [
'userId' => $userId
]
]);
}
});
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Product::class
]);
}
public function getBlockPrefix()
{
return 'app_applications_user';
}
}
Note
Notice, that a Route-Parameter
can not be NULL
and that we have multiple options, to get our $userId
. The easiest way is to use the EventListener
like in our example. For more information go to the Symfony Form Events-Documentation . If you want to see the other options, read our and the Symfony Documentation about Forms in general.
Boolean
The form type BooleanType
can be used for boolean fields. It renders a true/false radio select.
Field Options
- default: (true/false/null) The initial value to be set if the value in the resource is null. If this is null (default), none of the checkboxes will be checked.
Currency
The type '' enhavo currency'' can be used for any field, where a currency is needed.
Features
The enhavo currency type converts the database integer value into a full price and vice versa. It works like a natural price field and not like a database field, it is not needed to type 1200, to express 12,00 EUR, which makes it very comfortable for the user.
FormType
<?php
use Enhavo\Bundle\FormBundle\Form\Type\CurrencyType;
class YourShopClass extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('price', CurrencyType::class, array(
'label' => 'Price'
));
}
}
Date
Date Time
Entity Tree
Head Line
List
The enhavo_list
helps you to list individual fields on your page. To use the enhavo_list
just follow these steps:
- Add to FormType
- Add to your orm.yml
- Add properties
Add to FormType
Add the enhavo_list
to your FormType. For the parameter type
you can either add a FormType from an Entity you have created or use a doctrine type. You can only add more list items if the allow_add
parameter is true. If you want to delete added items, set the allow_delete
parameter to true.
In this example we use a doctrine formType.
$builder->add('tag', 'enhavo_list', array(
'type' => 'text',
'label' => 'label.tag',
'prototype' => true,
'allow_add' => true,
'by_reference' => false,
'allow_delete' => true
));
If you want to use your own entity, just replace the type
like this:
'type' => 'project_tag',
In this example we added a tag to the enhavo_list
.
Add to your orm.yml
Add the list type to your arme.orm.yml
. If you added a doctrine type, just add a field with type array
like this:
tag:
type: array
nullable: true
If you added your own formType, create a oneToMany
relationship. In this case you also have to add some extra code to the add function in your entity:
$tag->setAcme($this);
and to the remove function:
$this->tags->removeElement($tag);
Add properties
There are two more properties you can add to the formType. Add these like you have done it with the allow_delete
property. If you want to separate the items from eachother with a border, set the border
property to true. If not you can just skip this step.
'border' => false,
If you want to sort the added items, set the sortable
property to true.
'sortable' => true,
If you have used your own entity, you have to do a few steps more. First you add sortable_property
like you have done it with the border and sortable property before.
'sortable_property' => 'order'
Then you add a order
field to the orm.yml of the entity you have used in the enhavo_list
.
order:
column: '`order`'
type: string
length: 255
After that use the order as a hidden field in the tagType like this:
$builder->add('order', 'hidden', array(
'attr' => array('class' => 'order')
));
The name of the class has to be the same you used for the sortable_property
.
Message
Poly Collection
This type is used for collections, which need different form types for each item. It will ask the user to select a type if he add a new item.
Basic Usage
use Enhavo\Bundle\FormBundle\Form\Type\PolyCollectionType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
// ...
$builder->add('items', PolyCollectionType::class, [
// a list of entry types, which the user can choose when pressing add button
'entry_types' => [
'text' => TextType::class,
'date' => DateType::class,
],
// these options are passed to type
'entry_types_options' => [
'text' => ['label' => 'I am a label'],
'date' => ['label' => 'Type in the date'],
],
// tell how we know what type the data is
'entry_type_resolver' => function($data) {
return $data instanceof DateType ? 'date' : 'text';
},
]);
Field Options
entry_types
entry_types_options
entry_type_resolver
Position
Slug
Unit
Wysiwyg
This section explains how you can configure your wysiwyg editor system-wide and in some special cases. Enhavo uses the TinyMCE
editor, so if you are familiar with its settings you should easily be able to configure it. Otherwise you should also read the TinyMCE configuration docs.
Configuration
You can find the system wide configurations under app/config/wysiwyg.yml
. All settings here are equivalent to the TinyMCE
configuration, mentioned above. Note that this is a yaml file while the TinyMCE configuration is a Javascript Object or JSON, but yaml can easily be converted to JSON.
These configurations are available:
height: 150
toolbar1: "undo redo | bold italic underline strikethrough subscript superscript removeformat | link styleselect"
toolbar2: "table | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | code"
style_formats:
- {title: 'Bold text', inline: 'b'}
- {title: 'Red text', inline: 'span', styles: {color: '#ff0000'}}
- {title: 'Red header', block: 'h1', styles: {color: '#ff0000'}}
- {title: 'Example 1', inline: 'span', classes: 'example1'}
- {title: 'Example 2', inline: 'span', classes: 'example2'}
- {title: 'Table styles'}
- {title: 'Table row 1', selector: 'tr', classes: 'tablerow1'}
formats:
alignleft: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'left'}
aligncenter: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'center'}
alignright: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'right'}
alignfull: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'full'}
bold: {inline: 'span', 'classes': 'bold'}
italic: {inline: 'span', 'classes': 'italic'}
underline: {inline: 'span', 'classes': 'underline', exact: true}
strikethrough: {inline: 'del'}
customformat: {inline: 'span', styles: {color: '#00ff00', fontSize: '20px'}, attributes: {title: 'My custom format'}}
content_css: ~ # see below
content_css
Since we're using the assets/assetics commands for css file locations, you need to use the "@" syntax for the configuration of content_css
.
#single file
content_css: '@FooBundle/Resources/public/css/styleOne.css'
#multiple files
content_css:
- '@FooBundle/Resources/public/css/styleOne.css'
- '@FooBundle/Resources/public/css/styleTwo.css'
FormType
If you need a special configuration for just one form, you can override or filter some settings in your FormType class, in the option array.
- formats: Needs an array, where you can list the formats that should be shown.
- height: Override the height
- toolbar1: Override the toolbar1
- toolbar2: Override the toolbar2
- content_css: Override the content_css, this could be an array or a string (use "@" syntax)
$builder->add('text', 'wysiwyg', array(
'formats' => array('Bold text', 'Red text'),
'height' => 300,
'toolbar1' => '',
'toolbar2' => ''
'content_css' => array(
'@FooBundle/Resources/public/css/styleOne.css'
)
);