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 dodonemetody, 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
redrawControlvyvolá 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.jsmá 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--commentsaj. 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í?