zprovoznění formuláře v šabloně → uplný začátečník
- chuck_horis
- Člen | 8
Zdravím všechny, jelikož jsem slyšel na nette samou chválu, rozhodl jsem
se, že se to taky naučím. Posledních pár dní po večerech tedy studuji..
Mám však problém rozchodit i základní věci, které v php normálně
zvládám :(
Stáhl jsem si nette 2 beta, poté jsem vytvořil statický web podle
tutoriálu „Statický web s menu“, což jsem zmákl, pak jsem chtěl podle
dalšího vytvořit formulář se zasíláním na mejl, to už se mi nepovedlo..
Autor používá 2 alpha, je tento tutoriál funkční?
Pustil jsem se tedy podle dokumentace do vytváření vlastního řešení..
do homepage presenteru jsem tedy přidal:
<?php
protected function createComponentForm()
{
$form = new Nette\Application\UI\Form;
$form->addText('name', 'Jméno:');
$form->addText('email', 'Email:');
$form->addTextarea('note', 'Poznamka');
$form->onSuccess[] = callback($this, 'signInFormSubmitted');
return $form;
}
?>
do šablony contact.latte
<?php
{control Form}
?>
Laděnka píše: „Component with name ‚Form‘ does not exist“
Já si však myslím, že tu komponentu jsem vytvořil v tom presenteru,
ne?
Děkuji za každou radu!! :)
- chuck_horis
- Člen | 8
Tak další den a další pokus s nette :)
Nechápu asi jednu věc, pokud si čtu např návod jako na formuláře nebo
databaze s nette, kam mám tento kod kopírovat? Jedná se mi o to, že když
ho dám do šablony nic se nedeje a kod se vypíše jako text.. Proto jsem kod
dal do pressenteru. Kam tedy kopírovat ukázky kodů? Do šablon ?
Snažil jsem se rozchodit validaci:
<?php
protected function createComponentForm()
{
$form = new Nette\Application\UI\Form;
$form->addText('name', 'Name:')
->addRule(Form::FILLED, 'Zadejte jméno');
$form->addText('email', 'Email:')
->addRule(Form::EMAIL, 'Zadejte jméno');
$form->addTextarea('note', 'Note:')
->addRule(Form::FILLED, 'Vyplnte poznámku!');
$form->addSubmit('send', 'Odeslat');
return $form;
}
?>
Samozřejmě, laděnka mi píše že class "Form ",takžeje potřeba jí vytvořit nebo vložit? Vím že se tam nemá psát Nette\Forms\Form ale Nette\Application\UI\Form, když je to v presenteru :\ Stejně tak nevím jak vložit javascript validaci :\
Dále bych rád pokračoval s odesláním na mejl, takže pokud doplním
<?php
$form->onSubmitted[] = 'FormSubmitted';
?>
A pak vytvořím komponentu Formsubmitted bude to dobře, ano? Musím říct, že fakt strašně tápu i v základní logice:\ Díky za pomoc!
Editoval chuck_horis (10. 11. 2011 13:32)
- Filip Procházka
- Moderator | 4668
Ono kdyby jsi si pročetl tu dokumentaci i 2×, tak se třeba lépe chytneš. A evidentně máš také problémy se základy PHP, které by jsi si měl doplnit!
chuck_horis napsal(a):
Nechápu asi jednu věc, pokud si čtu např návod jako na formuláře nebo databaze s nette, kam mám tento kod kopírovat? Jedná se mi o to, že když ho dám do šablony nic se nedeje a kod se vypíše jako text.. Proto jsem kod dal do pressenteru. Kam tedy kopírovat ukázky kodů? Do šablon ?
Ideálně nekopírovat, ale jen na něj kouknout a napsat ho sám. Dříve si
zapamatuješ API. Do šablony se kopírují šablony a PHP kód se kopíruje
většinou do presenterů, nebo vlastních tříd, které vhodně umístíš
v adresáři app/
(třeba do
app/models/NejakaTrida.php
).
Snažil jsem se rozchodit validaci:
protected function createComponentForm()
{
$form = new Nette\Application\UI\Form;
$form->addText('name', 'Name:')
->addRule(Form::FILLED, 'Zadejte jméno');
$form->addText('email', 'Email:')
->addRule(Form::EMAIL, 'Zadejte email');
$form->addTextarea('note', 'Note:')
->addRule(Form::FILLED, 'Vyplňte poznámku!');
$form->addSubmit('send', 'Odeslat');
$form->onSuccess[] = callback($this, 'signInFormSubmitted');
return $form;
}
Samozřejmě, laděnka mi píše že class "Form ",takžeje potřeba jí vytvořit nebo vložit?
Tuhle větu se nebudu snažit pochopit.
Vím že se tam nemá psát Nette\Forms\Form ale Nette\Application\UI\Form, když je to v presenteru.
Vidíš, aspoň něco :)
Stejně tak nevím jak vložit javascript validaci :\
Nijak, ty pravidla Nette uloží k formulářovým prvkům samo. Ty musíš
jenom do hlavičky layoutu nakopírovat „přilinkování“ javascriptu,
který je bude kontrolovat. Hledej nette.forms.js
.
Dále bych rád pokračoval s odesláním na mejl, takže pokud doplním
Odeslání na „mejl“ se dělá pomocí Nette\Mail\Message.
<?php $form->onSubmitted[] = 'FormSubmitted'; ?>
A pak vytvořím komponentu Formsubmitted bude to dobře, ano?
Rozhodně to nebude dobře, dobře to bylo předtím. Tohle není žádná komponenta, ale callback, který se má zavolat, pokud je formulář odeslán validně.
Takže opravit na
$form->onSuccess[] = callback($this, 'signInFormSubmitted');
A do téhle metody presenteru
public function signInFormSubmitted($form) { ...
si pak vložíš svoje zpracování, nebo odesílání na email, podle dokumentace.
Příště, až budeš psát příspěvek na fórum, tak než klikneš na tlačítko odeslat, běž ještě jednou se podívat na kód a po řádku ho projdi. Protože mi to přijde, že jsi zkopírovat pár věcí z dokumentace, slepil je dohromady a divíš se, že to nefunguje.
- ZAJDAN
- Člen | 45
tak nettíci tady si lámu hlavu i já…nastala chvíle kdy potřebuju
vytvořit formulář a vykreslit v šabloně ovšem něco je špatně.
vytvořili jsme si presenter Registration.Presenter.php
<?php
use Nette\Forms\Form;
class RegistrationPresenter extends BasePresenter {
public function renderDefault() {
$template->signInForm = $this->createComponentSignInForm();
if(!Nette\Environment::isProduction()) {
$this->stubData();
}
}
protected function createComponentSignInForm() {
$form = new Form;
$form->setAction('/submit.php');
$form->setMethod('GET');
$form->addText('name', 'Jméno:');
$form->addText('adresse','adresa:');
$regions = array(
'1' => 'Jihočeský',
'2' => 'Jihomoravský',
'3' => 'Karlovarský',
);
$form->addSelect('regions','Kraj:', $regions)
->setPrompt('Zvolte Kraj');
$form->addText('city','Město:');
$form->addText('email','email:');
$form->addText('phone1','Telefon č.1:');
$form->addText('phone2','Telefon č.2:');
$form->addText('web','WWW:');
return $form;
}
public function signInFormSubmitted($form)
{
// po odeslání formuláře
}
public function addService($name, $service) {
}
public function hasService($name) {
}
public function removeService($name) {
}
/**
* Stub data for development purpose only.
*/
public function stubData() {
}
}
?>
dále jsme si vytvořili šablonu \templates\Registration\default.latte
{form form}
<table>
<tr class="required">
<th>{label name /}</th>
<td>{input name}</td>
</tr>
...
</table>
{/form form}
ovšem dostávám hlášku:
reating default object from empty value
kde mu vadí na řádku 11
11: $template->signInForm = $this->createComponentSignInForm();
a tady si nejsem jistý, zda takto je to správně – renderovat form do
šablony
Editoval ZAJDAN (3. 3. 2012 16:05)
- Jan Endel
- Člen | 1016
Nevím kde začít první, ale zkusím to od vrchu dolů:
- takhle se továrnička nevolá v renderDefault rozhodně nevolá
- Environment je fujík, použij raději:
if ($this->context->parameters['productionMode'] === false)
- Sign In je přihlašovací formulář, Sign Up je registrační
- Formuláři nedáváme v Nette presenterech akci takto, ale přidáme mu callback:
$form->onSuccess[] = callback($this, 'signInFormSubmitted');
- Pokud už to je tedy registrační formulář, doporučuju prvkům přidat "validační pravidla"https://doc.nette.org/cs/forms#toc-validace :
$form->addText('name', 'Jméno:')
->setRequired('Zadejte prosím své jméno.');
- Předpokládám, že používáš Netbeans 7.1, je v nich u Nette takový malý bug, že podtrhuje červeně název třídy i když je správně (protože mu prý chybí implementace metod z IContainer). Takže klidně metody addService, hasService a remoteService odmaž.
- Formulář, pokud se budeš držet mého postupu vygeneruješ v šabloně takto:
{form signInForm}
{*rozepsani formulare *}
{/form}
- Není potřeba v koncové značce
{/form}
psát název formuláře - Aby si nemusel generovat prvky jeden po druhém, můžeš použít tuhle jednoduchou šablonu:
{form signInForm}
<ul class="errors" n:if="$form->hasErrors()">
<li n:foreach="$form->errors as $error">{!$error}</li>
</ul>
<table>
{foreach $form->components as $component}
{if $iterator->isLast()}
<tr>
<td colspan="2">Položky označené <span style="color:red;">*</span> jsou povinné.</td>
</tr>
{/if}
{if (!($component instanceof \Nette\Forms\Controls\HiddenField)) && (!($component instanceof \Nette\Forms\Controls\SubmitButton))}
<tr>
<th style="text-align: right;">{label $component->name /}:{if $component->isRequired()}<span style="color:red;">*</span>{/if}</th>
<td>{input $component->name}</td>
</tr>
{/if}
{if ($component instanceof \Nette\Forms\Controls\SubmitButton)}
<tr>
<td colspan="2" style="text-align: center">{input $component->name}</td>
</tr>
{/if}
{/foreach}
</table>
{/form}
*) Poznámka: HiddenField se automaticky vykreslí před
makrem {/form}
Editoval pilec (3. 3. 2012 18:31)
- ZAJDAN
- Člen | 45
díky
a co použít tento postup, který mi funguje ale zlobí mě, že se mi nedaří
render poslat do příslušné šablony.
mám presenter:
app/presenters/RegistrationPresenter.php
use Nette\Forms\Form;
class RegistrationPresenter extends BasePresenter {
public function renderDefault() {
$this->template->setFile(__DIR__ . '/default.latte' );
$this->template->render();
/* $template->signInForm = $this->createComponentSignInForm(); */
if ($this->context->parameters['productionMode'] === false) {
$this->stubData();
}
}
protected function createComponentForm() {
$form = new Form;
.....
a šablonu v templates/Registration/default.latte
{block #content}
<div class="bodyForm">
{control form}
</div>
{/block}
problém je že render to vyrendruje pouze pokud je default.latte umístěno
app/presenters/
jenže já chci aby render použil /templates/Registration/default.latte
Editoval ZAJDAN (3. 3. 2012 19:30)
- ZAJDAN
- Člen | 45
pilec napsal(a):
smaž řádek se setFile.
tim jsem dostaval vystup:
Template file name was not specified
*15: $this->template->render(); *
ted mi pekne fachci jak jsi mi doporucil:
public function renderDefault() {
$form->onSuccess[] = callback($this, 'FormSubmitted');
if ($this->context->parameters['productionMode'] === false) {
$this->stubData();
}
}
protected function createComponentForm() {
$form = new Form;
jen s tim rozdilem ze v sablone to vpustim:
{block #content}
<div class="bodyForm">
{control form}
</div>
{/block}
a fachci to pekne
Editoval ZAJDAN (4. 3. 2012 1:27)
- Jan Endel
- Člen | 1016
to ti nemůže fungovat, řádek s:
$form->onSuccess[] = callback($this, 'FormSubmitted');
musí být v metodě createComponent, poněvadž $form je proměnná lokální k té metodě.
a v presenteru v renderech nemusíš psát
$this->template->render();
o to se stará Nette.
Editoval pilec (4. 3. 2012 2:04)
- ZAJDAN
- Člen | 45
zvláštní, pač to fungovalo i tak , ale máš pravdu…nějak jsem to
přehlédl.
Nýní je to přesunuto kam to patří.
Teď bych měl otázku jakým způsobem ten formulář rozdělit na bloky tak
abych každý blok měl v jiné třídě. Jde mi o stylování
pomocí css.
Editoval ZAJDAN (4. 3. 2012 16:25)
- ViPEr*CZ*
- Člen | 817
To se nesmí form vykresilt takhle {control form}, ale musíš si udělat
vlastní vykreslení.
https://doc.nette.org/cs/forms#…
- ZAJDAN
- Člen | 45
ViPErCZ napsal(a):
To se nesmí form vykresilt takhle {control form}, ale musíš si udělat vlastní vykreslení.
https://doc.nette.org/cs/forms#…
takže bych měl stávající callback:
$form->onSuccess[] = callback($this, 'FormSubmitted');
nahradit za:
$form->render
?
- ZAJDAN
- Člen | 45
ViPErCZ napsal(a):
Ne ne todle $form->onSuccess[] = callback($this, ‚FormSubmitted‘); je nejspíš na dobrým místě předpokládám a navíc jde o akci submittu… to nemá s css nic společného. Myslel jsem šablonu předělat.
někde se přece musí říct, že se bude renderovat manuálně a to tedy
řeší jen změna zápisu v latte?
z {control Form} na {form Form} ?
- ZAJDAN
- Člen | 45
ViPErCZ napsal(a):
Jo, prostuduj si tu dokumentaci co jsem poslal link… tam to je hezky ukázané. Každopádně pokud chceš stylovat, dá se použít i to co máš. Každý element má svoje IDéčko, takže to jde ostylovat i tak jednoduše.
mě jde spíše o to, aby se formulář zavřel do jednoho generálního divu, což řeším v latte šabloně. Ale uvnitře tohodle divu udělat ještě další divy a do ni vpouštět jednolivé bloky formuláře. Tím bych pak mohl jednotlivým divům nastavit různé pozadí atd.
- ViPEr*CZ*
- Člen | 817
ZAJDAN napsal(a):
ViPErCZ napsal(a):
Jo, prostuduj si tu dokumentaci co jsem poslal link… tam to je hezky ukázané. Každopádně pokud chceš stylovat, dá se použít i to co máš. Každý element má svoje IDéčko, takže to jde ostylovat i tak jednoduše.
mě jde spíše o to, aby se formulář zavřel do jednoho generálního divu, což řeším v latte šabloně. Ale uvnitře tohodle divu udělat ještě další divy a do ni vpouštět jednolivé bloky formuláře. Tím bych pak mohl jednotlivým divům nastavit různé pozadí atd.
Jasný pak viz. dokumentace.
{form form}
{control $form errors}
<div id="mujdiv">{form['jmeno']->label}{form['jmeno']->control}</div>
{/form form}
- ZAJDAN
- Člen | 45
ViPErCZ napsal(a):
První form je tuším název makra a druhý form je název komponenty. Tj. mohlo by tam místo toho být např.:
{form loginForm}
vypadá to, že je tomu tak {form nazevKomponenty}
ovšem v mém případě to komponentu s použitím tohoto makra hledá jinde
než bych chtěl a nemůže ji najít
dostávám výstup:
Component with name ‚RegForm‘ does not exist.
já tu komponentu vytvářím v presenteru
/presenters/RegistrationPresenter
protected function createComponentRegForm() {
$form = new Form;
.........
- ZAJDAN
- Člen | 45
tak po pár změnách jsem dosáhl žádaného vysledku:
latte vypadá takto (zatím):
{block #content}
{form regForm}
<div class="bodyForm">
{control regForm}
<div id="Form1">{$form['name']->label}{$form['name']->control}</div>
</div>
<div class="fotoContainer">
<div id="Form2">{$form['avatar']->label}{$form['avatar']->control}</div>
</div>
{/form regForm}
{/block}
Editoval ZAJDAN (5. 3. 2012 0:42)
- ViPEr*CZ*
- Člen | 817
Třída Form umí kontejnerovat: https://doc.nette.org/cs/forms#…
Dále {control regForm} v tom bloku bude nějaký divoký. A id=„Form1“ je
tam 2×, což není také dobře.
- ZAJDAN
- Člen | 45
ViPErCZ napsal(a):
Třída Form umí kontejnerovat: https://doc.nette.org/cs/forms#…
Dále {control regForm} v tom bloku bude nějaký divoký. A id=„Form1“ je tam 2×, což není také dobře.
jasně to dvojí ID vím… to bylo ihned po nakopírování -ale to je samozřejmost…i tak díky
a to seskupování – grupování to je přesně ono to se mi
líbí…díky
co by mě ale zajímalo jak se v šabloně odkážu na konkrétní Group
Editoval ZAJDAN (4. 3. 2012 21:12)