Ajax v action metodě, nevykreslovat šablonu, jen překreslit snippet

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

Zdravím, jak zařídit, aby metoda action nevykreslila celou šablonu, ale překreslila jen jeden snippet?

public function actionDetail($id, $edit=NULL) {

   $this->template->product = $this->repository->table('products')->get($id);
   $this->template->edit = $edit;

   if ($edit)
      { //přidat pole do editačního formuláře:
          $this['editForm']->addText($edit, $edit);
      }

// jak udělat něco jako toto (jen naznačení toho, co bych chtěl udělat):
   if($edit AND $this->ajax) {
       // když známe jméno snippetu a jde o ajax, překreslit jen ten snippet, ne celou stránku
       $this->redrawControl($edit);
      }
      else
        {
           //normálně vykreslit všechno
        }
}

šablona:

{snippet item}
   {if $edit == 'item'}
      {control editForm}
   {else}{$p->item}{/if}
     <a n:href="this edit => 'item'" class='ajax'></a>
{/snippet}

Metoda action modifikuje editační formulář. Chtěl bych, aby se objevil pomocí ajaxu.
Díky.

Editoval ludek (21. 5. 2015 12:20)

David Matějka
Moderator | 6445
+
0
-

a co to udela ted?

  • mas nainstalovany nette.ajax.js?
  • odesle se pozadavek ajaxove?
  • prijde odpoved? jaka?
ludek
Člen | 83
+
0
-

David Matějka napsal(a):
a co to udela ted?

Teď to nedělá nic. Kliknu, udělá se get požadavek, nic se nepřekreslí a odezva je {"state":[]}.

Ajax mi jinde (na handlerech) normálně funguje. Všechno je funkční bez ajaxu. Jde o to, že nevím co vůbec napsat, aby to udělalo, co chci.

David Matějka
Moderator | 6445
+
0
-

chybu tam zadnou nevidim…

  • Nemas tam nejakou specialitu, kterou zatajujes? :)
  • jak tam mas ten komentar //normálně vykreslit všechno tak tam asi nedelas nic specialniho, ne?
  • ta sablona je normalni sablona presenteru pro tu akci?
  • zkus si to odkrokovat, nebo aspon poslat nejaky debug info (treba firelog, nebo to aspon dat do payloadu $this->payload->foo = $bar), treba u toho radku redrawControl, jestli se to tam dostane a co se prekresluje…
ludek
Člen | 83
+
0
-

David Matějka napsal(a):
chybu tam zadnou nevidim…

  • Nemas tam nejakou specialitu, kterou zatajujes? :)

To je nedorozumění, špatně se ptám. Ten kód tam vůbec nemám, chtěl jsem jen naznačit, co bych chtěl napsat, ale nevím jak. (Radši to v původním dotazu nějak opravím).

Otázka zní: jak to udělat, aby action v závislosti na parametru jednou vykreslila celou šablonu a jindy jen překreslila jeden snippet?

David Matějka
Moderator | 6445
+
0
-

@ludek tak, jak mas ten kod, by to melo fungovat

ludek
Člen | 83
+
0
-

V tom případě by na konec action stačilo napsat

if($this->ajax) { $this->redrawControl('jmeno_snippetu'); }

a bylo by to. Ale to bohužel nefunguje.

Po kliknutí na ajaxový odkaz se provede normální get požadavek se správným Content-Type application/json, ale nepřijde na něj žádná odpověď. Resp. přijde jen {"state":[]}, přičemž by mělo přijít {"state":[],"snippets":{"snippet--jmeno_snippetu":" .... Když odstraním class='ajax' z odkazu, všechno normálně funguje (samozřejmě s tím, že se obnoví celá stránka).

ludek
Člen | 83
+
0
-

Tak ono to jde, ale ne s jednotlivými dynamicky pojmenovanými snippety. Pokud na konec action napíšu prázdné

if($this->ajax) { $this->redrawControl(); }

nebo

if($this->ajax) { $this->redrawControl('itemsContainer'); }
// itemsContainer je statický snippet, který obaluje všechny dynamické

a zavolám to z ajaxového odkazu

<a n:href="this edit => 'item'" class='ajax'>tohle edituj</a>

Ajax zafunguje, ale vrátí se všechny snippety najednou. S dynamicky pojmenovanými snippety to nefunguje. (Nette 2.3.2)

dokumentaci jsem našel: Dynamické snippety nelze invalidovat přímo (invalidace item-1 neudělá vůbec nic), musíte invalidovat jim nadřazený statický snippet (zde snippet itemsContainer).