Naja.js odesílání GET formuláře a přepis url

Laxren
Backer | 23
+
0
-

Zdravím,

mám filtrovací formulář, který když odešlete, tak by se měly hodnoty z formuláře předat do url a překreslit určité snippety.

Formulář funguje správně jen tehdy, když není přes ajax.. (když smažu .ajax z formuláře).

Když ho zajaxuji, tak tracy normálně vypisuje, že se něco ajaxového stalo, ale nepředalo se nic z formuláře a když si něco vypíšu ve Succeeded metodě třeba Debugger::fireLog($form->isSuccess());, tak se mi nic nevypíše, nejspíše se to tam vůbec nedostalo..

Když vymažu z formuláře $form->setMethod(Form::GET); , tak se to do Succeeded metody už dostane, ale nepředá se samozřejmě nic do parametrů.

Problém se objevil, když jsem updatoval z nette 2.4 na 3.0 a nahradil nette.ajax.js za naja.js. (s nette 2.4 a nette.ajax.js vše fungovalo).

Napadá někoho něco?

Presenter

<?php

protected function createComponentFilterForm()
{
	$form = $this->formFactory->create();
	$form->setMethod(Form::GET);
	$form->addText('search', 'Hledat');
	$form->addSelect('order_by', 'Řadit podle', array(
		'order_no' => 'Doporučené',
		'newest' => 'Nejnovější',
		'lowest_price' => 'Nejnižší ceny',
		'highest_price' => 'Nejvyšší ceny'
	))->setRequired(true);
	$form->addRadioList('categories', 'Kategorie'); /*Itemy se nastaví v renderu*/
	$form->addSubmit('filter', 'Filtrovat');
	$form->onSuccess[] = [$this, 'filterFormSucceeded'];
	return $form;
}

public function filterFormSucceeded($form, $values)
{
	//Debugger::fireLog($form->isSuccess());
	//Debugger::fireLog($this->getParameters());
	if($this->isAjax()){
		$this->redrawControl('filterListingBlock');
		$this->redrawControl('filterFormArea');
		$this->redrawControl('filterForm');
		$this->payload->postGet = TRUE;
		$this->payload->url = 'https://' . $this->url->getHost() . $this->url->getBasePath() . $this->url->getRelativeUrl();
		//Zkoušel jsem to i bez payloadu a výsledek byl stejný.

	}
}

?>

latte form

{snippet filterForm}
<form n:name="filterForm" class="ajax filterForm">
    <ul class="errors" n:if="$form->hasErrors()">
        <li n:foreach="$form->errors as $error">{$error}</li>
    </ul>
    <div class="row">
        <div class="col-md-12">
            <div class="search err">
                <button type="submit" value="Submit"><span class="fas fa-search"></span></button>
                {input search class => search-input, data-change-filterForm => '', placeholder => 'Vyhledat...'}
                <button type="button" title="Vymazat vyhledávání" n:class="clear-search-input"><span class="fas fa-times"></span></button>
            </div>
            <div class="selectbox err">
                {input order_by class => selectbox-input, data-change-filterForm => ''}
            </div>
            <div class="checkbox-content err">
                {foreach $form[categories]->items as $key => $label}
                    <label class="checkbox-l" n:name="categories:$key">{$label}
                        <input n:name="categories:$key" data-change-filterForm/>
                        <span></span>
                    </label>
                {/foreach}
            </div>
        </div>
    </div>

    <div class="button-offset">
    	{input filter class => 'button small', data-submit-filterForm => ''}
    </div>
</form>
{/snippet}

latte default

{snippetArea filterFormArea}
	{include $filterFormPath}
{/snippetArea}

Další, méně podstatný, dotaz ohledně naja.js..
V dokumentaci se doporučuje initializovat pomocí ‚document.addEventListener('DOMContentLoaded‘, naja.initialize.bind(naja));‚, ale když chci přidat nějaké options, tak jak se to má správně udělat? Může se třeba.. 'document.addEventListener('DOMContentLoaded‘, naja.initialize({ history: ‚replace‘ }).bind(naja));' ? Ale to pak vyhazuje chybu s .bind, tak se může .bind vymazat nebo.. ?

jiri.pudil
Nette Blogger | 1028
+
+1
-

Ahoj, s podobným problémem (nefunkční odesílání formulářů přes GET) už se kdosi hlásil na slacku, je to bug a bude brzy opraven.

K méně podstatnému dotazu: jedna možnost je obalit to volání do funkce:

document.addEventListener('DOMContentLoaded', () => naja.initialize(options));

Taky by mělo fungovat toto:

document.addEventListener('DOMContentLoaded', naja.initialize.bind(naja, options));

Ale ta obalující funkce je asi na první pohled srozumitelnější. Zamyslím se, jestli tímto směrem neupravit i dokumentaci :)

Editoval jiri.pudil (24. 4. 2020 11:03)

Laxren
Backer | 23
+
0
-

Díky moc za rychlou reakci a objasnění, budu čekat na opravu.

PS: Díky za Naju ;)

