Contributte\Form-multiplier a závislý selectbox
- LuKo
- Člen | 116
Ahoj,
snažím se nakombinovat Form-multiplier a závislé selectboxy. Ve formuláři lze přidávat řádky dle potřeby, na každém řádku lze vybrat kategorii a případně i odpovídající podkategorii.
final class NewOrderFormFactory
{
use Nette\SmartObject;
public function __construct(private FormFactory $factory, private ListManager $listManager) { }
public function create(): Form
{
$form = $this->factory->create();
// ...
$multiplier = $form->addMultiplier('multiplier', function (Nette\Forms\Container $container, Nette\Forms\Form $form) {
$category = $container->addSelect('category_id', 'Kategorie:', $this->listManager->getCategories());
$category_sub = $container->addSelect('category_sub_id', 'Podkategorie:')
->setHtmlAttribute('data-items', $this->listManager->getSubcategories())
->setHtmlAttribute('data-depends', $category->getHtmlName()); // ERROR: Component 'category_id' is not attached to 'Nette\Forms\Form'.
$form->onAnchor[] = fn() =>
$category_sub->setItems($category->getValue() ? $this->listManager->getSubcategories($category->getValue()) : []);
}, 1, 10);
// ...
$form->addSubmit('send', 'Uložit');
return $form;
}
}
Řádek $category->getHtmlName()
v Multiplieru vrací:
Component 'category_id' is not attached to 'Nette\Forms\Form'
.
Nějak jsem se v tom zasekl a nemohu se hnout dále. Asi to bude jen nějaké
přehlédnutí, každopádně byl bych rád za jakékoli nakopnutí správným
směrem.
Předem díky za jakýkoli postřeh.
- m.brecher
- Generous Backer | 864
@LuKo
is not attached to ‚Nette\Forms\Form‘
To znamená, že se snažíš použít ten prvek předčasně ještě v době, kdy není připojen do hierarchie komponent – to bude v události Anchor. Zkus přesunout ten kód do callbacku onAnchor, nějak takhle:
$form = $this->factory->create();
// ...
$multiplier = $form->addMultiplier('multiplier', function (Nette\Forms\Container $container, Nette\Forms\Form $form) {
$category = $container->addSelect('category_id', 'Kategorie:', $this->listManager->getCategories());
$category_sub = $container->addSelect('category_sub_id', 'Podkategorie:')
->setHtmlAttribute('data-items', $this->listManager->getSubcategories());
$form->onAnchor[] = function()use($category_sub){
$category_sub->setHtmlAttribute('data-depends', $category->getHtmlName());
$category_sub->setItems($category->getValue() ? $this->listManager->getSubcategories($category->getValue()) : []);
};
}, 1, 10);
// ...
$form->addSubmit('send', 'Uložit');
return $form;
Píšu z hlavy, tak si to musíš doladit ;).
Editoval m.brecher (28. 3. 2023 1:23)
- LuKo
- Člen | 116
onAnchor
uvnitř Multiplieru mě napadl jako první, ale tam se
nezavolá. Zkusil jsem to tedy trochu méně elegantně vyřešit mimo
Multiplier:
public function create(): Form
{
$form = $this->factory->create();
$multiplier = $form->addMultiplier('multiplier', function (Nette\Forms\Container $container, Nette\Forms\Form $form) {
$category = $container->addSelect('category_id', 'Kategorie:', $this->listManager->getCategories());
$category_sub = $container->addSelect('category_sub_id', 'Podkategorie:')
->setHtmlAttribute('data-items', $this->listManager->getSubcategories());
}, 1, 10);
$form->onAnchor[] = function($form) {
foreach ($form['multiplier']->getComponents() as $item) {
if(!($item instanceof Submitter)) {
$item['category_sub_id']
->setHtmlAttribute('data-depends', $item['category_id']->getHtmlName())
->setItems($item['category_id']->getValue() ? $this->listManager->getSubcategories($item['category_id']->getValue()) : []);
}
}
};
$form->addSubmit('send', 'Uložit');
return $form;
}
Toto již funguje dle očekávání. Jen si nejsem jistý, zda to nelze
řešit nějak elegantněji, bez té podmínky
if(!($item instanceof Submitter))
.
- LuKo
- Člen | 116
Vida, to jsem přehlédl. Nyní je tedy finální verze:
public function create(): Form
{
$form = $this->factory->create();
// ...
$multiplier = $form->addMultiplier('multiplier', function (Nette\Forms\Container $container, Nette\Forms\Form $form) {
$container->addSelect('category_id', 'Kategorie:', $this->listManager->getCategories());
$container->addSelect('category_sub_id', 'Podkategorie:')
->setHtmlAttribute('data-items', $this->listManager->getSubcategories());
}, 1, 10);
$multiplier->onCreate[] = function (Nette\Forms\Container $container) {
$container['category_sub_id']
->setHtmlAttribute('data-depends', $container['category_id']->getHtmlName())
->setItems($container['category_id']->getValue() ? $this->listManager->getSubcategories($container['category_id']->getValue()) : []);
};
// ...
$form->addSubmit('send', 'Uložit');
return $form;
}
Případně je také možná mírně rozepsanější verze:
$multiplier->onCreate[] = function (Nette\Forms\Container $container) {
$category = $container->getComponent('category_id');
$category_sub = $container->getComponent('category_sub_id');
$category_sub
->setHtmlAttribute('data-depends', $category->getHtmlName())
->setItems($category->getValue() ? $this->listManager->getSubcategories($category->getValue()) : []);
};
Již to plně funguje, uvádím to sem jen pro případ, kdyby někdy někdo řešil něco podobného ;-)
Díky za cenné rady.