Ukážeme si, jak vytvořit a použít custom input v Nette formulářích pomocí navěšovacích metod, vlastního formuláře a přímo ve formuláři.
Téměř v každém projektu dospějeme do stavu, kdy je potřeba vytvořit si vlastní typ inputu. V mých aplikacíh se často opakuje DateInput
, DateTimeInput
a např. ImageControl
.
Nechceme neustále vynalézat kolo, tak se pokusím řadu z nejpouživanějších přidat do contributte/forms
. Než to tak bude, pojďme se podívat jaké máme možnosti.
Napadají mě 3 varianty:
- Instant Usage
- Extension Method
- Custom Form
Než přejdeme na ukázky, tak si vytvoříme custom input.
class EmailInput extends Nette\Forms\Controls\TextInput
{
public function __construct($label = null)
{
parent::__construct($label);
$this->setType('email');
}
public function setAlert($message)
{
$this->setRequired(TRUE);
$this->addRule(Nette\Forms\Form::EMAIL, $message);
}
}
Instant Usage
Náš EmailInput
použijeme ve formuláři přímo a to zavoláním metody addComponent($name, $component)
, poté input získáme metodou getComponent($name)
.
Protože Nette\Forms\Container
implementuje ArrayAccess
, lze inputy navěšovat i přes $form[$name]
a obdobně získat přes $form[$name]
.
class EmailPresenter extends Nette\Application\UI\Presenter
{
protected function createComponentEmailForm()
{
$form = new Form();
$form->addComponent('email', new EmailInput('My e-mail'));
$form->getComponent('email')->setAlert('Please type valid e-mail address');
// ====
$form['email'] = new EmailInput('My e-mail');
$form['email']->setAlert('Please type valid e-mail address');
return $form;
}
}
Osobně se mi to ale tolik nelíbí, daleko víc cool je využívat $form->add<input>
. S tím nám pomůžou následující 2 techniky.
Extension Method
Extension method je nanásilná technika, která nám umožní “navěsit” extra input do naších formulářů.
// bootstrap.php || CompilerExtension
Nette\Forms\Container::setExtensionMethod(
Nette\Forms\Container::class,
'addEmailInput',
function(Nette\Forms\Container $container, $name, $title = 'Your e-mail address') {
return $container[$name] = new EmailInput($title);
}
);
Využijeme k tomu Nette\Forms\Container::setExtensionMethod
, která navěsí extra metodu addEmailInput
, kterou můžeme použít při sestavování formulářů. setExtensionMethod
je vhodné zavolat v souboru bootstrap.php
nebo lépe, a to v CompilerExtension
. Důležité je zavolat tyto metody před použitím ve formulářích.
class EmailPresenter extends Nette\Application\UI\Presenter
{
protected function createComponentEmailForm()
{
$form = new Form();
$form->addEmailInput('email', 'My e-mail')
->setAlert('Please type valid e-mail address');
return $form;
}
}
Do objektu EmailInput
se předá titulek My e-mail
. Pokud bychom title neuvedli, vezme se předdefinovaná Your e-mail address
.
Podobně můžeme navěšovat i nové metody do Nette\Forms\Controls\BaseControl
a tím si rozšířit naše komponenty o super vlastnosti.
Custom Form
use Nette\Forms\Form;
class EmailForm extends Form
{
public function addEmailInput($name, $title = 'Your e-mail address')
{
return $this[$name] = new EmailInput($title);
}
}
class EmailPresenter extends Nette\Application\UI\Presenter
{
protected function createComponentEmailForm()
{
$form = new EmailForm();
$form->addEmailInput('email', 'My e-mail')
->setAlert('Please type valid e-mail address');
return $form;
}
}
Doufam, že jsem vám alespoň trochu přiblížil, jak lze tvořit a používat custom inputy v Nette formulářích. Pokud znáte další postupy, budu rád, když je uvedete v komentářích.