Problém s předáváním parametrů render metodě komponenty při překreslení snippetu v komponentě
- chikeet
- Člen | 160
Zdravím,
mám v latte komponentu:
{control emailShareComponent-2 center => TRUE, gaCategory => 'myCategory', gaAction => 'myAction'}
V komponentě je formulář, který se odesílá ajaxově (kvůli hezkým chybovým hláškám).
{snippet form}
{form emailShareForm class => 'ajax '}
{* ... *}
<button n:name="submit" type="submit" class="sendGaEvent" data-ga-category="{$gaCategory}" data-ga-action="{$gaAction}">{_front.form.submit}</button>
{/form}
{/snippet}
Problém je, že renderování snippetu „form“ při odpovědi na ajaxový požadavek mi skončí s exception ‚Undefined variable: gaCategory‘. Jak to provést, aby to takhle fungovalo? Při renderování to předávám komponentě proto, že se stejná komponenta používá napříč celým frontendem s různými parametry. Lepší způsob mě momentálně nenapadá. Zjevně mi ale uniká nějaká souvislost mezi fungováním snippetů a předáváním parametrů ze šablony presenteru. Za nakopnutí budu ráda.
Edit: v komponentě mám:
public function render(array $data = [])
{
# template
$template = $this->reflection->shortName;
$this->template->setFile(__DIR__ . '/' . $template . '.latte');
# template vars
foreach($data as $name => $value){
$this->template->$name = $value;
}
// ...
$this->template->render();
}
Render metoda se při ajaxu zavolá, ale pole $data
je
prázdné.
Editoval chikeet (31. 10. 2015 16:20)
- vitkutny
- Člen | 73
pokud jsou parametry povinné, vyžaduj je vždy v konstruktoru komponenty, dle toho vytvoř několik createComponent metod, případně zkombinuj pomocí multiplieru
protected function createComponentCenteredEmailShareComponent(){
return new Multiplier(function($gaCategory){
return new Multiplier(function($gaAction) use($gaCategory){
$control = new EmailShareComponent($gaCategory, $gaAction);
$control->setCentered();
return $control;
});
});
}
\—
použití v šabloně
{control centeredEmailShareComponent-gaCategory-gaAction}
\—
pokud je centrování provedeno mimo snippet, je možné využít samostatnou šablonu
/—html
{control emailShareComponent-gaCategory-gaAction:centered}
\—
nicméně pokud to jde tak zrovna centrování bych nedával do komponenty a tam kde má být centrovaná bych obalil divem s odpovídající třídou
/—-html
<div class=“centeredEmailShareComponent”>
{control emailShareComponent-gaCategory-gaAction}
</div>
- ic
- Člen | 430
A ještě si říkám, jestli jsou ty formuláře odesílány ajaxově
jenom kvůli hezkým chybovým hláškám, dá se to udělat
i bez toho. Metoda Nette.addError
( https://github.com/…etteForms.js#L235
) je pěkně psána tak, že se dá ‚přetížit‘ a místo alertování
může dělat nějaký o kus krásnější efekt. Jako výpis do flash
zpráviček nebo do nějakého elementu před/za ten který
formulářový prvek.
- chikeet
- Člen | 160
ic napsal(a):
A ještě si říkám, jestli jsou ty formuláře odesílány ajaxově jenom kvůli hezkým chybovým hláškám, dá se to udělat i bez toho. Metoda
Nette.addError
( https://github.com/…etteForms.js#L235 ) je pěkně psána tak, že se dá ‚přetížit‘ a místo alertování může dělat nějaký o kus krásnější efekt. Jako výpis do flash zpráviček nebo do nějakého elementu před/za ten který formulářový prvek.
To zní dobře. Je to určeno jen pro jednoduchou js validaci, nebo by se tam dala nějak rozumně ajaxově rozjet i server-side validace? To je totiž hlavní důvod současného řešení.
- ic
- Člen | 430
chikeet napsal(a):
To zní dobře. Je to určeno jen pro jednoduchou js validaci, nebo by se tam dala nějak rozumně ajaxově rozjet i server-side validace? To je totiž hlavní důvod současného řešení.
Nevím teď jestli jsme se dobře rozuměli… každopádně běžné nette formuláře, když je používám nějak takto:
$form->addText(self::COLUMN_USERNAME, 'Email:')
->setType('email')
->setAttribute('maxlength', 255)
->setRequired('Vyplň svůj email.')
->addRule(Form::EMAIL, 'Musíš zadat platnou emailovou adresu.');
$form->addPassword(self::COLUMN_PASSWORD, 'Password:')
->setAttribute('pattern', '^.{4,}$')
->setRequired('Zapomněl jsi zadat heslo.')
->addRule(Form::NOT_EQUAL, 'Heslo nesmí být stejné jako tvůj email', $form[self::COLUMN_USERNAME])
->addRule(Form::MIN_LENGTH, 'Heslo musí mít alespoň %d znaky', 4);
tak se automaticky validuje serverová část a navíc se generují
data-
atributy pro klientskou validaci pomocí
netteForms.js
(pokud si ho tedy člověk naincluduje do
stránky).
( ->setAttribute('pattern', '^.{4,}$')
je akorát pro html5
validaci bez nette, v podstatě duplicita k
->addRule(Form::MIN_LENGTH, 'Heslo musí mít alespoň %d znaky', 4)
akorát to bude pracovat i klientům bez JS )
A já měl za to, že problém je v tom, že netteForms.js
nedělají příliš přívětivé varování (běžný javascriptový alert).
Ale naštěstí se dají (aniž by musel člověk netteForms.js
hackovat a něco tam přepisovat) přetížit a ty hlášky si vypisovat někam
do formuláře, což je takové uživatelsky přívětivější.
- chikeet
- Člen | 160
@ic Šlo mi spíš o složitější validace, kde potřebuju po odeslání formu něco ověřit na serveru apod. Hlavně se mi to nechce řešit nadvakrát, jednou pro js validaci a podruhé pro tu po odeslání. Takže ajax tam řešit stejně musím, protože tyhle věci do js asi nemá smysl cpát. Každopádně ale díky za přínosné info :-)