Naja, sortable, ajax snippety

d@rkWolf
Člen | 167
+
0
-

Zdravím, netušíte, co dělám špatně? @jiripudil ? Do handle se nedostanou data, co odesílám přes naja.makeRequest, není mi jasné proč. V proměnné „order“ je pole s upraveným pořadím od sortovače, ale v tom handle mám pole data furt prázdné, handle se spustí, protože ta flashMessage se zobrazí. Když se podívám v prohlížeči na provedený request, tak v něm to pole data s obsahem je. Zkoušel jsem i použít GET místo POST, ale nemá to na výsledek žádný vliv.

Udělal jsem to podle staršího ne-nette projektu, kde to mám řešené stejně, akorát si v jquery.load volám zvláštní soubor, kde je to zpracování a tam mi to funguje, data v requestu jsou úplně stejné…

Presenter – handle

public function handleSortImages(array $data)
{
    bdump($data);
    $this->flashMessage('Pořadí obrázků bylo aktualizováno!', 'alert-success');
    $this->redirect('this');
}

V šabloně

{snippet imagesList}
<ul class="gallery" id="sortable" data-link="{link sortImages!}">
    <li class="ImageHolder" n:foreach="$images as $oneImage" data-id="{$oneImage->id}">obrázek...</li>
</ul>
{/snippet}

samostatný JS soubor(není v šabloně)

naja.addEventListener('load', () => {
    let sortElem = $('#sortable');
    if (sortElem.length) {
        let postLink = sortElem.data('link');
        let list = Sortable.create(sortable, {
            animation: 100,
            onUpdate: function (evt) {
                let order = list.toArray(); // use instance
                naja.makeRequest('POST', postLink, {data: order});
            }
        });
    }
});
dakur
Člen | 493
+
0
-

@darkWolf Parametry action metody se berou z query stringu URL, kdežto ty posíláš data v těle požadavku. $this->getHttpRequest()->getRawBody() ti vrátí tělo, potom ho můžeš libovolně rozparsovat.

Editoval dakur (9. 9. 2020 9:19)

d@rkWolf
Člen | 167
+
0
-

@dakur to by to ale mělo fungovat, když to pošlu GETem ne? a to taky nefungovalo, zkoušel sem obojí

jiri.pudil
Nette Blogger | 1029
+
0
-

Jak ten request vypadá? Moje podezření je, že URLSearchParams, které Naja využívá k serializaci objektu s daty, si neporadí s polem a serializují ho v podobě, které neporozumí server.

Možná bych zkusil ten objekt sestavit ručně s pomocí []:

const data = new URLSearchParams();
for (const item of order) {
	data.append('data[]', item);
}

naja.makeRequest('POST', postLink, data);
d@rkWolf
Člen | 167
+
0
-

@jiripudil zkusil jsem to takto jak píšeš, furt mi to padá na:

Uncaught TypeError: ‚append‘ called on an object that does not implement interface URLSearchParams.

Když to posílám POSTem:

XHR POST http://web-base-start.local/admin/gallery/edit/992?do=sortImages

[HTTP/1.1 200 OK 921ms]

[] […]
0 „3286“
1 „3285“
2 „3287“

1

%5B%5D=3286&%5B%5D=3285&%5B%5D=3287

Když to pošlu GETem:

XHR GET http://web-base-start.local/admin/gallery/edit/992?do=sortImages&data%5B%5D=3286&data%5B%5D=3285&data%5B%5D=3287

[HTTP/1.1 200 OK 720ms]

Ten admin je celej ajaxovej, snippety se překreslí, flash message co mám v té Handle se zobrazí, ale data tam žádný nejsou, furt je to prázdné, nevím, čím to, sem z toho zoufalý…hlavně, kdy mi to ve starém systému, kde sem to posílal takto:

$('.messages-block').load('./ajax/process_sortable.php', {gal_order: order, gal_id: gal_id});

Editoval d@rkWolf (15. 9. 2020 14:56)

d@rkWolf
Člen | 167
+
0
-

Tak sem to zprovoznil, ač teda úplně netuším proč, nicméně takto to funguje:

let order = list.toArray();
naja.makeRequest('POST', postLink, {'galOrder': JSON.stringify(order)});

V handle pak použiju json_decode, asi je to něco s tím, že sem posílal to pole, ale moc jasný proč mi to teda není, když bez Nette mi stejný mechanismus s jQuery fungoval.

dakur
Člen | 493
+
0
-

