Trošku mimo nette – rada ohledně foreach
- wicked
- Člen | 290
Ahoj,
úplně to nesouvisí s Nette, ale na jiná fóra nechodím, takže to aspoň tady zkusím :)
v šabloně vypisuji jidelní menu tahle:
{foreach $jidlo->where('den >=', $today)->order('den ASC') as $jidla}
<div class="tabulka_jidelnilistek mezera">
<h4>{$jidla->den}</h4>
<table class="rezervace_jidel">
<tr>
<td class="prvni_sloupec">{$jidla->kategorie}</td>
<td class="druhy_sloupec">{$jidla->nazev}</td>
<td class="treti_sloupec">{if $jidla->veganska}<div class="cervenekolecko">Veg</div>{/if}</td>
<td class="ctvrty_sloupec">{if $jidla->detoxikacni}<div class="cervenekolecko">BL</div>{/if}</td>
<td class="paty_sloupec">{if $jidla->bezlepkova}<div class="cervenekolecko">DX</div>{/if}</td>
<td class="sesty_sloupec"></td>
<td class="sedmy_sloupec">{$jidla->cena}Kč</td>
</tr>
</table>
</div>
{/foreach}
$today = je aktuální datum
to mě vyhodí takovýto výpis
Ale už strašně dlouho se snažím přijít na to, jak jednotlivé položky mám vypsat tak aby se zobrazovali co datum, to všechna jídla k němu do jednoho boxu …
Doufám, že se nezlobíte, že jsem to dal sem a napsal jsem to srozumitelně.
Předem děkuji za radu
- Filip Procházka
- Moderator | 4668
Buďto upravíš vstupní data, abys iteroval dvouúrovňové pole, nebo si někam uložíš stav a „oddělovač“ budeš vkládat pouze pokud se změní datum.
Jako jednodušší bych viděl první variantu.
$this->template->jidelnicek = $connection
->query("... WHERE den >= ? ORDER BY den ASC", $today)
->fetchAssoc('den[]');
Tohle by mělo vytvořit požadovanou strukturu, dyštak si s tím pohraj, to zvládneš :) Má to stejnou syntax jako dibi::fetchAssoc, k tomu určitě něco vygooglíš.
<div class="tabulka_jidelnilistek mezera" n:foreach="$jidelnicek as $den => $jidla">
<h4>{$den}</h4>
<table class="rezervace_jidel">
<tr n:foreach="$jidla as $jidlo">
<td class="prvni_sloupec">{$jidlo->kategorie}</td>
...
</tr>
</table>
</div>
- Etch
- Člen | 403
Mnoha způsoby… třeba:
{var $den = null}
{foreach $jidlo->where('den >=', $today)->order('den ASC') as $jidla}
{if $den != $jidla->den}
<div class="tabulka_jidelnilistek mezera">
<h4>{$jidla->den}</h4>
{/if}
<table class="rezervace_jidel">
<tr>
<td class="prvni_sloupec">{$jidla->kategorie}</td>
<td class="druhy_sloupec">{$jidla->nazev}</td>
<td class="treti_sloupec">{if $jidla->veganska}<div class="cervenekolecko">Veg</div>{/if}</td>
<td class="ctvrty_sloupec">{if $jidla->detoxikacni}<div class="cervenekolecko">BL</div>{/if}</td>
<td class="paty_sloupec">{if $jidla->bezlepkova}<div class="cervenekolecko">DX</div>{/if}</td>
<td class="sesty_sloupec"></td>
<td class="sedmy_sloupec">{$jidla->cena}Kč</td>
</tr>
</table>
{if $den != $jidla->den}
</div>
{/if}
{? $den = $jidla->den}
{/foreach}
- Etch
- Člen | 403
No je pravda, že vzhledem k tomu, jak máš napsané to HTML tak by bylo výhodnější si dané pole předpřipravit jak píše @FilipProcházka. Navíc pokud je dostupné fetchAssoc tak je to nejjednoduší varianta.
Ten způsob s podmínkama se hodí pouze pokud máš HTML například následující:
{var $den = null}
{foreach $jidlo->where('den >=', $today)->order('den ASC') as $jidla}
{if $den != $jidla->den}
<div class="tabulka_jidelnilistek mezera">
<h4>{$jidla->den}</h4>
</div>
{/if}
<div>
<table class="rezervace_jidel">
<tr>
<td class="prvni_sloupec">{$jidla->kategorie}</td>
<td class="druhy_sloupec">{$jidla->nazev}</td>
<td class="treti_sloupec">{if $jidla->veganska}<div class="cervenekolecko">Veg</div>{/if}</td>
<td class="ctvrty_sloupec">{if $jidla->detoxikacni}<div class="cervenekolecko">BL</div>{/if}</td>
<td class="paty_sloupec">{if $jidla->bezlepkova}<div class="cervenekolecko">DX</div>{/if}</td>
<td class="sesty_sloupec"></td>
<td class="sedmy_sloupec">{$jidla->cena}Kč</td>
</tr>
</table>
</div>
{? $den = $jidla->den}
{/foreach}
- wicked
- Člen | 290
Etch napsal(a):
No je pravda, že vzhledem k tomu, jak máš napsané to HTML tak by bylo výhodnější si dané pole předpřipravit jak píše @FilipProcházka. Navíc pokud je dostupné fetchAssoc tak je to nejjednoduší varianta.
Ten způsob s podmínkama se hodí pouze pokud máš HTML například následující:
Takže mám předělat vytahování dat? A nějak zakomponovat fetchAssoc()? Jedu na Nette Database …
- Etch
- Člen | 403
Nepoužívám Nette Database, takže nemohu říci, jestli fetchAssoc podporuje (EDIT: podle API podporuje fetchAssoc). Pokud ano tak ho použij. Pokud ho nepodporuje, tak si můžeš dané pole připravit ručně.
$jidla = $jidlo->where('den >=', $today)->order('den ASC')->fetchAll();
$out = array();
foreach($jidla AS $jidlo){
$out[$jidlo->den][] = $jidlo;
}
$this->template->jidla = $out;
a pak vypisuj jak popsal @FilipProcházka.
Editoval Etch (28. 12. 2014 21:11)
- wicked
- Člen | 290
Etch napsal(a):
Nepoužívám Nette Database, takže nemohu říci, jestli fetchAssoc podporuje (EDIT: podle API podporuje fetchAssoc). Pokud ano tak ho použij. Pokud ho nepodporuje, tak si můžeš dané pole připravit ručně.
$jidla = $jidlo->where('den >=', $today)->order('den ASC')->fetchAll(); $out = array(); foreach($jidla AS $jidlo){ $out[$jidlo->den][] = $jidlo; } $this->template->jidla = $out;
a pak vypisuj jak popsal @FilipProcházka.
Ano podporuje, musel bych udělat komplet update …
Jinak vyřešil jsem to díky Vám takto
sablona:
<div class="tabulka_jidelnilistek mezera" n:foreach="$jidla as $den => $jidelnicek">
<h4>{$den}</h4>
<table class="rezervace_jidel">
<tr n:foreach="$jidelnicek as $jidlo">
<td class="prvni_sloupec">{$jidlo->kategorie}</td>
<td class="druhy_sloupec">{$jidlo->nazev}</td>
<td class="treti_sloupec">{if $jidlo->veganska}<div class="cervenekolecko">Veg</div>{/if}</td>
<td class="ctvrty_sloupec">{if $jidlo->detoxikacni}<div class="cervenekolecko">BL</div>{/if}</td>
<td class="paty_sloupec">{if $jidlo->bezlepkova}<div class="cervenekolecko">DX</div>{/if}</td>
<td class="sesty_sloupec"></td>
<td class="sedmy_sloupec">{$jidlo->cena}Kč</td>
</tr>
</table>
</div>
presenter:
$jidla = $this->jidla->findAll()->where('den >=', $this->today())->order('den ASC')->fetchAll();
$out = array();
foreach ($jidla AS $jidlo) {
$out[$jidlo->den][] = $jidlo;
}
$this->template->jidla = $out;
Ještě jednou děkuji :)
- wicked
- Člen | 290
Rád bych obnovil toto téma, ale pro změnu s jiným dotazem … Doufám, že najdu dobrou duši s radou :)
Mám presenter, který vypisuje jídla na určitý den (jak jsme řešili výše) ale teď přemýšlím, jak řešit objednávku jídel?
Když kouknete sem jde mi o to, abych po vyplnění kusů jídel dostal jako výstup toho formuláře počet jídel k danému dni->jídlu
Napadlo mě nějak předávat id toho jídla, ale vůnec nevím jak to propojit s formulářek …
Zatím mám „základ“ takto
šablona:
{block content}
{form objednavkaForm}
<div class="nadpis_jidelnilistek">REZERVACE JÍDEL</div>
<div class="tabulka_jidelnilistek mezera" n:foreach="$jidla as $den => $jidelnicek">
<h4>{$den}</h4>
<table class="rezervace_jidel">
<tr n:foreach="$jidelnicek as $jidlo" {if $iterator->isLast()} class="bezpruhu"{/if}>
<td class="prvni_sloupec">{$jidlo->kategorie}</td>
<td class="druhy_sloupec">{$jidlo->nazev}</td>
<td class="treti_sloupec">{if $jidlo->veganska}<div class="cervenekolecko">Veg</div>{/if}</td>
<td class="ctvrty_sloupec">{if $jidlo->detoxikacni}<div class="cervenekolecko">BL</div>{/if}</td>
<td class="paty_sloupec">{if $jidlo->bezlepkova}<div class="cervenekolecko">DX</div>{/if}</td>
<td class="sesty_sloupec">{$jidlo->cena},-Kč</td>
<td class="sedmy_sloupec">{input pocet}</td>
</tr>
</table>
</div>
{input odeslat}
{/form}
{/block}
Presenter:
class MenuPresenter extends HomepagePresenter {
/** @var \App\Model\JidlaModel @inject */
public $jidla;
public function renderDefault() {
$jidla = $this->jidla->findAll()->where('den >=', $this->today())->order('den ASC')->fetchAll();
$out = array();
foreach ($jidla as $jidlo) {
$out[$jidlo->den][] = $jidlo;
}
$this->template->jidla = $out;
}
// Dnesni datum
public function today() {
return date('d. m. Y');
}
public function createComponentObjednavkaForm() {
$form = new Form();
$form->addText('pocet', '')
->setType('number')
->setDefaultValue('0')
->addRule(Form::INTEGER, 'Musí být číslo!');
$form->addSubmit('odeslat', 'Odeslat objednávku')
->setAttribute('id', 'odeslat');
// call method signInFormSucceeded() on success
$form->onSuccess[] = $this->objednavkaFormSucceeded;
return $form;
}
public function objednavkaFormSucceeded($form){
$values = $form->getValues();
dump($values);
}
}
Ale prosím, jak bych mohl řešit to, abych jako výstup z toho formuláře měl kompletní přehled objednávky? Počet jídel, jídlo?
Mockrát děkuji … :)
- trejjam
- Backer | 65
Koukni na low-level formuláře
Btw doporučuju přidat k těm zkratkám nějaký title.
- trejjam
- Backer | 65
Zkus něco takového
{block content}
{form objednavkaForm}
<div class="nadpis_jidelnilistek">REZERVACE JÍDEL</div>
<div class="tabulka_jidelnilistek mezera" n:foreach="$jidla as $den => $jidelnicek">
<h4>{$den}</h4>
<table class="rezervace_jidel">
<tr n:foreach="$jidelnicek as $jidlo" n:class="$iterator->isLast()?bezpruhu">
<td class="prvni_sloupec">{$jidlo->kategorie}</td>
<td class="druhy_sloupec">{$jidlo->nazev}</td>
<td class="treti_sloupec"><div n:if="$jidlo->veganska" class="cervenekolecko" title="Jídlo vhodné pro vegetariány">Veg</div></td>
...
<td class="sedmy_sloupec"><input type="hidden" name="jidloId[]" value="{$jidlo->id}"><input type="number" min="0" name="jidloPocet[]"></td>
</tr>
</table>
</div>
{input odeslat}
{/form}
{/block}
Pro čtení by mělo fungovat něco jako:
$jidloId=$form->getHttpData($form::DATA_TEXT, 'jidloId[]'); //podívej se, zda je i typ DATA_NUMBER/INT/etc
$jidloPocet=$form->getHttpData($form::DATA_TEXT, 'jidloPocet[]');
$jidloObjednavka=array_combine($jidloId, $jidloPocet);
Editoval trejjam (30. 12. 2014 0:06)
- wicked
- Člen | 290
trejjam napsal(a):
Zkus něco takového
{block content} {form objednavkaForm} <div class="nadpis_jidelnilistek">REZERVACE JÍDEL</div> <div class="tabulka_jidelnilistek mezera" n:foreach="$jidla as $den => $jidelnicek"> <h4>{$den}</h4> <table class="rezervace_jidel"> <tr n:foreach="$jidelnicek as $jidlo" n:class="$iterator->isLast()?bezpruhu"> <td class="prvni_sloupec">{$jidlo->kategorie}</td> <td class="druhy_sloupec">{$jidlo->nazev}</td> <td class="treti_sloupec"><div n:if="$jidlo->veganska" class="cervenekolecko" title="Jídlo vhodné pro vegetariány">Veg</div></td> ... <td class="sedmy_sloupec"><input type="hidden" name="jidloId[]" value="{$jidlo->id}"><input type="number" min="0" name="jidloPocet[]"></td> </tr> </table> </div> {input odeslat} {/form} {/block}
Pro čtení by mělo fungovat něco jako:
$jidloId=$form->getHttpData($form::DATA_TEXT, 'jidloId[]'); //podívej se, zda je i typ DATA_NUMBER/INT/etc $jidloPocet=$form->getHttpData($form::DATA_TEXT, 'jidloPocet[]'); $jidloObjednavka=array_combine($jidloId, $jidloPocet);
Ano ano :) Dostanu ID jidel a k nim jejich počet :-) Ted už jenom zpracuji :)
DĚKUJI MNOHOKRÁT! :-)
- wicked
- Člen | 290
Jen bych se chtěl ještě ujistit, je toto zpracování v pořádku? Nebo bych měl něco upravit?
public function objednavkaFormSucceeded($form) {
// Dostaneme hodnoty
$jidloId = $form->getHttpData($form::DATA_TEXT, 'jidloId[]');
$jidloPocet = $form->getHttpData($form::DATA_TEXT, 'jidloPocet[]');
// Hodnoty do 1 pole
$jidloObjednavka = array_combine($jidloId, $jidloPocet);
// Projdeme hodnoty a rozdelime ve foreach
foreach ($jidloObjednavka as $jidlo => $ks) {
if ($ks) {
try {
// Nastavime sessions
$session = $this->getSession('objednavka');
$session->polozkyObjednavka[] = array(
"jidlo" => $jidlo,
"pocet" => $ks
);
$this->flashMessage('Objednávka byla úspěšně zpracována!', 'alert alert-success');
$this->redirect('this');
} catch (Exception $ex) {
$form->addError('Při ukládání se vyskytla chyba: ' . $ex);
if ($ex instanceof \Nette\Application\AbortException) {
throw $ex;
}
}
}
}
}
Děkuji :)
EDIT: Tak něco je blbě, uloží mě to jenom 1. zaznam, ale ne všechny postupně …
Editoval wicked (30. 12. 2014 14:15)