Nefunguje Simple ajax example

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
aum
Člen | 12
+
0
-

Zdravím a prosím o radu.
Zkusil jsem příklad Simple ajax example (https://doc.nette.org/…ication/ajax). Pomocí Composeru jsem vytvořil nový Sandbox-projekt, do www/js doplnil nette.ajax.js z GitHub, přidal <script src=„{$basePath}/js/nette.ajax.js“></script> do @layout.latte a inicializaci do main.js.
Upravil HomepagePresenter.php a default.latte podle návodu.
Po clicku na „Change variable!“ se „default value“ změní na „changed value via ajax“, ale ne prostřednictvím ajaxu. Zavolá se handleChangeVariable(), ale podmínka if ($this->isAjax()) je FALSE.
Co může být špatně a jak to hledat?
Předem díky.

Oli
Člen | 1215
+
0
-

Udělal jsi to přesně stejně jako je v tom návodu? Napadají mě možnosti, co se mohlo stát:

  1. zapomněl jsi na class="ajax"
  2. chyba v js. Podívej se do console

Je ale možný že to je i v něčem jiným…

aum
Člen | 12
+
0
-

Ano je to přesně zkopírované z návodu. Console je prázdná. class=„ajax“ tam je, ale chová se to stejně jako když tam není. Nette je 2.4, knihovny aktuální.

aum
Člen | 12
+
0
-

Zjistil jsem, že to souvisí se šablonami. V @layout.latte mám:

{**
 * @param string   $basePath web base path
 * @param array    $flashes  flash messages
 *}
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">

	<title>{ifset title}{include title|stripHtml} | {/ifset}Nette Sandbox</title>

	<link rel="stylesheet" href="{$basePath}/css/style.css">
	<meta name="viewport" content="width=device-width">
	{block head}{/block}
</head>

<body>
	<div n:foreach="$flashes as $flash" n:class="flash, $flash->type">{$flash->message}</div>

	{include content}

	{block scripts}
	<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
	<script src="https://nette.github.io/resources/js/netteForms.min.js"></script>
	<script src="{$basePath}/js/nette.ajax.js"></script>
	<script src="{$basePath}/js/main.js"></script>
	{/block}
</body>
</html>

Pokud je v default.latte jen:

<div>
    {snippet ajaxChange}
        {$anyVariable}
    {/snippet}

    <a n:href="changeVariable!" class="ajax">Change variable!</a>
</div>

vůbec neproběhne {block scripts} z @layout.latte.
Pokud default.latte upravím:

{block content}
<div>
    {snippet ajaxChange}
        {$anyVariable}
    {/snippet}

    <a n:href="changeVariable!" class="ajax">Change variable!</a>
</div>
{/block}

{block scripts}
{include parent}
{/block}

{block scripts} z @layout.latte proběhne, ajax se zavolá, ale objeví se chyba
„NetworkError: 500 Internal Server Error – http://localhost/ajax3/www/?…“ – Possible problem: you are sending a HTTP header while already having some data in output buffer. Try Tracy\OutputDebugger or start session earlier.

Jak správně propojit @layout.latte a default.latte?

Editoval aum (19. 10. 2016 15:57)

CZechBoY
Člen | 3608
+
0
-

@aum je možný používat syntax zvýrazňovače na foru? /--latte\--

aum
Člen | 12
+
0
-

Nerozumím.

jiri.pudil
Nette Blogger | 1032
+
+1
-

@aum @CZechBoY tě chtěl požádat, abys zdrojové kódy na fóru zapisoval tak, aby se daly pohodlně číst – zvýšíš tím šanci, že ti někdo poradí :)

aum
Člen | 12
+
0
-

Opraveno. Díky.
Tedy to formátování příspěvku.
Ajax stále nefunguje.

Editoval aum (19. 10. 2016 22:01)

premek_k
Člen | 172
+
0
-

A když to default.latte napíšeš takto?

{block content}
<div>
    {snippet ajaxChange}
        {$anyVariable}
    {/snippet}

    <a n:href="changeVariable!" class="ajax">Change variable!</a>
</div>
{/block}
aum
Člen | 12
+
0
-

Pak ajax nejde protože se nenačtou a neinicializují knihovny z {block scripts} v @layout.latte.

Jak spolu @layout.latte a default.latte souvisí? Jak sjou spolu provázané?

Jan Mikeš
Člen | 771
+
0
-

Pokud nemáš v šabloně uvedeno {extends none} tak hledá svůj „layout“ a to v tomto pořadí: https://api.nette.org/…ter.php.html#…
Zjednodušeně v praxi to znamená, že hledá toto: Presenter.@layout.latte @layout.latte ve stejném adresáři, o adresář výše atd… (více ti řekne ten zdrojový kód).

Pokud tuto funkci nepřepisuješ, nebo nepoužíváš makro {extends} nebo {layout} nemusíš se tedy o propojení s @layout.latte starat, protože proběhne automaticky.

Proto si v šabloně default.latte definuješ {block content} ten se totiž vloží na příslušné místo právě do @layout.latte a to {include content}