@darkWolf Píšeš zkusil jsem to takto jak píšeš, furt mi to padá na... – ale jak jsi to zkusil? V původním příkladu používáš to, co vyplivne Sortable – jak jsi z toho potom udělal URLSearchParams? Možná tam bude chyba v té konverzi.

d@rkWolf
Člen | 167
+
0
-

@dakur mno však tak jak to píše Jiří Pudil, objekt new urlsearchparams a naládování těch položek z pole for cyklem-a výsledek byl ta chyba jak sem psal

ale teď mi to funguje, používám furt to pole ze Sortable, akorát na něj použiju JSON.stringify, to se do proměnné v handle předá správně, aj je jedno, jestli to pošlu POSTem, nebo GETem

dakur
Člen | 493
+
0
-

@darkWolf Narazil jsem teď na něco podobného – měl jsem na vstupu pole, které jsem potřeboval poslat na server a tam ho použít. Když jsem napsal naja.makeRequest('POST', someUrl, data), tak jsem na backendu dostal v raw body: []=prvek1&[]=prvek2 etc.

@jiripudil mi poradil, že by mohlo být řešením přidání dataType: 'json' do options, čímž se instruuje underlying (jak se to řekne česky?) knihovna qwest a už jsem na backendu dostal pěkný encodovaný JSON.

Takže:

naja.makeRequest('POST', someUrl, data, {dataType: 'json'})

Editoval dakur (2. 10. 2020 13:30)

d@rkWolf
Člen | 167
+
+1
-

@dakur Mno to v podstatě asi bude stejnej výstup, jako sem získal použitím JSON.Stringify ne? Každopádně v dokumentaci sem si toho nevšiml, že se tam dá tohle uvést do options.

prog1
Člen | 45
+
0
-

Ahoj! S najou začínám, zatím jsem ji na svůj kód v nette zkoušel aplikovat zkušebně podle @jiripudil a to funguje (na odkazech mám třídu ajax plus snipety u contentu a tittle, index.js zde).

index.js

document.addEventListener(
    'DOMContentLoaded',
    () => {
        naja.addEventListener('complete', () => {
            document.body.style.backgroundColor = `#${Math.floor(Math.random() * (2**24)).toString(16)}`;
        });
        naja.inicialize();
    }
);

V nette aplikaci mám tabulku, kde chcu po kliknutí na Datum vytvoření pomocí naji srovnat položky podle data (created_at). Mohl by mi prosím někdo poradit, jak toho mám co nejjednodušeji docílit?
Předem moc díky.

Infanticide0
Člen | 103
+
+2
-

Naja nic nesortuje. Ty chceš něco jako:

  • Datum vytvoření = odkaz na signál/přidání parametru
  • podle parametru přidáš orderBy pro data tabulky
  • invaliduješ snippet/control s tabulkou a vrátíš payload pro Naju

Editoval Infanticide0 (11. 3. 20:00)

prog1
Člen | 45
+
0
-

Můžu poprosit podrobněji?
Teď to mám srovnané natvrdo ...->order(sloupec. 'DESC') pouze v Nette.

Šaman
Člen | 2659
+
+3
-

Vždycky to bude v Nette (teda, pokud se bavíme o řešení pomocí snippetů a zabudované podpory ajaxu v Nette). Tohle je potřeba pochopit – Naja nebude s daty dělat nic, jen zařídí ajaxové překreslení části nebo celé stránky.

Takže ty si vytvoříš tabulku, nějaký html odkaz (nejspíš nadpis sloupce, podle kterého budeš řadit), ten odkaz povede na signál, který vyrenderuje stránku s jiným řazením tabulky a (bez ajaxu) provede redirect na stejnou stránku. Až do teď žádná Naja, js, ani ajax.

Teprve až ti tohle bude šlapat, tak do projektu načteš Naju, tomu odkazu přidáš html class="ajax" a v tom signálu přidáš podmínku (i když jsi to mohl mít už od začátku):

if ($this->isAjax()) {
  $this->redrawControl();
} else {
  $this->redirect('this');
}

Je to z hlavy, možná jsou v tom překlepy. Všechno by mělo být v dokumentaci – životní cyklus presenteru, signály a ajax.
Důležité je, že Naja ti pak jen zařídí překreslení bez realoadu stránky, ale princip funguje stejně, jako kdybys to řešil s reloadem.

S pomocí snippetů se pak dá překreslovat jen malá část stránky, třeba jen ta tabulka a nenačítat celou stránku. To je ale až druhý level. Pokud je ta tabulka na stránce to hlavní, ani to většinou není potřeba řešit přes pojmenované snippety.

Editoval Šaman (13. 3. 9:27)