Vlastní form komponenta form->addNeco
- pavelinnuendo
- Člen | 33
Ahoj,
bojuji s tím, že u form->addText(..) se mi stále opakuje spousta
řádků se ->getControlPrototype()->addAttributes() a addRule. Rád bych
si proto podědil addText do vlastní komponenty form->addNeco(..), ale
nepřišel jsem na to jak.
Vše co jsem dohledal je pro starší Nette a ani to nerozchodil, třeba jako
důkaz,
že jsem hledal:
https://forum.nette.org/…addcondition
Mohl bych tedy poprosit o úplně základní kód implementace form->addNeco()?
Děkuji!
- Felix
- Nette Core | 1247
Presne jak pises, bud si podedis BaseControl nebo jestli je to primo prace s TextInput, tak rovnou ten. Pokud ale nebudes pridavat extra funkcionalitu, muzes to vsechno vyresit modifikovanim existujiciho TextInputu, nemusis tak vytvaret nove tridy.
Pak mas defacto 2 varianty:
- Extension Method
// bootstrap.php
Nette\Utils\ObjectMixin::setExtensionMethod(
Nette\Forms\Container::class,
'addMyInput',
function(Container $container, $name, $title = "My input", $size = 15) {
return $container[$name] = new MyTextInput($title, $size);
}
);
class Presenter
{
protected function createComponentForm()
{
$form = new Form();
$form->addMyInput($title = 'Test', $size = 25);
return $form;
}
}
- Vlastni form
class MyForm extends Form
{
public function addMyInput($name, $title = "My input", $size = 15)
{
return $this[$name] = new MyTextInput($title, $size);
}
}
class Presenter
{
protected function createComponentForm()
{
$form = new MyForm();
$form->addMyInput($title = 'Test', $size = 25);
return $form;
}
}
Editoval Felix (11. 8. 2017 23:14)
- pavelinnuendo
- Člen | 33
Pochopil jsem správně, že metoda createComponentForm() je v objektu MyTextInput?
Pak varianta jedna padá na Missing argument 4 for
Nette\Loaders\RobotLoader::App\Forms\{closure}() s
A varianta dvě na Undefined variable: name
- Felix
- Nette Core | 1247
pavelinnuendo napsal(a):
Pochopil jsem správně, že metoda createComponentForm() je v objektu MyTextInput?
Pak varianta jedna padá na Missing argument 4 for Nette\Loaders\RobotLoader::App\Forms\{closure}() s
A varianta dvě na Undefined variable: name
Malinko tedka nerozumim ke je problem, radeji jsem upravil ukazky jeste. :-)
- pavelinnuendo
- Člen | 33
Děkuji za trpělivost, ale ještě to je málo. :(
Varianta 1:
Call to a member function addComponent() on string
Varianta 2:
Argument 1 passed to {closure}() must be an instance of Container, instance of
Nette\Application\UI\Form given
MyTextINput mám takto:
class MyTextInput extends Nette\Forms\Container {
protected function createComponentForm()
{
$form = new Form();
$form->addMyInput($title = 'Test', $size = 25);
return $form;
}
}
Editoval pavelinnuendo (11. 8. 2017 23:33)
- pavelinnuendo
- Člen | 33
Už se chytám, takto to funguje:
class MyTextInput extends Nette\Forms\Controls\TextInput {
public function __construct($label, $maxLength)
{
parent::__construct($label, $maxLength);
$this->control->addAttributes([...]);
}
}
Děkuji vám oběma moc za trpělivost! :)
- pavelinnuendo
- Člen | 33
A varianta s setExtensionMethod je správně takto (má tam být Form nikoli Container):
Nette\Utils\ObjectMixin::setExtensionMethod(
Nette\Forms\Container::class,
'addMyInput',
function(Nette\Application\UI\Form $form, $name, $title, $size = null) {
return $form[$name] = new MyTextInput($title, $size);
}
);
- Felix
- Nette Core | 1247
Urcite to funguje na Nette\Form\Container
https://api.nette.org/…ntainer.html#…
- CZechBoY
- Člen | 3608
@Felix u toho custom formu je jeste mozna technika pres traitu.
Vytvori se trait s addXyz, custom form ktery bude mit prepsanou metodu
addContainer vracejici custom container. Form i Container pouzivajici tu
traitu.
trait TMyFormControls
{
pubf addEmail(...){...}
public function addContainer($name)
{
$control = new MyContainer;
$control->currentGroup = $this->currentGroup;
if ($this->currentGroup !== null) {
$this->currentGroup->add($control);
}
return $this[$name] = $control;
}
class CustomForm extends Form
{
use TMyFormControls;
}
class MyContainer extends Container {
use TMyFormControls;
}