Tato třída rozšiřuje Nette formulář o několik funkcí
Mimo klasických metod setValues()
a getValues()
tu zde máme i setData()
a getData()
. To nám umožňuje přiřazovat k formuláři objekt, který bude formulář editovat. Využití najdeme zejména u entit. Formulář umí editovat ty data, na které máme ovladač - mapper
(viz mappers
).
Jedná se o ovladač, který edituje datový objekt. Pro vytvoření vlastního mapperu stačí implementovat rozhraní Venne\Forms\IMapper
.
onSuccess
- odeslání je validníonError
- odeslání je chybnéonValidate
- při validacionAttached
- při připojení k předkovionSave
- při ukládání do datového objektu (vizdata
), provádí se pouze tehdy, pokud je formulář validní, navíc může formulář ještě invalidovatonLoad
- při načítání z datového objektu (vizdata
)
Abychom dostali do formuláře své vlastní nové typy inputu, stačí jednoduše implementovat rozhraní Venne\Forms\IControlExtension
.
<?php
class DoctrineExtension extends Object implements IControlExtension
{
protected $form;
public function setForm(Form $form)
{
$this->form = $form;
}
public function getControls()
{
return array(
'one', 'two'
);
}
public function addOne($name)
{
return $this->form[$name] = new MyOne;
}
public function addTwo($name, $containerFactory, $entityFactory = NULL)
{
return $this->form[$name] = new MyTwo($containerFactory, $entityFactory);
}
}
Usnadňuje nám vytváření znovupoužitelných továrniček.
<?php
namespace CmsModule\Content\Forms;
use Venne;
use Venne\Forms\FormFactory;
use Venne\Application\UI\Form;
use DoctrineModule\Forms\Mappers\EntityMapper;
use DoctrineModule\ORM\BaseRepository;
class RoutesFormFactory extends FormFactory
{
protected $mapper;
protected $repository;
public function __construct(EntityMapper $mapper, BaseRepository $repository)
{
$this->mapper = $mapper;
$this->repository = $repository;
}
protected function getMapper()
{
return $this->mapper;
}
protected function getControlExtensions()
{
return array(
new \DoctrineModule\Forms\ControlExtensions\DoctrineExtension(),
);
}
protected function configure(Form $form)
{
$form->addMany('routes', function(\Nette\Forms\Container $container)
{
$container->setCurrentGroup($container->getForm()->addGroup('Route' . $container->data->url));
$container->addText('title', 'Title');
$container->addText('keywords', 'Keywords');
$container->addText('description', 'Description');
$container->addText('author', 'Author');
$container->addSelect('robots', 'Robots', \CmsModule\Content\Entities\RouteEntity::$robotsValues);
$container->addCheckbox('copyLayoutFromParent', 'Layout from parent');
});
$form->setCurrentGroup();
$form->addSubmit('_submit', 'Save');
}
public function handleSave(Form $form)
{
try {
$this->repository->save($form->data);
} catch (\DoctrineModule\ORM\SqlException $e) {
if ($e->getCode() == 23000) {
$form->addError("Role is not unique");
} else {
throw $e;
}
} catch (\Nette\InvalidArgumentException $e) {
$form->addError($e->getMessage());
}
}
}
__construct()
- použijeme pro podání požadovaných služebinjectFactory()
- nastavujeme zvenčí. Slouží pro podání továrny výchozího formuláře. V Nette bychom nastavovali službu@nette.basicForm
.getMapper()
- definuje mapper pro formulář. Lze vynechat.getControlExtensions()
- definuje třídy implementujícíIControlExtension
pro nové formulářové prvky. Lze vynechat.configure(Form $form)
- konfiguruje podobu formuláře.handleSuccess($form)
handleError($form)
handleValidate($form)
handleSave($form)
handleLoad($form)
handleAttached($form)
services:
cms.websiteFormFactory:
class: CmsModule\Forms\WebsiteFormFactory
setup:
- injectFactory(@nette.basicFormFactory)
class LanguagePresenter extends BasePresenter
{
...
protected $form;
public function injectForm(\CmsModule\Forms\LanguageFormFactory $form)
{
$this->form = $form;
}
public function createComponentForm()
{
$repository = $this->languageRepository;
$entity = $repository->createNew();
$form = $this->form->invoke($entity);
$form->onSuccess[] = $this->formSuccess;
return $form;
}
public function formSuccess()
{
$this->flashMessage('Entity has been saved.', 'success');
if (!$this->isAjax()) {
$this->redirect('this');
}
}
}