Generovani tabulek podle jmena v latte

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
TheNEoo
Člen | 75
+
0
-

Ahoj,
řeším decentní problém, který spíše souvisí s php než celkově s nette, ale k problému.

Potřebuji rozdělit jednu tabulku podle jmen.

Co mám na mysli:

.latte

<!-- takto nějak standardně vypisujeme data v šabloně a sčítáme -->

{var $soucet}
{foreach $item as $items}
 {first}
  <table>
   <thead>
    <tr>
     <th>Jméno</th>
     <th>Peníze</th>
    </tr>
   </thead>
   <tbody>
 {/first}

   <tr>
    <td>{$items->jmeno}</td>
    <td>{$items->penize}</td>
   </tr>
   {? $soucet = $items->penize + $soucet}

 {last}
  </tbody>
  <tfoot>
   <tr>
    <td>Součet {$soucet},-</td>
   </tr>
  </tfoot>
 </table>
 {/last}

{/foreach}

.latte

<!-- Jenže já to potřebuji rozdělit tabulku podle jmen, to znamená co změna jména, to nová tabulka -->
<!-- Zatím jsem dal dohromady toto a funguje to normálně, problém s kterým si nevím rady je <tfoot> na konci se součtem -->

{var $jmeno}
{var $soucet}
{foreach $item as $items}

{if $items->jmeno != $jmeno}
<table>
 <thead>
  <tr>
   <th>Jméno</th>
   <th>Peníze</th>
  </tr>
 </thead>

 <tbody>
  <tr>
   <td>{$items->jmeno}</td>
   <td>{$items->penize}</td>
  </tr>
{? $jmeno = $items->jmeno} <!-- Ukládám si jméno do proměné a v if kontroluji -->
{? $soucet = $items->celkem + $soucet} <!-- Sčítáme peníze -->

{else}
  <tr>
   <td>{$items->jmeno}</td>
   <td>{$items->penize}</td>
  </tr>
{? $jmeno = $items->jmeno} <!-- Ukládám si jméno do proměné a v if kontroluji -->
{? $soucet = $items->celkem + $soucet} <!-- Sčítáme peníze -->
{/if}

{/foreach}

<!-- Ve výsledku dostanu viz níže, ale potřebuji tam ještě dostat na konci ukončení tabulky, tbody a vložit celkový součet na konci do tfoot -->

<table>
 <thead>
  <tr>
   <th>Jméno</th>
   <th>Peníze</th>
  </tr>
 </thead>

 <tbody>
  <tr>
   <td>Petr Novák</td>
   <td>10</td>
  </tr>
  <tr>
   <td>Petr Novák</td>
   <td>20</td>
  </tr>

<table>
 <thead>
  <tr>
   <th>Jméno</th>
   <th>Peníze</th>
  </tr>
 </thead>

 <tbody>
  <tr>
   <td>Karel Novák</td>
   <td>10</td>
  </tr>
  <tr>
   <td>Karel Novák</td>
   <td>20</td>
  </tr>

<!-- Potřebuji -->

<table>
 <thead>
  <tr>
   <th>Jméno</th>
   <th>Peníze</th>
  </tr>
 </thead>

 <tbody>
  <tr>
   <td>Petr Novák</td>
   <td>10</td>
  </tr>
  <tr>
   <td>Petr Novák</td>
   <td>20</td>
  </tr>
 </tbody>
 <tfoot>
  <tr>
   <td>Celkem 30,-</td>
  </tr>
 </tfoot>
</table>

<table>
 <thead>
  <tr>
   <th>Jméno</th>
   <th>Peníze</th>
  </tr>
 </thead>

 <tbody>
  <tr>
   <td>Karel Novák</td>
   <td>10</td>
  </tr>
  <tr>
   <td>Karel Novák</td>
   <td>20</td>
  </tr>
 </tbody>
 <tfoot>
  <tr>
   <td>Celkem 30,-</td>
  </tr>
 </tfoot>
</table>
vvoody
Člen | 910
+
0
-

