Komponenta při prekreslení snippetu se nedokáže vykreslit
- Danny
- Člen | 146
zdravím,
potřeboval bych poradit. Mám vytvořenou komponentu kde mám multiplier
public function createComponentForm() {
return new UI\Multiplier(function() {
$form = new UI\Form;
$form->setTranslator($this->translator);
$form->getElementPrototype()->addAttributes(array('class' => 'ajax'));
$form->addHidden('type', $this->type);
$form->addText('name', 'messages.layout.form.name')
->setRequired('Zadejte jméno');
$form->addEmail('email', 'messages.layout.form.email')
->setRequired('Zadejte email');
$form->addTextArea('content', 'messages.layout.form.content')
->setRequired('Zadejte dotaz');
$form->addSubmit('send', 'messages.layout.form.send');
$form->onSuccess[] = [$this, 'contactFormSucceeded'];
return $form;
});
}
V render metode komponenty predavam ID do sablony
{control multipleForm, $id}
public function render($id)
{
$template = $this->template;
$template->setTranslator($this->translator);
$template->id= $id;
$template->setFile(__DIR__ . '/component.latte');
$template->render();
}
a vykresluju podle toho multipler form
component.latte
{snippet formSnippet}
<div class="contact-box">
{form form-$id}
<div class="contact-form">
<div>
<div class="form-group">
{label email/}
{input email}
</div>
</div>
<div>
<div class="form-group textarea">
{label content/}
{input content}
</div>
</div>
</div>
{/form}
</div>
{/snippet}
Vše funguje bez problému ale pokud tu componentu při
zpracování(odeslání) zpracuju ajaxem a refresnu snippet
snippetForm tak mi to hodí hlášku
Nette\InvalidArgumentException Component name must be non-empty
alphanumeric string, '' given.
Arguments: form-
Pochopil jsem to tak že při překreslení snippet ten form nezná ID a proto není schopný vykreslit form- místo např form-1.
Věděl by někdo jak tohle vyřešit?
Díky moc :)
- David Matějka
- Moderator | 6445
trochu se ztracim v hierarchii (kdej je to multipleForm
definovany?) komponent, ale problem bude asi v
{control multipleForm, $id}
. nikdy nepredavej data do render metody
komponenty, s ajaxem to nefunguje. predavej to primo v createComponent*
metode. pokud vykreslujes vice komponent, tak pouzij multiplier.
a to tve pouziti multiplieru je divny, predavas tam id pres
{control form-$id}
, ale nikde ho nezpracovavas, jelikoz tam
mas jen
return new UI\Multiplier(function() {
a dle component.latte to vypada, ze tam vykreslujes vzdy jen jeden formular
nebude ti uplne stacit, kdyz budes mit komponentu s formularem:
public function createComponentForm() {
$form = new UI\Form;
$form->setTranslator($this->translator);
$form->getElementPrototype()->addAttributes(array('class' => 'ajax'));
$form->addHidden('type', $this->type);
$form->addText('name', 'messages.layout.form.name')
->setRequired('Zadejte jméno');
$form->addEmail('email', 'messages.layout.form.email')
->setRequired('Zadejte email');
$form->addTextArea('content', 'messages.layout.form.content')
->setRequired('Zadejte dotaz');
$form->addSubmit('send', 'messages.layout.form.send');
$form->onSuccess[] = [$this, 'contactFormSucceeded'];
return $form;
}
bez multiplieru a z presenteru rovnou predavat ID v createComponent* metode?
vice o fungovani snippetu v https://www.youtube.com/watch?…
- Danny
- Člen | 146
Díky za reakci.
Princip je takový že sem chtěl vytvořit komponentu kterou budu moct použít víckrát v projektu, respektive potřebuju formulář který může být buď poptávka/nabídka/dotaz. Položky budou pořád stejné, jen se bude lišit IDčkem.
Form pro poptávku a nabídku je ve footeru takže jí injectuju rovnou v base presentru aby se includovala vždy v šablone, na každé stránce.
V base presentru teda mám:
public function createComponentMultipleForm () {
return $this->contactComponent->build();
}
A pak ve footeru mám (momentálně místo ID předávám konstantu OFFER atd)
{control multipleForm, 1}
{control multipleForm, 2}
Šlo mi o to že bych si jenom v šablone předal parametr do komponenty a v komponentě vykreslil ten form s tímto ID, nebo s jiným příznakem.
- David Matějka
- Moderator | 6445
ok, udelej to zhruba nasledovne:
public function createComponentMultipleForm () {
return new Multiplier(function ($id) {
return $this->contactComponent->build($id);
});
}
a to contactComponent->build($id)
ti vrati komponentu, ktere
preda id nekam do konstruktoru a ta uz pod sebou nemusi mit zadny mutliplier,
v createComponentForm bude vracet klasicky form
a ve footer pak budes zapisovat {control multipleForm-1}
- Danny
- Člen | 146
Když to udělám takto, tak mi to píše
Nette\MemberAccessException
Call to undefined method Nette\Application\UI\Multiplier::render().
Předpokládám že je to ta metoda Render kterou mám v komponentě, v které si setuju template atd, ale nechápu proč jí to nezná.
public function render($id)
{
$template = $this->template;
$template->setTranslator($this->translator);
$template->id= $id;
$template->setFile(__DIR__ . '/component.latte');
$template->render();
}
- David Matějka
- Moderator | 6445
opravdu mas v sablone {control multipleForm-1}
a ne
{control multipleForm 1}
?
- David Matějka
- Moderator | 6445
$this->contactComponent->build($id);
musi vzdy vracet
novou instanci komponenty
- Danny
- Člen | 146
Takhle vypadá ta komponenta
<?php
namespace App\FrontendModule\Components;
class ContactComponent extends BaseControl
{
//constructor a zavislosti atd..
public function build($id) {
$form = new UI\Form;
$form->setTranslator($this->translator);
$form->getElementPrototype()->addAttributes(array('class' => 'ajax'));
// inputs...
$form->addSubmit('send', 'messages.layout.form.send');
$form->onSuccess[] = [$this, 'contactFormSucceeded'];
return $form;
}
public function contactFormSucceeded(UI\Form $form, $values) {
//zpracovani
}
public function render()
{
$template = $this->template;
$template->setTranslator($this->translator);
$template->setFile(__DIR__ . '/component.latte');
$template->render();
}
}
Editoval Danny (30. 8. 2018 10:53)
- David Matějka
- Moderator | 6445
jsem myslel, ze build je nejaka tovarna, ktera ti bude vytvaret tu komponentu ContactComponent, ale ono ti to vraci ten formular. mrkni "do dokumentace':https://doc.nette.org/…n/components#… jak psat komponenty s tovarnama.