formulář – nezavolá se callback z onSuccess
- Filip111
- Člen | 244
Prosím o radu/kontrolu: jedná se o jednoduchý formulář s odesláním
na email vytvořený uvnitř controlu.
Vykreslí se v pořádku, validace funguje v pořádku, když ho odešlu, data
v $_POST jsou naplněná, ale callback nastavený v onSuccess se neprovede.
Určitě je to nějaká začátečnická blbost…
use Nette\Application\UI\Form;
class ContactFormControl extends \Nette\Application\UI\Control {
public function render()
{
$form = new Form;
$form->addText('name', 'Jméno:', 30, 40)
->addRule(Form::MIN_LENGTH, 'Zadejte jméno', 5)
->addRule(Form::MAX_LENGTH, 'Jméno může mít maximálně 40 znaků', 40);
$form->addText('email', 'Váš email:', 30, 40)
->addRule(Form::EMAIL, 'Zadaný email není platný.');
$form->addTextArea('content', 'Text emailu:')
->addRule(Form::MIN_LENGTH, 'Zadejte text emailu.', 10)
->addRule(Form::MAX_LENGTH, 'Maximální délka textu je 5000 znaků', 5000);
$form->addSubmit('send', 'Odeslat');
$form->onSuccess[] = array($this, "sendSuccess");
echo $form;
}
public function sendSuccess($form)
{
// tady se proste nic nestane
$values = $form->getValues();
die('sended');
dump($values);
}
}
Ještě doplním továrničku z presenteru ať je to kompletní:
protected function createComponentContactForm()
{
$c = new \ContactFormControl ();
return $c;
}
- Filip Procházka
- Moderator | 4668
Fujky … ti to trochu upravim
class ContactForm extends Nette\Application\UI\Form {
public function __construct()
{
parent::__construct();
$this->addText('name', 'Jméno:', 30, 40)
->addRule(Form::MIN_LENGTH, 'Zadejte jméno', 5)
->addRule(Form::MAX_LENGTH, 'Jméno může mít maximálně 40 znaků', 40);
$this->addText('email', 'Váš email:', 30, 40)
->addRule(Form::EMAIL, 'Zadaný email není platný.');
$this->addTextArea('content', 'Text emailu:')
->addRule(Form::MIN_LENGTH, 'Zadejte text emailu.', 10)
->addRule(Form::MAX_LENGTH, 'Maximální délka textu je 5000 znaků', 5000);
$this->addSubmit('send', 'Odeslat');
$this->onSuccess[] = array($this, "sendSuccess");
}
public function sendSuccess()
{
// tady se proste nic nestane
$values = $this->getValues();
die('sended');
dump($values);
}
}
a továrnička
protected function createComponentContactForm()
{
return new \ContactForm();
}
Obalovat formulář do komponenty není špatný nápad, ale udělal jsi to úplně špatně. V metodě render se k němu signál nejenomže nedostane, ale vůbec jsi ten formulář ani nepřipojil k té rodičovské komponentě.
- Filip111
- Člen | 244
@22: HosipLan už asi ví jak jsem na tom…takže nepředpokládá
záludnosti, ale jen začátečnický chyby :)
Vykreslení je v šabloně jednoduše {control contactForm} a tohle je opravdu
jen formulář. Možná to obalení controlem a nějakou další logikou budu
potřebovat.
@HosipLan: Funguje to – myslel jsem, že pokud vytvářím komponentu musí dědit z \Nette\Application\UI\Control proto jsem se snažil formulář obalit. Teď mi ale docvaklo, že v továrničce createComponentContactForm() si vlastně můžu dělat co budu chtít.
Díky pánové, prozatím hotovo.
- Filip Procházka
- Moderator | 4668
@**Filip111**, 22: to udělat můžeš, ale nejjednodušší bude dát do šablony pohledu
{include 'mojeSablona.latte', 'form' => $control['contactForm']}
a tam v té „mojeSablona“ vykreslit ten formulář jak budeš potřebovat.
Pokud bys potřeboval můžeš formuláři časem upravit render
metodu aby uměla vykreslit šablonu přímo.
- Filip Procházka
- Moderator | 4668
Řekl jsem nejjednodušší :) Ale dobrá poznámka, snippety fungovat nebudou a invalidace divně.
- Filip111
- Člen | 244
Prozatím se to chystám použít tak jak už jsem před pár dny diskutoval s HosipLan(em?)…mám v databázi texty, které se renderují do šablony. V textu může být použit nějaký control jakožto plugin, takže volání musí být co nejjednodušší.
Navíc incude tam prostě být nesmí, to už by byla megadíra
v aplikaci.
Zatím ale nebudu předbíhat – až k tomu dojdu, začnu to řešit (a
možná už budu chápat v Nette víc souvislostí, zatím je to kousek po
kousku ale mám problém si to v hlavě pospojovat).
- Filip Procházka
- Moderator | 4668
Něco mi říká, že jsi úplně mimo :)) include je naprosto v pořádku. Navíc tohle je include šablony, o tohle se stará Nette.
Ale možná jsem tě nepochopil, přeber si, co jsem napsal a zkus vysvětlit co jsi napsal ty.
- Filip111
- Člen | 244
Zkusím to rozvést…možná jsem úplně mimo, ale ještě nechci předbíhat :)
Převádím frontend staršího CMS, takže zrovna tohle je něco co by se v Nette dalo vyřešit líp…ale zatím nevím jak, takže myšlenku jsem převedl do Nette.
V DB mám uložené články, ty obsluhuje jeden presenter. Článek obsahuje text a protože si zákazník občas vzpomněl, že tady uprostřed textu chce mít anketu nebo že před kontaktním formulářem chce mít vlastní text, používám pro objekt ankety, kontaktního formuláře atd.
{control poll 1}
{control contactForm}
(Pokud tam toho je víc, článek se zamkne a edituji ho jen já, aby v tom lidi neudělali bordel)
V presenteru se pak tento text renderuje, takže komponenty se spustí a zobrazí. Žádoucí je, aby volání těchto komponent/pluginů bylo co nejjednodušší a aby v textu článku nemohlo být nic jiného než volání určitých komponent (například include).
Zatím nevím jak jinak bych podobné požadavky řešil…takže používám
něco co asi není Nette řešení.
Jestli jste už pochopili o co mi jde a pořád si myslíte, že jsem úplně
mimo, tak prosím o nástin jednoduchého Nette řešení (stačí jen
myšlenka, bez kódu).
Díky.
- Filip Procházka
- Moderator | 4668
Aha, už tě chápu. Můžeš si udělat kombinaci maker, speciálně podle
tvé potřeby. A třeba odstranit {include}
a podobná, nebo
naopak, povolit jen to co potřebuješ. Toto nastavené Latte Engine pak
můžeš předat šabloně jako filtr a použít ji, pro
zpracování textů.
- Filip111
- Člen | 244
Vzhledem k tomu, že článek může editovat kde kdo, může tam klidně
vložit sám nějaký latte makra a rozsypat design, případně při použití
neexistujícího controlu to spadne do chyby.
Nekoukal jsem, jak Nette ošetřuje include v šablonách – pravděpodobně
je to ošetřené, takže by to nemusela být bezpečnostní díra narozdíl od
klasického includu, ale při zadání neexistujícího includu by to stejně
skončilo chybou celé aplikace.
Pointa je zkrátka taková, že je nežádoucí aby uživatel, který tvoří články používal jakákoliv latte makra s výjimkou povolených controlů.
Asi by nakonec bylo lepší, kdybych nezapisoval do článků přímo volání controlu, ale jen nějaké zástupné znaky, např.:
[[plugin poll 1]]
a obsah článku držel striktně v rovině HTML a nepovoloval jiné
elementy.
Potom bych před vypsáním nahradil tyto volání pluginu za volání controlu
{control poll 1} a nechal renderovat obsah.
- Filip Procházka
- Moderator | 4668
Článek v databázi preprocesuje pomocí latte, aby v něm mohl mít
vykreslení komponent (třeba anketu). Proto je nežádoucí, aby redaktor mohl
napsat {include 'sablona'}
, nebo nejdeboze
{? dump(Nette\Environment::getConfig())}
Ještě bys mohl udělat to, že by jsi využil Texy!
a dopsal
si do něj modul, který tohle zpracuje, nějaký výchozí na metadata
{{neco}}
tam už je, snad by šel upravit?
Editoval HosipLan (24. 8. 2011 11:17)
- Lopata
- Člen | 139
Hlavně je třeba mít na paměti, že Latte neodstraňuje php tagy, to
musíš udělat sám. K čemu je zakázané {include $dest}
, když
funguje normálné PHP include, že… Doporučuji podědit
Nette\Latte\Engine
a přepsat metodu __invoke()
.
Budeš-li to odstraňovat regulárním výrazem, dej pozor na vylomeniny typu
<<?php ?>?php foo(); ?>
nebo
<?php foo(); /*
(žádný end tag). Neopomeň ani asp a short
tags, popř. <?=
.
- Filip111
- Člen | 244
Texy asi používat nebudu – v administraci používám TinyMCE, takže
si přegenerování nějakých metadat budu muset zajistit sám.
Jde o to, že zatím mám předělaný jen frontend a ten využívá již
existující strukturu databáze – nebyl jsem nucenej nic měnit, takže
můžu kdykoliv nakopírovat novou verzi frontendu v Nette na starší web
(vlastní „CMS“) kde jsou již články v DB uložený v HTML formátu
(udělat update struktury databáze na aktuální verzi), lehce upravit šablony
(což ze Smarty na latte není takový problém) a web by měl běžet jako
dřív (tedy lépe než dřív :)
Pokud zjistím, že musím udělat tlustou čáru mezi starou a novou verzí frontendu nebo celého CMS, změnit strukturu DB a hlavně až budu mít pod Nette udělanou i administraci, můžu uvažovat o používaní Texy!
@Lopata: díky za rady…když už jste mi toho všichni tolik doporučili, asi se do toho pustím co nejdřív.
Editoval Filip111 (24. 8. 2011 13:15)