Jejda :D neprogramuj v sablone, presun to aspon do presenteru a najlepsie rovno do modelu. Mal by ti vracat uz data vo tvare npr:

array(
	array(
		'jmeno' => 'Petr Novák',
		'penize' => array(10,20,30),
		'celkem' => 60
	),
	array(
		'jmeno' => 'Karel Novák',
		'penize' => array(10,15,20),
		'celkem' => 45
	{
);

a v sablone uz prehladnejsie

<table n:foreach="$data as $person">
	<thead>
		<tr>
			<th>Jméno</th>
			<th>Peníze</th>
		</tr>
	</thead>
	<tbody>
		<tr n:foreach="$person['penize'] as $penize">
			<td>{$person['jmeno']}</td>
			<td>{$penize}</td>
		</tr>
	</tbody>
	<tfoot>
		<tr>
			<td>Celkem {$person['celkem']},-</td>
		</tr>
	</tfoot>
</table>
TheNEoo
Člen | 75
+
0
-

vvoody napsal(a):

Jejda :D neprogramuj v sablone, presun to aspon do presenteru a najlepsie rovno do modelu. Mal by ti vracat uz data vo tvare npr:

Tak jsem to prepsal do toho modelu a vystup z modelu je to vicerozmerne pole i se souctem. Vypada ve vysledku stejne, jako to tve.

Ale vubec jsem zatim nepochopil, jak se ted pouzije ten n:foreach v table ve vicerozmernem poli, s tim jsem jeste nepracoval.

Dale si myslim, ze cely ten kod se bude vykonavat porad dokola, jak se bude ze sablony volat foreach, ktery je spojen v render metode s modelem. Takze se bude muset prepsat i toto si myslim:

public function renderDefault(){
  $this->template->itemsCesty = $this->context->createVypis()->findCesty(); // dle me se bude kod v modelu vykonavat pokazde, provede-li foreach z latte jeden cyklus. Takze upravit ?
}

vysledek v modelu vypada takto:
Urcite to pujde napsat lepe, ale ja se to vse ucim, nic jineho me zatim nenapadlo.

public function findCesty() {


            $jmeno = '';
            $i = 0;

            foreach($this->connection->query('SELECT * FROM is_cesty ORDER BY jmeno') as $item){

                if($jmeno != $item->jmeno){

                   $data['jmeno'] = $item->jmeno;
                   $data['datum'][] = $item->datum;
                   $data['pocatek'][] = $item->pocatek;
                   $data['konec'][] = $item->konec;
                   $data['ucel_cesty'][] = $item->ucel_cesty;
                   $data['km'][] = $item->km;
                   $data['stravne'][] = $item->stravne;
                   $data['poznamka'][] = $item->poznamka;
                   $data['celkem'][] = $item->celkem;

                   $data['soucet'] = $item->celkem;

                   if($i != $i){
                      $data['soucet'] = 0;
                   }

                   $i++;

                   $vystup[$i] = $data;

                }else{

                   $data['datum'][] = $item->datum;
                   $data['pocatek'][] = $item->pocatek;
                   $data['konec'][] = $item->konec;
                   $data['ucel_cesty'][] = $item->ucel_cesty;
                   $data['km'][] = $item->km;
                   $data['stravne'][] = $item->stravne;
                   $data['poznamka'][] = $item->poznamka;
                   $data['celkem'][] = $item->celkem;

                   $data['soucet'] = $item->celkem + $data['soucet'];

                   $vystup[$i] = $data;
                }

              $jmeno = $item->jmeno;

            }

         return $vystup;
}

Editoval TheNEoo (14. 5. 2012 17:33)

vvoody
Člen | 910
+
0
-

aha :) no v navrhu databazi mas jednu vec nedoladenu a to stlpec ‚jmeno‘ – mal by to byt idendifikator – cudzi kluc do zvlast tabulky, ktora by mala obsahovat mená všetkych ludi (pomenujme ju ‚jmena‘ a zadefinujme stlpce ‚id‘ a ‚jmeno‘) a taktiez by som pre optimalizaciu do tejto tabulky dal aj stlpec soucet. Pribudla by ti jedna starost, vzdy ked budes pridavat riadok do tabulky ‚is_cesty‘ tak zaktualizujes prislusny soucet v tabulke ‚jmena‘. No ale na druhu stranu odpadne ti jedna vecsia starost, pri kazdom zobrazeni tabulky nebudes musiet ten sucet ratat. Jo a taktiez tvoj navrh nepocita v pripadom keby mali dvaja ludia rovnake meno, merglo by ich to dokopy co asi nechces.

ak sa na to teda das tak znova v bodoch:

  1. zduplikuj si pre istotu tabulku ‚is_cesty‘
  2. vytvor tabulku ‚jmena‘ so stlpcami ‚id‘ (integer, auto increment, not null), ‚jmeno‘ (varchar) a ‚suma‘ (int/float/decimal podla potreby)
  3. naplnime ‚jmena‘ jednym dotazom (bude to z hlavy tak pozor :D)

INSERT INTO jmena (jmeno,suma) VALUES(SELECT jmeno,SUM(penize) FROM is_cesty GROUP BY jmeno);
ale pre istotu najskorej spusti v phpmyadmin/admineri
SELECT jmeno,SUM(penize) FROM is_cesty GROUP BY jmeno;

  1. dostaneme idcka z tabulky ‚jmena‘ do tabulky ‚is_cesty‘

UPDATE is_cesty, set is_cesty.jmeno=jmena.id WHERE is_cesty.jmeno=jmena.jmeno;

  1. teraz pretypuj ten stlpec is_cesty.jmeno z toho co tam mas (asi varchar) na to co si pouzil pre jmena.id (integer, not null, ale auto increment NIE!)
  2. jo a ak chces, dobre je dodrovat nejaku konvenciu nazvov cudzich klucov cize zmenit nazov stlpca is_cesty.jmeno na trebars is_cesty.jmena_id
  3. hotovo podme na aplikaciu

Ak si vsimnes priklad v dokumentacii tak v tvojom pripade to bude nieco podobne:

<table n:foreach="$jmena as $jmeno">
        <thead>
		<tr>
			<th colspan="...">{$jmeno->jmeno}</th>
		</tr>
                <tr>
                        <th>Datum</th>
                        <th>Peníze</th>
                        <th>Ucel cesty</th>
			...
                </tr>
        </thead>
        <tbody>
                <tr n:foreach="$jmeno->related('is_cesty','jmeno_id') as $cesta">
                        <td>{$cesta->datum}</td>
                        <td>{$cesta->penize}</td>
                        <td>{$cesta->ucel_cesty}</td>
			...
                </tr>
        </tbody>
        <tfoot>
                <tr>
                        <td colspan="...">Celkem {$jmeno->suma},-</td>
                </tr>
        </tfoot>
</table>

$jmena – $database->table(‚jmena‘);
$jmeno – riadok z tabulky jmena
$cesta – riadok z tabulky is_cesty

TheNEoo
Člen | 75
+
0
-

ok neni problem to predelat id usera samozrejmne mam tak to malicko jen predelam to je na chvilku pak se pustim dal sql slozim a pak dam vedet vysledek.

akce edit add a delete me netrapi jelikoz jsou to jen vypisy.

Editoval TheNEoo (14. 5. 2012 19:05)

TheNEoo
Člen | 75
+
0
-

vvoody napsal(a):

aha :) no v navrhu databazi mas jednu vec nedoladenu a to stlpec ‚jmeno‘ – mal by to byt idendifikator – cudzi kluc do zvlast tabulky, ktora by mala obsahovat mená všetkych ludi (pomenujme ju ‚jmena‘ a zadefinujme stlpce ‚id‘ a ‚jmeno‘) a taktiez by som pre optimalizaciu do tejto tabulky dal aj stlpec soucet. Pribudla by ti jedna starost, vzdy ked budes pridavat riadok do tabulky ‚is_cesty‘ tak zaktualizujes prislusny soucet v tabulke ‚jmena‘. No ale na druhu stranu odpadne ti jedna vecsia starost, pri kazdom zobrazeni tabulky nebudes musiet ten sucet ratat. Jo a taktiez tvoj navrh nepocita v pripadom keby mali dvaja ludia rovnake meno, merglo by ich to dokopy co asi nechces.

