Ajax – Zmena formulare po odesilani pozadavku
- Piticu
- Člen | 93
Ahoj,
uz nekolik hodin se snazim davat dohromady Ajax,Zmena formulare a Snippet(predpokladam ze tohle potrebuji pro zmenu formulare). Vubec se nedari aspon trochu prekreslovat okno.
answerSecurityQuestionForm.latte
<form n:name="answerSecuriyQuestionForm">
....
</form>
sendPasswordLinkForm.latte
<script>
window.onload = function () {
$('#submit').click(function (e) {
$.ajax({
type: "POST",
url: {link checkEmail!},
data: { email: $('#email').val()},
success: function (data) {
alert('OK');
},
error: function (textStatus, errorThrown) {
alert('BAD');
}
});
});
}
</script>
<form n:name="sendPasswordLinkForm">
....
</form>
reset.latte – hlavni soubor pro obnoveni hesla
{block title}Obnovení hesla{/block}
{block content}
.....
{if $presenter->getParameter('token') && $presenter->getParameter('email')}
{include 'resetPasswordForm.latte'} //TOHLE NENI NIJAK PODSTATNE
{else}
{include 'sendPasswordLinkForm.latte'}
{/if}
......
{/block}
AccountPresenter
class AccountPresenter extends BasePresenter
{
public function handleCheckEmail(){
if($this->isAjax()){
//pokud zadana emailova adresa existuje
//nejak kouzelne smaz aktualni formular a zobraz formular answerSecuritQuestionForm.latte
}
}
}
Rozdelil jsem formulare do vice latte souboru, ale nemam problem je dat
dohromady, pokud bude fungovat prepinani formularu.
V podstate sendPasswordLinkForm.latte obsahuje formular, kde
uzivatel zadava email sveho uctu.
Pokud takovy email existuje,tak chci aby aktualni formular zmizel a misto neho, aby byl answerSecuriyQuestionForm, ktery obsahuje bezpecnostni otazku a odpoved, ktere patri k uctu se zadanym emailem.
Jak teda na to?
Zkusil jsem neco ve smyslu:
$this->template->setFile(__DIR__ . '/../templates/Account/answerSecurityQuestionForm.latte');
$this->template->render();
nebo redrawControl ruznymi zpusoby, ale bez sance. Nevim jak na to.
Dekuji vam.
Editoval Piticu (30. 1. 2018 2:13)
- Ondřej Kubíček
- Člen | 494
a navíc když si to takhle řešíš sám a nepoužíváš třeba nette.ajax.js, takže si musíš ten snippet sám překreslit v successu potom co ti ze serveru přijde payload s novou šablonou
- Piticu
- Člen | 93
Tak udelal jsem teda par zmen, ale porad delam neco spatne. Je to poprve kdyz pracuji s ajaxem a snippety a moc mi to nejde no :D
AccountPresenter
public function handleCheckEmail(){
$this->redrawControl('resetPassword');
}
reset.latte
{snippetArea resetPassword}
{if $presenter->isAjax()}}
{include 'aswerSecurityQuestionForm.latte'}
{else}
{include 'sendPasswordLinkForm.latte'}
{/if}
{/snippetArea}
sendpasswordLinkForm.latte
//formular pro zadani emailove adresy
<a n:href="checkEmail!" class="ajax">Submit</a>
Ajax pozadavek se odesle, ale porad stejny formular. Jdu na to dobre? Nebo spis zase mam tam nesmysly?
- Šaman
- Člen | 2666
SnippetArea
se nepřekresluje, ta slouží ke složitější
práci se snippety. Pro začátek zkus:
- Obyčejnou šablonu, v ní mít snippet (bez
snippetArea
) - přilinkovat a inicializovat
nette.ajax.js
(a pozor, pro určitou práci s formuláři je potřeba mít inette.forms.js
, jinak ten ajax nefunguje – je tam nezdokumentovaná závislost.) - Překreslit snippet z handleru presenteru.
Až tohle bude fungovat, můžeš to zkoušet zesložiťovat.
- Piticu
- Člen | 93
Šaman napsal(a):
SnippetArea
se nepřekresluje, ta slouží ke složitější práci se snippety. Pro začátek zkus:
- Obyčejnou šablonu, v ní mít snippet (bez
snippetArea
)- přilinkovat a inicializovat
nette.ajax.js
(a pozor, pro určitou práci s formuláři je potřeba mít inette.forms.js
, jinak ten ajax nefunguje – je tam nezdokumentovaná závislost.)- Překreslit snippet z handleru presenteru.
Až tohle bude fungovat, můžeš to zkoušet zesložiťovat.
Ted jsem zkusil jen nejakej text prekreslovat, ale porad nic. Neco, nekde delam spatne. Takze zatim zbytecne neco nacvicuji s formularem.
public function renderReset(){
$this->template->resetForm = "aaaaaaaaaaaa";
}
public function actionReset($email, $token){}
public function handleCheckEmail(){
if($this->isAjax()){
$this->template->resetForm = "bbbbbbb";
$this->redrawControl('resetPassword');
}
}
{snippet resetPassword}
{$resetForm}
<a n:href="checkEmail!" class="ajax">Submit</a>
{/snippet}
Ocekaval jsem ze po kliknuti na Submit se mi to prepise na bbbb. Zadna zmena. Zatim zkoumam co delam spatne.
- Šaman
- Člen | 2666
Jop, přesně tohle jsem myslel. Ještě si zjisti, jestli vůbec nastane to
$this->isAjax()
(třeba pomocí bdump
). Když ne,
zkontroluj si ty js knihovny. Jakou verzi Nette máš?
Dodatek: Zkus ještě tu renderReset
změnit na
actionReset
. Teď z hlavy nevím, jestli se při překreslení
znovu nenastaví původní hodnota v té render metodě. Já už používám
hlavně komponenty, tam tenhle problém nenastává (a ty se nastavují
z podobných důvodů už v action
).
Editoval Šaman (30. 1. 2018 12:20)
- Piticu
- Člen | 93
Šaman napsal(a):
Jop, přesně tohle jsem myslel. Ještě si zjisti, jestli vůbec nastane to
$this->isAjax()
(třeba pomocíbdump
). Když ne, zkontroluj si ty js knihovny. Jakou verzi Nette máš?
$this->isAjax()
funguje. Ted jsem zkusil tenhle priklad:
https://doc.nette.org/…ication/ajax#…
a vsechno funguje v poradku :). Verze 2.4
- Piticu
- Člen | 93
Šaman napsal(a):
Ještě jsem tam dopsal tu poznámku o
action
arender
. Verze 2.4 je fajn, při ajaxu se ti přidá i debug panel, takže se během ajaxových požadavků dá dumpovat. To dost ulehčuje ladění.
Uz mi funguje prepinani textu. Prepsal jsem renderReset
na
actionReset
. Sice nevim proc to funguje, ale uz jsem udelal krok
dopredu.
Mam jeste k tomu dotaz:
Jak muzu pouzit tuhle sablonu v Presenteru?
<form n:name="sendPasswordLinkForm">
<ul class="alert-message error" n:if="$form->hasErrors()">
<li n:foreach="$form->errors as $error">{$error}</li>
</ul>
<div class="row myborder">
<img src="{$basePath}/img/logo_websitebuilder.png" alt="FastWeb">
<hr>
{snippet flashMessage}
<div n:foreach="$flashes as $flash" class="alert-message {$flash->type}">
<a class="close" data-dismiss="alert">×</a>
<p>{$flash->message}</p>
</div>
{/snippet}
<div class="input-group margin-bottom-20">
<span class="input-group-addon"><i class="glyphicon glyphicon-envelope mycolor"></i></span>
<input id="email" size="60" maxlength="255" class="form-control"
placeholder="Emailová adresa vašeho účtu" n:name="email" type="text">
</div>
<br><br><br><br>
<div class="row">
<div class="col-md-12 text-center">
<button class="btn-u" type="submit" n:name="reset">Obnovit heslo</button>
</div>
</div>
<a n:href="checkEmail!" class="ajax">Submit</a>
<div class="row">
<div class="col-md-12">
<p class="account-already">Pokud ještě nemáte účet, tady si ho <a n:href="signup">vytvoříte.</a></p>
</div>
</div>
<div class="row">
<div class="col-md-12">
<p class="account-already">Pokud už účet máte, stačí se <a n:href="signin">přihlásit.</a></p>
</div>
</div>
</form>
ukaze mi error Unknown attribute n:name in...
. Zkusil jsem
Nette\Bridges\ApplicationLatte\UIMacros::install($latte->getCompiler());
ale bez uspechu :/ Chci ted delat totez co s textem, jenze misto textu budou ty dve sablony.
UPDATE:
$latte = new Latte\Engine;
Nette\Bridges\ApplicationLatte\UIMacros::install($latte->getCompiler());
$this->template->resetForm = $latte->render(__DIR__ . '/../templates/Account/sendPasswordLinkForm.latte');
Takhle to mam prozatim.
Editoval Piticu (30. 1. 2018 12:44)
- Šaman
- Člen | 2666
Tak to bylo tím, že po příkazu k překreslení se opravdu znovu spustí
render, včetně render metody. A ta to přepsala zase na aaaaa
.
Action
nastává ještě před handlery.
Nechápu otázku. V šabloně presenteru přece n:makra fungují. To
zkoušíš samostatné latte, nebo co? Jestli ti jde o includované šablony,
udělej si z nich komponenty. Includované šablony si se snippety moc
nerozumí (ta makra se musí předtím zkompilovat).
Jestli pracuješ s běžnou strukturou projektu, tak žádné ruční instalace
latte nepotřebuješ.
Editoval Šaman (30. 1. 2018 12:47)
- Piticu
- Člen | 93
Šaman napsal(a):
Tak to bylo tím, že po příkazu k překreslení se opravdu znovu spustí render, včetně render metody. A ta to přepsala zase na
aaaaa
. Action nastává ještě před handlery.
Nechápu otázku. V šabloně presenteru přece n:makra fungují. To zkoušíš samostatné latte, nebo co? Jestli ti jde o includované šablony, udělej si z nich komponenty. Includované šablony si se snippety moc nerozumí (ta makra se musí předtím zkompilovat).
V podstate mam 2 formulare, a kazdy ma svuj latte soubor. A muj cil je zobrazit(includovat) jeden a po odeslani AJAX pozadavku, odstranit ten prvni a zobrazit(includovat) druhy.
Zkusim se teda mrknout na komponenty.
Projekt jsem udelal pres composer:
composer create-project nette/web-project myproject
Editoval Piticu (30. 1. 2018 12:53)
- Šaman
- Člen | 2666
Jj, web-project
je dobrý základ. Pak nepotřebuješ žádné
latte bridges, to máš už všechno funkční.
Co potřebuješ je buď hodit ty formuláře do komponenty (vlastní, pokud
potřebuješ to ruční vykreslení), nebo je zatím vykreslovat pomocí
rendereru (pak se s nimi pracuje taky jako s komponentou a vykreslí se
pomocí {control testForm}
). Kdysi jsem includoval šablony, ale
už pár let jsem to nedělal, tak ti neřeknu kde přesně bude problém. Ale
v includovaných šablonách některé složitější možnosti latte
nefungují. (Bude to souviset s tím, že běžná šablona je vlastně nejen
html, ale i kód, který je potřeba zkompilovat. A u snippetů se při tom
vygenerují i funkce pro překreslování jednotlivých bloků apod. Ale
includovat můžeš i za běhu a pak ti tyhle předkompilované části
chybí.)
- Piticu
- Člen | 93
Ja se chtel drzet latte souboru, kvuli te HTML struktry (divs). Tak moje predstava byla, ze to pujde bez problemu :D
Jinak je v Presenteru mam i jako Component
protected function createComponentSendPasswordLinkForm()
{
$form = new Form;
$form->addEmail('email')
->setRequired('Zadejte prosím Email Vašého účtu');
$form->addSubmit('reset','Obnovit');
$form->onSuccess[] = [$this,'sendPasswordLinkFormSucceded'];
return $form;
- Šaman
- Člen | 2666
Tak to zkus nejprve renderovat defaultně
{control sendPasswordLinkForm}
. To si dej do ifů a zkus rozchodit.
Jako poslední pak bude vyčlenit to do komponent a přidat manuální
vykreslení.
Případně to prostě dej oboje manuálně do šablony presenteru. Bez includování.
Jinak koukal jsem, že includování ještě používám, ale jen na vložení menu. Tam nemám nic složitějšího, než pár ifů pro zvýraznění aktuální položky. A řekl bych, že na složité věci to ani není určené. K tomu slouží komponenty (zvlášť, když chceš mít pohromadě kód a šablonu, což je přesně to, co od formulářů chceš).
- Piticu
- Člen | 93
Šaman napsal(a):
Tak to zkus nejprve renderovat defaultně
{control sendPasswordLinkForm}
. To si dej do ifů a zkus rozchodit. Jako poslední pak bude vyčlenit to do komponent a přidat manuální vykreslení.Případně to prostě dej oboje manuálně do šablony presenteru. Bez includování.
Jinak koukal jsem, že includování ještě používám, ale jen na vložení menu. Tam nemám nic složitějšího, než pár ifů pro zvýraznění aktuální položky. A řekl bych, že na složité věci to ani není určené. K tomu slouží komponenty (zvlášť, když chceš mít pohromadě kód a šablonu, což je přesně to, co od formulářů chceš).
No,je to na me uz dost narocne a trochu se v tom ztracim, ale asi zrusim sablony a zkusim prve mit vsechno v jedne sablone hlavni sablone. Hlavni cil je at to jakkoliv funguje :D
Edit: Kouzelnym zpusobem funguje to pomoci if
a
isAjax
.
{snippet resetPassword}
{if $presenter->isAjax()}
<form n:name="answerSecuriyQuestionForm">
//form
</form>
{else}
<form n:name="sendPasswordLinkForm">
//form
</form>
{/if}
<a n:href="checkEmail!" class="ajax">Submit</a>
{/snippet}
Dekuji za pomoc
Editoval Piticu (30. 1. 2018 13:58)