Module which handle forms.
[TOC]
command:
$ composer require wame/DynamicObject:0.0.1
or
composer.json:
{
// ...
"require": {
// ...
"wame/DynamicObject" : "0.0.1"
}
}
To obtaining form component, module provide builders. Each builder provide functionality to handle different tasks.
config:
Admin.MyFormBuilder:
class: Wame\DynamicObject\Forms\EntityFormBuilder
setup:
- setRepository(@MyRepository)
- add(@Wame\DynamicObject\Forms\Groups\IBasicGroupFactory, 'BasicGroup', {priority: 200})
- add(@Wame\DynamicObject\Forms\Containers\ITitleContainerFactory, 'TitleContainer', {priority: 190})
php:
/**
* Create component form
*
* @return EntityForm form
*/
protected function createComponentForm()
{
return $this->context->getService("Admin.MyFormBuilder")
->setEntity($this->entity)
->build($this->domain);
}
add(containerFactory, containerName, containerParameters)
example:
- add(@Wame\DynamicObject\Forms\Containers\ITitleContainerFactory, 'TitleContainer', {priority: 90})
Parameters:
- priority - containers with higher priority are top
- domain - value that must be equals with value provided in
build
method
remove(containerName)
example:
- remove('TitleContainer')
**setRepository(repository)
example:
- setRepository(@MyRepository)
redirectTo(route|link)
example:
- redirectTo(:Admin:Dashboard:)
example:
services:
MyFormBuilder:
class: Wame\MyModule\Forms\MyFormBuilder
setup:
- add(@Wame\DynamicObject\Forms\Containers\ITitleContainerFactory, 'TitleContainer', {priority: 90})
Builder which doesn't save anything to database, there is nothing like create
/update
... just submit
.
Builder:
class FilterFormBuilder extends BaseFormBuilder
{
/** {@inheritDoc} */
public function submit($form, $values)
{
// code
}
}
Component:
protected function createComponentSortForm()
{
$form = $this->articleFormBuilder->build();
return $form;
}
Improved builder that handle single entity. Edit provide entity which is used for container's default values and create empty entity, which is filled by containers.
Builder must implement getRepository
method, that is used to working with entity.
In order to handle default values, you need call setEntity
.
Builder working with translatable data.
In order to handle default values, you need call setEntity
and setLangEntity
.
MyFormBuilder.php (FormBuilder)
<?php
namespace Wame\MyModule\Forms;
use Wame\MyModule\Repositories\MyRepository;
use Wame\DynamicObject\Forms\LangEntityFormBuilder;
class MyFormBuilder extends LangEntityFormBuilder
{
/** @var ParameterRepository */
private $parameterRepository;
public function __construct(ParameterRepository $parameterRepository)
{
parent::__construct();
$this->parameterRepository = $parameterRepository;
}
/** {@inheritDoc} */
public function getRepository()
{
return $this->myRepository;
}
}
Builder which saves all containers as individual rows.
In order to handle default values , you need call setEntities
or setCriteria
.
MyFormBuilder.php:
<?php
namespace Wame\MyModule\Forms;
use Wame\MyModule\Repositories\MyRepository;
use Wame\DynamicObject\Forms\RowFormBuilder;
class MyFormBuilder extends RowFormBuilder
{
// code ...
}
Every form container shoud be in this structure: forms\conintainers\<containerName>\<ContainerName>Container
(e.g.: forms\containers\title\TitleContainer
), to achieve consistence .
ITitleContainerFactory (Container)
<?php
namespace Wame\DynamicObject\Forms\Containers;
use Wame\DynamicObject\Registers\Types\IBaseContainer;
interface ITitleContainerFactory extends IBaseContainer
{
/** @return TitleContainer */
public function create();
}
class TitleContainer extends BaseContainer
{
/** {@inheritDoc} */
public function configure()
{
$this->addText('title', _('Title'))
->setRequired(_('Please enter title'));
}
/** {@inheritDoc} */
public function setDefaultValues($entity, $langEntity = null)
{
$this['title']->setDefaultValue($entity->getTitle());
}
/** {@inheritDoc} */
public function create($form, $values)
{
$entity = method_exists($form, 'getLangEntity') ? $form->getLangEntity(): $form->getEntity();
$entity->setTitle($values['title']);
}
/** {@inheritDoc} */
public function update($form, $values)
{
$entity = method_exists($form, 'getLangEntity') ? $form->getLangEntity(): $form->getEntity();
$entity->setTitle($values['title']);
}
}
Configure container
example:
/** {@inheritDoc} */
public function configure()
{
$this->addText('title', _('Title'))
->setRequired(_('Please enter title'));
}
Bind data to the template
example:
/** {@inheritDoc} */
public function compose($template)
{
$template->count = $this->count;
}
Create event callback
Update event callback
Post create event callback
Post update event callback
To prevent collision of name
parameter, containers has format: name="[<ContainerName>][<InputName>]"
(e.g.: name="[TitleContainer][title]"
)
Forms can be rendered automatically or by TemplateFormRender
, which render containers using latte templates.
Templates are located in same folder as container. Default name is default.latte
.
example:
{var $title = $container['title']}
<div class="form-group">
{label $title/}
<input class="form-control" n:name="$title">
</div>
It's possible create form group in container's method configure
:
/** {@inheritDoc} */
public function configure()
{
$group = new BasicGroup;
$this->getForm()->addBaseGroup($group);
// ...
}
or in config:
- add(@Wame\DynamicObject\Forms\Groups\IBasicGroupFactory, "BasicGroup", {priority: 60, tag: div, attributes: {class: group, data-group: basic}})
parameters:
- priority - groups with higher priority are top
- domain -
- tag - html element name
- attributes - html element attributes
- setTag($tag) - set html element name
- setAttributes($attributes) - set html element attributes
- setAttribute($name, $value) - set html element attribute
- Check if you pass entity to builder via
setEntity
method.
- Check if you add container in config
- Check if container's template has right name
- Check if you implemented proper method in container (
create
,update
,postCreate
,postUpdate
)