Instalace více maker do latte – formuláře a linkGenerator
- oorac
- Člen | 7
Ahoj,
rád bych požádal o radu. Snažím se lazyloadem renderovat data na
stránce s tím, že klient by teď rád dostal do renderovaných dat
i modální okna, kde budou formuláře. Jakou cestou je nejlepší se
vydat?
Doteď jsem data přes ajax renderoval tímhle kódem.
$latte = new Engine();
$latte->setTempDirectory(ROOT_DIR . '/temp');
UIMacros::install($latte->getCompiler());
$latte->addProvider('uiControl', $this->linkGenerator);
$latte->addFilter(NULL, 'App\Services\IbiHelpers::common');
$latte->addFilter(NULL, 'App\Filters\Filters::common');
$translator = $this->translator;
$latte->addFilter('translate', $translator === null ? null : function (FilterInfo $fi, ...$args) use ($translator) {
return $translator->translate(...$args);
});
$params = [
'orders' => $orders,
'items' => $items,
'stocklist' => $stocklist,
'totalCount' => $count,
'linkGeneratorUse' => true,
'basePath' => '/store',
];
$response['orders'] = $latte->renderToString(ROOT_DIR . '/app/StoreModule/templates/Distribution/@rowSupplier.latte', $params);
$response['totalCount'] = $count;
$response['items'] = $items;
$response['stocklist'] = $stocklist;
$response['offset'] = $offset + $count;
$this->sendResponse(new JsonResponse($response));
Teď se snažím tam nainstalovat další Macro na formuláře přidáním řádku
FormMacros::install($latte->getCompiler());
ale hlásí mi to chybu s uiControl u n:name ve formuláři. Jak to prosím rozpoznat tak, aby latte chápalo, že na n:href chci linkGenerator, ale na n:name chci FormMarocs…?
Případně, je lepší cesta, kterou se vydat?
Děkuji
Editoval oorac (13. 2. 2023 8:25)
- Marek Bartoš
- Nette Blogger | 1264
To neuděláš, obojí závisí na provideru uiControl a ten by správně
měl být jen typu Nette\Application\UI\Control, LinkGenerator byl vždy jen
workaround.
Ale uiControl se používá jen v případě, že používáš
n:name="field"
, když použiješ
n:name="$form['field']"
, tak by to myslím mělo projít.
Editoval Marek Bartoš (13. 2. 2023 15:08)
- oorac
- Člen | 7
Marek Bartoš napsal(a):
To neuděláš, obojí závisí na provideru uiControl a ten by správně měl být jen typu Nette\Application\UI\Control, LinkGenerator byl vždy jen workaround.
Ale uiControl se používá jen v případě, že používášn:name="field"
, když použiješn:name="$form['field']"
, tak by to myslím mělo projít.
Můžu poprosit ještě o jednu radu?
Musel jsem nakonec udělat ještě jednu změnu a to, že v tomto jednom latte
volám jen uiControl bez formMacros, protože to bylo pomalé a neefektivní,
tak jsem to vymyslel tak, že jsem vytvořil ještě podřadnou stránku stejný
princip volání dat pro modal okno, kde mám teprve ten form renderovaný.
Nicméně, když dám odeslat formulář, tak se mi stránka změní na danou
action, která se volá přes jqery na volání dat pro modal okno a
nepřesměruje se mi to na onSuccess příkaz. Dokážeš mi s tímto
poradit?
Tohle mi načte stránku s doklady.
public function actionJsonSubscriberOrder() : void
{
............
$latte = new Engine();
$latte->setTempDirectory(ROOT_DIR . '/temp');
UIMacros::install($latte->getCompiler());
$latte->addProvider('uiControl', $this->linkGenerator);
$latte->addFilter(NULL, 'App\Services\IbiHelpers::common');
$latte->addFilter(NULL, 'App\Filters\Filters::common');
$translator = $this->translator;
$latte->addFilter('translate', $translator === null ? null : function (FilterInfo $fi, ...$args) use ($translator) {
return $translator->translate(...$args);
});
$params = [
'orders' => $orders,
'forDelivery' => $forDelivery,
'showNewStocklist' => $showNewStocklist,
'showConfirmedStocklist' => $showConfirmedStocklist,
'totalCount' => $count,
'linkGeneratorUse' => true,
'basePath' => '/store',
];
$response['orders'] = $latte->renderToString(ROOT_DIR . '/app/StoreModule/templates/Distribution/@rowSubscriber.latte', $params);
$response['totalCount'] = $count;
$response['showNewStocklist'] = $showNewStocklist;
$response['showConfirmedStocklist'] = $showConfirmedStocklist;
$response['offset'] = $offset + $count;
$this->sendResponse(new JsonResponse($response));
}
U každého dokladu je nějaké modal okno, které se vytváří opět přes další volání:
public function actionJsonSubscriberOrderItem() : void
{
................
$latte = new Engine();
$latte->setTempDirectory(ROOT_DIR . '/temp');
UIMacros::install($latte->getCompiler());
FormMacros::install($latte->getCompiler());
$latte->addProvider('uiControl', $this->linkGenerator);
$latte->addFilter(NULL, 'App\Services\IbiHelpers::common');
$latte->addFilter(NULL, 'App\Filters\Filters::common');
$translator = $this->translator;
$latte->addFilter('translate', $translator === null ? null : static function (FilterInfo $fi, ...$args) use ($translator) {
return $translator->translate(...$args);
});
$form = $this['createStocklistFromOrder'];
assert($form instanceof Form);
$params = [
'linkGeneratorUse' => true,
'products' => $this->products,
'form' => $form,
'basePath' => '/store',
];
$response['items'] = $latte->renderToString(ROOT_DIR . '/app/StoreModule/templates/Distribution/@modalSubscriber.latte', $params);
$this->sendResponse(new JsonResponse($response));
}
a až v tom modálním oknu mám n:name=„$form“, kde renderuji
formulář. Nicméně po odeslání formuláře se mi snaží nette
přesměrovat na stránku actionJsonSubscriberOrderItem, což je špatně.
Formulář mám v php takhle
public function createComponentCreateStocklistFromOrder() : Form
{
$form = $this->form();
$form->setAction('/store/distribution/create-stocklist');
$itemContainer = $form->addContainer('items');
foreach ($this->products['true'] as $product) {
$items = $itemContainer->addContainer($product['product_id']);
$items->addCheckbox('delivery');
}
$form->addSubmit('submit');
$form->onSuccess[] = [$this, 'createStocklist'];
return $form;
}
Takže bych rád, abych se po odeslání dostal na metodu createStocklist.
Jde to nějak vymyslet?
Děkuji
Editoval oorac (14. 2. 2023 20:14)
- Marek Bartoš
- Nette Blogger | 1264
Tipnu si setAction(). Formulář chceš zpracovat na stránce, kde je definovaný, jinak na zpracování skrze Nette nedojde. Přesměrovat jinam máš až v onSuccess. Při odeslání formuláře jsi request poslal na jinou stránku, na které instance formuláře není a tak ti jen přišla post data, která nemá kdo zpracovat.
Btw, proč řešíš odkazy manuálně? Od toho máš v presenteru
$this->link()
Stejně tak Latte, k šabloně se všemi makry a filtry co Nette poskytuje se
dostaneš přes $this->template
, případně vytvoříš přes
$this->templateFactory->createTemplate()
. Z template už se
dostaneš k Latte\Engine přes template->getEngine()
, aby sis
nastavil vlastní, lokální filtry a makra.
- Marek Bartoš
- Nette Blogger | 1264
Tohle bys taky nemusel řešit. Pro phpstorm i phpstan jsou Nette pluginy a rozumí typu komponent i bez assertů
$form = $this['createStocklistFromOrder'];
assert($form instanceof Form);