Odeslání formuláře s animací
- akadlec
- Člen | 1326
No tak to potom seš ale na špatném fóru. To co ty chceš (pokud sem tě pochopil dobře) je animace pro zobrazení formuláře a o to se stará JS a né Nette či nette.ajax.js
Musíš si nastudovat něco o jQuery a slide pokud to chceš dělat pomocí něho
- Xantes
- Člen | 28
Po jQuery vím, co chci. Jde mi spíše o to, že normálně bez nette bych napsal něco jako:
$('#addCommentForm').submit(function(e) {
e.preventDefault();
$.post('ajax.php', $(this).serialize(), function(msg) {
$(msg.comment).insertBefore('#addCommentForm').hide().slideDown();
...
});
Ale nevím, jak na to za pomocí nette.ajax.js. Samozřejmě mi to ajaxově funguje, ale bez toho efektu. Formulář má jen classu ajax a nic podobného, jako kód výše není, tak nevím, kam dopsat ten efekt.
Může mě někdo nasměrovat?
- Vojtěch Dobeš
- Gold Partner | 1316
Dokonce se to dá zjednodušit:
$('#addCommentForm').submit(function(e) {
$(this).netteAjax(e).done(function(msg) {
$(msg.comment).insertBefore('#addCommentForm').hide().slideDown();
...
});
});
Editoval Vojtěch Dobeš (21. 4. 2015 10:52)
- Vojtěch Dobeš
- Gold Partner | 1316
A uděláš dobře, když na ten formulář CSS třídu ajax
nedáš, právě poněvadž si jeho odeslání obsluhuješ a ajaxuješ
po svém.
- one-two
- Člen | 80
Vojtěch Dobeš napsal(a):
Dokonce se to dá zjednodušit:
$('#addCommentForm').submit(function(e) { $(this).netteAjax(e).done(function(msg) { $(msg.comment).insertBefore('#addCommentForm').hide().slideDown(); ... }); });
nechceš hodit tohle do dokumentace na github? zrovna nedávno sem to řešil a poměrně dlouho sem se s tim patlal, než sem přišel na to, že to stačí takhle jednoduše :)
- Xantes
- Člen | 28
Děkuji oběma. Stále mi však něco uniká.
V presenteru mám po odeslání formu něco takového:
if ($this->isAjax()) {
$this->redrawControl('comments');
} else {
$this->redirect('this');
}
v šabloně:
{snippet comments}
{foreach $comments as $comment}
...
{/foreach}
{/snippet}
a js nyní tedy:
$('#addCommentForm').on('submit', function(e) {
e.preventDefault();
$.nette.ajax({
url: $(this).prop('action'),
data: $(this).serialize(),
success: function(msg) { // jak tady do msg dostanu ten komentář?
console.log(msg.comment);
$(msg.comment).insertBefore('#addCommentForm').hide().slideDown();
}
});
})
Ptám se asi hloupě, ale v javascriptu jsem začátečník a do teď jsem
ajax v nette používat tak, že jsem přidal class=„ajax“ a fungovalo to.
Bez nette jsem to měl vyřešeno, ale s ním si nevím rady.
Navíc, i kdyby se mi podařilo komentář dostat a zanimovat, jak chci, tak
už je stejně pozdě, protože redrawControl(‚comments‘) už to
překreslil, ne?
Mohl by mi to někdo objasnit?
- Vojtěch Dobeš
- Gold Partner | 1316
- První argument callbacku v property
success
(anebo callbacku předaného dodone
metody, což je modernější a doporučovaný způsob) je body, které přišlo ze serveru. Pokud to je JSON, tak je to rovnou javascriptový objekt. Říkejme mu pro jednotnost termínů payload. - Metoda
redrawControl
vyvolá překreslení daného snippetu, ale to neznamená, že by něco provedla v prohlížeči. Jediné, co zajistí, je, že v objektu payload bude objektsnippets
, kde pod klíčem (který generuje Nette a bude se rovnat přibližně stringusnippet--comments
) najdeš HTML toho překresleného snippetu. nette.ajax.js
má defaultně zapnutou extenzi, která se příznačně jmenujesnippets
. Ta se dívá dopayload.snippets
, celé to prosviští foreachem, podle klíčů najde odpovídající elementy snippetů (každý snippet má tosnippet--comments
aj. jako HTML atributid
) a jejich obsah nahradí tím novým HTML.
Pokud dobře chápu tvůj záměr, snažíš se Ajaxem načítat nové komentáře a chceš, aby se ty nové přidaly k již existujícím a objevily se slide animací.
Jak na to? Udělal bych to takto. Zaprvé, po přidání komentáře si do
šablony do pole $comments
dej jen ten nový komentář, jinak
následující kód nebude fungovat.
<div n:snippet="comments" data-ajax-snippet-behavior="prependAndSlide"> {* dám si na element snippetu svůj custom data atribut *}
{foreach $comments as $comment}
<div class="comment">
...
</div>
{/foreach}
</div>
var snippetsExtension = $.nette.ext('snippets'); // vytáhnu si extenzi pro její nakonfigurování
var originalApplySnippet = snippetsExtension.applySnippet;
snippetsExtension.applySnippet = function ($el, html, back) {
var behavior = $el.date('ajax-snippet-behavior');
if (behavior && this.behaviors[behavior]) {
this.behaviors[behavior]($el, html, back);
} else {
originalApplySnippet($el, html, back);
}
};
snippetsExtension.behaviors = {};
snippetsExtension.behaviors['prependAndSlide'] = function ($el, html, back) {
var $comment = $(html);
$comment.hide();
$el.prepend($comment);
$comment.slideDown();
};
- Xantes
- Člen | 28
@VojtěchDobeš díky za objasnění, i když je na mě ten js kód trochu složitý.
Nakonec jsem to vyřešil tak, že jsem $this->redrawControl(‚comments‘) vůbec nepoužil, místo toho jsem si ten komentář poslal přes $this->payload->comment a odchytil jsem si ho v tom callbacku success property. Takže výše můj js zdroják jsem jen minimálně upravil a fungovalo to, akorát jsem narazil, že jsem v poslaném komentáři potřeboval latte, tak jsem nakonec místo payload, odeslal šablonu
if ($this->isAjax()) {
$this->template->setFile('comment.latte');
akorát nevím, zda je to správné, čisté řešení?