ak sa na to teda das tak znova v bodoch:

  1. zduplikuj si pre istotu tabulku ‚is_cesty‘
  2. vytvor tabulku ‚jmena‘ so stlpcami ‚id‘ (integer, auto increment, not null), ‚jmeno‘ (varchar) a ‚suma‘ (int/float/decimal podla potreby)
  3. naplnime ‚jmena‘ jednym dotazom (bude to z hlavy tak pozor :D)

INSERT INTO jmena (jmeno,suma) VALUES(SELECT jmeno,SUM(penize) FROM is_cesty GROUP BY jmeno);
ale pre istotu najskorej spusti v phpmyadmin/admineri
SELECT jmeno,SUM(penize) FROM is_cesty GROUP BY jmeno;

  1. dostaneme idcka z tabulky ‚jmena‘ do tabulky ‚is_cesty‘

UPDATE is_cesty, set is_cesty.jmeno=jmena.id WHERE is_cesty.jmeno=jmena.jmeno;

  1. teraz pretypuj ten stlpec is_cesty.jmeno z toho co tam mas (asi varchar) na to co si pouzil pre jmena.id (integer, not null, ale auto increment NIE!)
  2. jo a ak chces, dobre je dodrovat nejaku konvenciu nazvov cudzich klucov cize zmenit nazov stlpca is_cesty.jmeno na trebars is_cesty.jmena_id
  3. hotovo podme na aplikaciu