Laxren
Backer | 23
+
0
-

@jiripudil
Zkouším tu upravenou verzi, která funguje, ale..
Když jdu na stránku, kde mám ten GET formulář a vyvolám ho a pak jdu v browser historii o krok zpět a vyvolám ho znova, tak se už předají jen ty parametry, které se předaly, než jsem šel o ten krok zpět a už se nechtějí předávat nové (ať už kliknu kolikrát chci). Opraví se to tím, že refreshnu stránku a pak to zas jde normálně, než se zas vrátí v historii..

///
stránka /produkty
odešle se ajaxově form → /produkty?query=xxx&query2=xxx&do=filterForm-submit
jde se o krok zpět v historii
odešle se znova a dají se tam ty původní parametry /produkty?query=xxx&query2=xxx&do=filterForm-submit
místo nových, který by tam měly být /produkty?query=yyyyyyy&query2=yyyyyyy&do=filterForm-submit
///

Nejsem si jistý, jestli to je způsobené mnou nebo Najou..

Kód je stejný jako nahoře.. jen v succeeded metodě se změnil jeden řádek $this->payload->url = $this->link('this', $this->getParameters());

Editoval Laxren (30. 4. 2020 10:21)

jiri.pudil
Nette Blogger | 1028
+
0
-

Ahoj @Laxren, bohužel se mi nedaří tebou popisované chování reprodukovat. Připravil bys mi prosím repo s minimálním kódem a popisem postupu, jakým se dá ta chyba vyvolat? Můžeš zkusit rozbít můj sandbox.

Laxren
Backer | 23
+
0
-

Ahoj @jiripudil,
promiň za zpožděnou odpověď.. teď jsem se na to ještě koukal a problém se zdá být v posílání formuláře automaticky přes jquery. Když posílám formulář tlačítkem (manuálně), tak vše funguje jak má. Ale když posílám formulář na on change, tak se to začne chovat jinak.

Postup..
Načte se stránka s ajax formulářem, uděláš první automatické odeslání formuláře a když se pak chce udělat další, tak se nepřepíšou hodnoty a předává to pořád ty stejné, které se poslali při tom prvním požadavku.
Tady je kdyžtak ukázka.

Možná je něco špatně s mým kódem na automatické posílání..

<script>
var form = document.getElementById('frm-filterForm');

$(document).on('change', '[data-change-filterForm]', function (e) {
	naja.uiHandler.submitForm(form);
});
</script>
jiri.pudil
Nette Blogger | 1028
+
+2
-

Možná je něco špatně s mým kódem na automatické posílání..

Myslím že ano :) pokud se tento kus kódu:

var form = document.getElementById('frm-filterForm');

vykoná pouze při načtení stránky, pak máš ve form navždy referenci na první instanci toho formuláře v DOMu. Naja jej sice překreslí a uživatel upravuje hodnoty v překresleném formuláři, ale ty odesíláš pořád ten původní, který už ani ve stránce nikde vykreslený není. Správně by sis měl instanci formuláře vytáhnout uvnitř toho event listeneru z události (e), někde tam určitě bude.

Laxren
Backer | 23
+
+1
-

Vyřešeno, díky za tvůj čas :)
Stačilo to jen přesunout do eventu a už to jde bez problému..

Doporučoval jsi něco takového?

<script>
$(document).on('change', '[data-change-filterForm]', function (e) {
	naja.uiHandler.submitForm(e.target.form);
});
</script>

Fungujou i možnosti jako..

<script>
$(document).on('change', '[data-change-filterForm]', function (e) {
	naja.uiHandler.submitForm(this.form);
});
</script>

nebo to původní..

<script>
$(document).on('change', '[data-change-filterForm]', function (e) {
	var form = document.getElementById('frm-filterForm');
	naja.uiHandler.submitForm(form);
});
</script>