Naja.js odesílání GET formuláře a přepis url
- Laxren
- Backer | 23
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 | 1029
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
@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 | 1029
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
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 | 1029
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
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>