Ahoj, tak jsem nad tim premyslel co a jak ma byt a docela v tom ted mam gulas. Uvedu na prikladech.

v modelu

public function findCesty(){
       $this->connection->query('SELECT cesta.* FROM is_cesty AS cesta INNER JOIN is_uzivatel ON cesta.ridic = is_uzivatel.id ORDER BY cesta.ridic');
// doufam ze sem to napsal dobre, je to z hlavy.

/* is_uzivatel nese id a jmeno uzivatele
 * is_cesty -> ridic obsahuje id jmena uzivatele ktery se nacte z is_uzivatel
 * Nevim, jestli mohu tento zapis pouzit na ten foreach na ktery me navadis :-) ale asi ne a vubec mi to nejde ted do hlavy
 */

}

v presenteru

public function renderDefault(){
       $this->template->itemsCesty = $this->context->createVypisy->findCesty();
}
//Tohle asi zustane stejne (mozna, nevim), z dokumentace jsem to moc nepochopil, bo spise vubec.

a o .latte se nebudu ani zminovat pac nevim co a jak tam.
Nerozumim tomu zapisu, jak ty data to bere rovna a tak.

Ak si vsimnes priklad v dokumentacii tak v tvojom pripade to bude nieco podobne:

<table n:foreach="$jmena as $jmeno">
        <thead>
		<tr>
			<th colspan="...">{$jmeno->jmeno}</th>
		</tr>
                <tr>
                        <th>Datum</th>
                        <th>Peníze</th>
                        <th>Ucel cesty</th>
			...
                </tr>
        </thead>
        <tbody>
                <tr n:foreach="$jmeno->related('is_cesty','jmeno_id') as $cesta">
                        <td>{$cesta->datum}</td>
                        <td>{$cesta->penize}</td>
                        <td>{$cesta->ucel_cesty}</td>
			...
                </tr>
        </tbody>
        <tfoot>
                <tr>
                        <td colspan="...">Celkem {$jmeno->suma},-</td>
                </tr>
        </tfoot>
</table>

$jmena – $database->table(‚jmena‘);
$jmeno – riadok z tabulky jmena
$cesta – riadok z tabulky is_cesty

Editoval TheNEoo (15. 5. 2012 19:18)