Přepočítání košíku s odmazáním
- tatyalien
- Člen | 239
Dobrý den,
rozjel jsem si přidávání a aktualizaci košíku pomocí ajaxu, funguje to
spolehlivě, ale když přepočítávám košík a přitom z něj odmazávám,
tak to nefunguje tak jak by mělo.
Příklad:
mám v košíku: kat-1 1ks, kat-2 2ks, kat-3 3ks… změním počet kusů na
0 u položky kat-2 a po odeslání by se měl zobrazit tedy formulář s:
kat-1 1ks, kat-3 3ks, ale vykreslí se mě kat-1 1ks, kat-2 0ks, kat-3 3ks,
když udělám aktualizaci stránky (F5) je vže ok.
Někdy se i vykreslí: kat-1 1ks, kat-3 0ks..
Nevím kde je zakopanej pes, jestli něco dělám blbě u ajaxu…?
Zde jsem to kdyžtak sesumíroval do mini_sendboxu.
Továrničku na editaci mám:
// jednoduchá továrnička
protected function createComponentBasketEditFormNew()
{
$form = new Form();
// natáhnu si kolik položek mám vytvořit
$kosik = $this->context->shoppingCart->printCartNew();
$i = 0;
$pole = Array();
$polozka = $form->addContainer('polozka');
foreach($kosik as $value) {
if($value['ks'] != 0){
$polozka->addContainer($i);
$polozka[$i]->addText('goods_katalog', 'katalog');
$polozka[$i]->addText('ks', 'ks:', 3,20);
$polozka[$i]->addText('poznamka', 'Poznámka:', 44,1024);
$i++;
$pole[$i-1] = Array('goods_katalog' => $value['goods_katalog'], 'ks' => $value['ks'], 'poznamka' => $value['poznamka']);
}
}
$arr = Array('polozka' => $pole);
// caption dodané v render metodě - obrázek
$form->addSubmit('ok', 'Odeslat');
$form->setDefaults($arr);
$form->onSuccess[] = callback($this, 'editBasketFormSubmitted');
// nastavení třídy pro formulář na ajax
$form->getElementPrototype()->class("ajax");
return $form;
}
public function editBasketFormSubmitted(Form $form)
{
try {
$values = $form->getValues();
foreach($values->polozka as $val) {
$this->context->shoppingCart->edit($val['goods_katalog'], $val['ks'], $val['poznamka'], $this->presenter, false);
}
$this->flashMessage('Nákupní košík přepočítán.', 'success');
if($this->isAjax()) {
$this->invalidateControl('basketSoucet');
$this->invalidateControl('flash');
$this->invalidateControl('basketInfo');
$this->invalidateControl('basketEdit');
$this->invalidateControl('javaAjax');
} else {
$this->redirect('this');
}
} catch (IOException $e) {
$form->addError($e->getMessage());
}
}
třída shopping cart je kdyžtak v sendobxu v linku nahoře.
- LeonardoCA
- Člen | 296
V rychlosti jsem na to mrknul, chyba je podle mne v tom, že komponenta je ve chvíli kdy se zpracovává handle již vytvořena. InvalidateControl znamená jen znovu vykreslit, ale ty položky košíku, které mají hodnotu 0 jsou již v definici formuláře a vykreslí se taky.
Jak to snadno a vtipně ošetřit zatím nevím a také by mne to zajímalo.
Editováno:
Buď zahodit komponentu a vytvořit znovu nebo ji nějak modifikovat?
Editoval LeonardoCA (4. 6. 2012 13:27)
- tatyalien
- Člen | 239
Taky jsem si říkal, že komponenta už nejspíš je někde vytvořená a nebere v potaz, že jsem jí invalidoval… u košíku mám i křížek na odstranění jednotlivé položky z košíku přes hendl a vše ok… ale chtěl jsem to i povolit, když má uživatel víc věcí v košíku a chce odmazat třeba 3 naráz… (no lépe řečeno, shop si jen dělám v nette pro své programátorské blbnutí :-D)
- LeonardoCA
- Člen | 296
zkus si pridat do kodu
Debugger::fireLog(‚createComponentBasketEditFormNew‘);
Debugger::fireLog(‚editBasketFormSubmitted‘);
do odpovidajicich trid a do handlaru toho mazani take vypis a sleduj v jakem
poradi se ti funkce volaji …
- tatyalien
- Člen | 239
Tak dvě situace:
- Situace 1:
Prvotní načtení:
- render start
- render konec
- (zde se nepřipojila komponenta)
ajax odeslani:
- továrna start
- // odesílal jsem kat-1 1, kat-2 0, kat-3 3
[Object { goods_katalog="kat-1", goods_nazev="katalog 1", ks=1, více...}, Object { goods_katalog="kat-2", goods_nazev="katalog 2", ks=2, více...}, Object { goods_katalog="kat-3", goods_nazev="katalog 3", ks=3, více...}]
- továrna konec
- editBasketFormSubmitted start
[Object { goods_katalog="kat-1", goods_nazev="katalog 1", ks=1, více...}, Object { goods_katalog="kat-3", goods_nazev="katalog 3", ks=3, více...}]
// v sessionu košíku je nyní vše ok
- editBasketFormSubmitted konec
- render start
- render konec
- ale nevrátí se mě nově aktualizovaný formulář, je zde furt z prvotního
- Situace 2:
když dám do render metody:
$frm = $this['basketEditFormNew'];
$frm['ok']->caption = "ok A";
// jen abych přistoupil k formuláři…
Začátek:
- render start
- továrna start
- // načtení košíku kat-1 1, kat-2 2, kat-3 3
[Object { goods_katalog="kat-1", goods_nazev="katalog 1", ks=1, více...}, Object { goods_katalog="kat-2", goods_nazev="katalog 2", ks=2, více...}, Object { goods_katalog="kat-3", goods_nazev="katalog 3", ks=3, více...}]
- továrna konec
- render konec
ajax odeslání:
- továrna start
- // staré data kat-1 1, kat-2 2, kat-3 3
[Object { goods_katalog="kat-1", goods_nazev="katalog 1", ks=1, více...}, Object { goods_katalog="kat-2", goods_nazev="katalog 2", ks=2, více...}, Object { goods_katalog="kat-3", goods_nazev="katalog 3", ks=3, více...}]
- továrna konec
- editBasketFormSubmitted start
// v košíku již vše ok kat-2 jsem odmazával
[Object { goods_katalog="kat-1", goods_nazev="katalog 1", ks=1, více...}, Object { goods_katalog="kat-3", goods_nazev="katalog 3", ks=3, více...}]
- editBasketFormSubmitted konec
- render start
- // zde se nezavolá továrna nově…
- render konec
Editoval tatyalien (5. 6. 2012 11:57)
- 22
- Člen | 1478
Nevím, co se tu přesně řeší, ale doporučil bych ti se podívat na životní cyklus presenteru
Data bych plnil v action
metodě a handlerem se dají měnit a
invalidovat snippet/y
- tatyalien
- Člen | 239
VYŘEŠENO:
Případné řešení je ze starého vlákna:
public function renderBasket()
{
...
if($this->isAjax()) {
// promazání formuláře a vytvoření formuláře
unset($this['basketEditForm']);
//... zvýšit počet řádků v session (já to zvětšuji při odesláním formuláře)
// a v továrničce si načtu kolik je potřeba vytvořit prvků v košíku...
$this->template->basketEditForm = $this->createComponentBasketEditForm();
$this->invalidateControl('title');
}
}
Editoval tatyalien (6. 6. 2012 12:49)
- Vojtěch Dobeš
- Gold Partner | 1316
Potřebuje v rámci jednoho requestu sestavit formulář, provést jeho zpracování a znovu sestavit ten samý formulář.
- tatyalien
- Člen | 239
Nejspíše ano, protože pokud jsem to nezavolal, tak komponenta měla staré data, takto se promazala a bylo to ok, vzorovej příklad bez unsetnutí je v prvním příspěvku, když se tam dodá unset tak vše funguje jak má…
Edit: Pokud se jen přepočítávaly hodnoty, není potřeba unsetnout, ale pokud se nastavilo u položek 0 ks tak tu hodnotu odmazávám a pak je potřeba formulář znovu sestavit.
Editoval tatyalien (6. 6. 2012 14:42)