Překreslení formuláře bez odeslání
- d@rkWolf
- Člen | 167
Zdravím, poradil by mi prosím někdo, kde dělám chybu?
Mám formulář, který je obalený ve snippetu a který potřebuju, aby se při jakékoliv změně překreslil, ale neodeslal-na odeslání je tam NE-ajaxový submit button.
<?php
{snippet summary}
<form id="frm-orderForm" ...>
...
</form
{/snippet}
?>
k tomu handle
<?php
public function handleRecalculateCart() {
$data = $this->presenter->getHttpRequest()->getPost();
...
$this->redrawControl('summary');
}
?>
a js v samostatném souboru s js scripty
<script>
$(document).on('change', '#frm-orderForm', function() {
$.nette.ajax({
type: 'POST',
url :'?do=recalculateCart',
data: $(this).serialize()
});
});
</script>
Z nějakého mě nepochopitelného důvodu se mi ten formulář při změně odesílá, jako bych kliknul na Submit, klasicky postem, kterej překresluje obsah na dokončení, místo aby se překreslil snippet.
- d@rkWolf
- Člen | 167
No já potřebuju, aby se mi při on(change) uložily aktuální údaje z polí do session(to mám v tom handlu) a překreslil se snippet s celým tím formem, jenže teď se stanou 2 věci, provede se ajax, jenže zároveň s ním se provede i normální ne-ajaxový post toho formu jako bych kliknul na normální submit tlačítko, takže zákazník místo aktualizované ceny nebo jiných údajů okamžitě odešle objednávku.
Tohle chování se objevilo po tom, co jsem upgradoval Nette z 2.2.7 na 2.3.10, na 2.2.7 se to s naprosto stejným kódem chovalo tak jak potřebuju. Zkusil jsem aktualizovat nette.ajax, jestli není nějaký problém v něm, ale nic se nezměnilo.
- d@rkWolf
- Člen | 167
CZechBoY napsal(a):
Chyba bude v js.
Predej sievent
a potom na nem tavolejpreventDefault()
, idealne hned na zacatku callbacku.$(document).on('change', 'tvuj selector', function(e) { e.preventDefault(); //... tvuj kod });
Mám tam na konci return false, tím to není, zkoušel jsem i preventDefault(), to sice zablokovalo odeslání, ale přesto provedlo zpracování odeslaného formuláře(public function orderFormSubmitted), takže pak nastala úplně problematická situace, protože při dalším refreshi všecko z koše zmizelo, jelikož neviditelná orderFormSubmitted vše odeslala a zrušila všecky data ze session)
- d@rkWolf
- Člen | 167
Ale asi sem na to přišel:
totiž nové Nette přidává k FormData do: orderForm-submit, asi tak nějak automaticky, takže když jsem v JS použil $(this).serialize(), dostal jsem to do těch odeslaných dat, v podstatě tam byly 2× do:, jedno recalculateCart jako parametr adresy a druhý orderForm-submit v datech formuláře, no a to orderForm-submit si následně odchytila funkce co zpracovává odeslání formuláře
takže jsem to upravil takto, prostě z tama to orderForm-submit vyhodím:
<script>
$(document).on('change', '#frm-orderForm', function(e) {
var data = $(this).serialize();
data = data.replace('&do=orderForm-submit', '');
$.nette.ajax({
type: 'POST',
url :'?do=recalculateCart',
data: data
});
return false;
});
</script>
- Jan Mikeš
- Člen | 771
Ahoj, tvůj způsob se mi moc nelíbí, zdá se mi dost nečisté ručně
serializovat data a handlovat sám request na form s do
parametrem,
to je opravdu fujky. Poradím ti, jak to děláme my.
Přidám si nový button, který slouží na ukládání dat, v šabloně ho přes css schovám:
$form->addSubmit('saveData', 'save')
->setValidationScope(FALSE)
->onClick[] = function(Button $button) use ($saveButtonCallback) {
$values = $button->getForm()->getValues(TRUE);
$saveButtonCallback($values);
};
Jen pro doplnění, $saveButtonCallback
je callable
předáno při vytváření instance formuláře
public function create($locale, array $inputs, callable $successCallback, callable $saveButtonCallback)
setValidationScope(false)
ti navíc vypne validační pravidla,
takže ukládá vždy aktuální data bez ohledu na validaci.
U nás to ukládáme na pozadí takto:
window.setInterval(function() {
$("[data-periodic-save]").click();
}, 60000);
Nic ale nebrání to navázat na tvůj handler onChange
Zbývá tlačítko vykreslit v šabloně, schovat ho, ajax nastavení atd. dle libosti:
{input saveData, data-periodic-save=>"", style=>"display: none;", data-ajax-body-class=>"no-spinner", data-ajax-off=>"[unique, abort, history, initOnAjax, modals, confirm, ajaxCloseClick, initFormsValidation, ajaxForms]"}
Pro úplnost, formulář pak vytvářím např takto:
protected function createComponentForm()
{
$saveCallback = function(array $values) {
$this->storage->store($values);
$this->onValuesSaved();
};
$successCallback = function() {
$this->storage->clean();
$this->onFormSuccess();
};
return $this->formFactory->create($this->locale, $this->inputs, $successCallback, $saveCallback);
}
Editoval Jan Mikeš (18. 6. 2017 15:10)
- d@rkWolf
- Člen | 167
Jo to vypadá hezky, vono v tom košíku by toho bylo potřeba předělat mnohem víc. Jenže od té doby, co sem to „podědil“ mám většinou sotva tak čas opravovat chyby, todle bylo nutný nějak rychle opravit doslova do 5 minut než otevřou a začnou jim tam posílat lidi objednávky místo výběru platební metody… Vrchol byl upgrade Nette a dalších komponent na verze kompatibilní s php7 a následné upravení co bylo třeba, což aspoň na chvíli zmírní stížnosti klientů na pomalost systému.
Každopádně si to připíšu k „To Do“