Určitě bych doporučil přečíst si o dědičnosti šablon více v dokumentaci: https://latte.nette.org/cs/tags#…

Ujisti se, že si v default.latte nepřepisuješ {block scripts}, nebo že v něm voláš {include parent}.

Já js řeším tak, že knihovny, které potřebuji všude mám mimo block a pod nimi mám prázdný {block js}{/block} který právě čeká na naplnění z potomků layoutu.

Editoval Lexi (20. 10. 2016 0:19)

premek_k
Člen | 172
+
0
-

Opravdu jsi to zkusil a nejede?

V default.latte definuješ blok „content“, který se vloží do @layout.latte do místa {include content}

Edit: @Lexi byl rychlejší…

Editoval premek_k (20. 10. 2016 0:22)

aum
Člen | 12
+
0
-

@premek_k: Promiň, už jsem zkoušel mnoho variant a zmýlil jsem se. Ajax v tvém řešení jede ale objeví se ta chyba “NetworkError: 500 Internal Server Error – http://localhost/ajax3/www/…” – Possible problem: you are sending a HTTP header while already having some data in output buffer. Try Tracy\OutputDebugger or start session earlier.

@Lexi: Dík, takhle nějak jsem si to myslel. Nerozumím ale tomu, proč když v default.latte nemám <div> blok obalený {block content}em, knihovny v @layout.latte se nanačtou.

Jan Mikeš
Člen | 771
+
0
-

@aum měl by jsi veškerý svůj kód strukturovat do blocků, pokud tak neučiníš a tvá šablona začíná přímo HTML kódem, o tuto dědičnost přijdeš a neextenduje se @layout.latte ale využívá se pouze šablona, ve tvém případě default.latte (Narozdíl od layoutů, ty mohou začínat přímo HTML kódem. Layout poznáš tak, že zpravidla v názvu souboru je použit zavináč, pokud budeš ale moc chtít, tak i tato jmenná konvence se dá změnit.)
Co se týká chyby s brzkým odesláním HTTP headeru: nevypisuješ někde něco v php pomocí echo nebo jiné funkce?

Doporučuji vyzkoušet taktéž v config.neon startovat session dříve pomocí:

session:
    autoStart: true # výchozí hodnota je 'smart'

Pokud by jsi byl úplně v koncích, zkus řešení uvedené na https://phpfashion.com/…-nette-2-2-3

A do pětice všeho dobrého: při vývoji můžete narazit na upozornění Possible problem: you are sending a HTTP header while already having some data in output buffer. Try OutputDebugger or start session earlier. To se objeví, když se snažíte odeslat HTTP hlavičky, a ono to sice ještě jde, nicméně aplikace už nějaký výstup předtím odeslala, jen ho zachytil output buffer. V takové situaci je nejlepší nastartovat OutputDebugger a zjistit, odkud se výstup posílal a předejít tomu. Od verze 2.2.3 máte také možnost toto dobře míněné upozornění potlačit pomocí proměnné Nette\Http\Response::$warnOnBuffer. Třeba opět z bootstrapu:

$container->getByType('Nette\Http\Response')->warnOnBuffer = FALSE;

Z praxe ale vím, že programátoři jsou lidé zvídaví a jsou 2 stavy, které je nenechávají klidným:

  1. Něco mi nefunguje a nevím proč
  2. Něco mi funguje a nevím proč :-)

Editoval Lexi (20. 10. 2016 5:18)

premek_k
Člen | 172
+
0
-

Co se týká chyby s brzkým odesláním HTTP headeru: nevypisuješ někde něco v php pomocí echo nebo jiné funkce?

Přesně tak- pokud tam máš nějaké ladící dumpy, tak odstranit. Problém může dělat i notice nebo jiná chyba, která vypadne ze serveru. Jednoduše to odhalíš v konzoli chromu na záložce „síť“, když se podíváš na response toho volání. Musí tam být jen čistý json. Ty tam před ním budeš mít něco „navíc“.

aum
Člen | 12
+
0
-

Bylo to tak. Měl jsem tam zapomenutý ladicí dump. Už to funguje. Děkuji všem za pomoc.

redbulliik
Člen | 3
+
0
-

Ahoj, mám raké problém zprovoznit příklad https://doc.nette.org/…ication/ajax
Nad snippet input type text, a po kliknutí na change variable se mi reloaduje celá stránka.
podmínka:

<?php
		if ($this->isAjax()) {
            $this->redrawControl('ajaxChange');
        }
?>

je negativní, ale i když odstranim podmínku a enchám pouze redraw, tak se mi reloaduje celá stránka.
sandndbox jsem stahl z https://nette.org/cs/packages a nette.ajax.js z : https://github.com/…ette.ajax.js
(zkopírovaný kod z náhledu souboru).
Má někdo tento příklad odskoušený? Se snippety začínám a nevím si stím rady.
Kód je přesně zkopírovaný z návodu a postupoval jsem tam, abych nic nezapoměl a nefunguje mi to, jak má.
Děkuji za každou pomoc.