Instalace více maker do latte – formuláře a linkGenerator

oorac
Člen | 6
+
0
-

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 | 1146
+
0
-

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 | 6
+
0
-

Funguje, moc děkuji za nasměrování.

oorac
Člen | 6
+
0
-

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 | 1146
+
+1
-

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 | 1146
+
0
-

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);
oorac
Člen | 6
+
0
-

Super, už je mi to hned jasnější, díky moc :)
Latte i form jsem upravil, nějak mi to nedocvaklo, díky za upozornění.