Autor Zpráva
sir_lamoid
Profil
Zdravím,

Mám menší problém s řazením položek menu.
Mám tabulku:

-
CREATE TABLE IF NOT EXISTS `menu` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `popisek` text NOT NULL,
  `id_nadrazena` int(11) NOT NULL,
  `uroven` int(11) NOT NULL,
  `top` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=16 ;

INSERT INTO `menu` (`id`, `popisek`, `id_nadrazena`, `uroven`, `top`) VALUES
(1, 'Chorvatsko', 1, 0, 1),
(2, 'Slovensko', 2, 0, 2),
(3, 'Drvenik', 1, 1, 1),
(4, 'Katarina', 3, 2, 1),
(5, 'Kuka', 3, 2, 1),
(6, 'Apollon', 3, 2, 1),
(7, 'Camp dole', 1, 1, 1),
(8, 'Karavan', 7, 2, 1),
(9, 'Chata', 7, 2, 1),
(10, 'Stan', 7, 2, 1),
(11, 'Bratislava', 2, 1, 2),
(12, 'Apartman', 11, 2, 2),
(13, 'Hotel', 7, 2, 1),
(15, 'Ňuf', 3, 2, 1);

kde:
TOP je nejvyšší položka menu takže u první úrovně je to vlastní id dané položky a u druhé a třetí to je id nadřazené.
ID_NADRAZENA je id nadřazené položky ala u první úrovně vlatní id u druhé úrovně je to id nadřazené TOP urovně a u třetí je to nadřazené ID druhé úrovně
uroven je číselný údaj o urovni(0 - 1uroveň, 1 - 2uroveň, 2 - 3uroveň)

nejvíce vysvětlí asi obrázek

položka Ňuf má být ale zařazena v Drveniku...
Můj prozatimní skript v PHP:
$sql=dibi::query('SELECT * FROM menu ORDER BY top ASC');
?>
<table>
<thead>
    <th>Položky</th>
    <th>Akce</th>
</thead>
<?php
while ($row = $sql->fetch()){
    if($row['uroven']==0){
        $oddel="";
    }
    elseif($row['uroven']==1){
        $oddel="&nbsp;&nbsp;";
    }
    else{
        $oddel="&nbsp;&nbsp;&nbsp;&nbsp;";
    }

?>
<tr>
    <td><?php echo $oddel; echo $row['popisek'];?></td>
    <td><a href="?page=edit&id=<?php echo $row['id'];?>"><img src="../css/img/upravit.fw.png" /></a>
    <a href="?page=del&id=<?php echo $row['id'];?>"><img src="../css/img/vymazat.fw.png" /></a></td>
</tr>
<?php
}
?>

a pro přidávání do db:
if($page=="add"){
    $sql=dibi::query('SELECT * FROM menu WHERE [uroven] < %i', "2");
    ?>
    <form action="?page=add_script" method="POST">
    <input type="text" name="jmeno" placeholder="Název položky" />
    <label for="uroven">Úroveň:</label>
    <select size="3" name="uroven" id="uroven">
        <option value="0">-- Vyberte --</option>
        <option value="0">První</option>
        <option value="1">&nbsp;&nbsp;Druhá</option>
        <option value="2">&nbsp;&nbsp;&nbsp;&nbsp;Třetí</option>
    </select>
    <select size="1" name="id_nadrazena">
    <option value="0">-- Vyberte --</option>
    <?php
    while($row = $sql->fetch()){?>
    
        <option value="<?php echo $row['id'];?>"><?php echo $row['popisek'];?></option>
        <?php
    }
    ?>
    </select>
    <input type="submit" class="btn btn-success btn-sm" value="Přidat novou položku" />
    </form>
<?php
}
elseif($page=="add_script"){
    if($_POST['uroven']==0){
        $result = dibi::query('SELECT id FROM menu ORDER BY id DESC LIMIT 1');
        $last = $result->fetchSingle();
        $id_nadrazena=($last+1);
        $top=$id_nadrazena;
    }
    elseif($_POST['uroven']==1){
        $id_nadrazena=$_POST['id_nadrazena'];
        $result = dibi::query('SELECT id_nadrazena FROM menu WHERE [id] = %i', $id_nadrazena);
        $id = $result->fetchSingle();
        $top=$id;
    }
    else{
        $id_nadrazena=$_POST['id_nadrazena'];
        $result = dibi::query('SELECT id_nadrazena FROM menu WHERE [id] = %i', $id_nadrazena, 'and [uroven] = %i', "1");
        $id = $result->fetchSingle();
        $top=$id;
    }
   $arr = array(
    'popisek'  => $_POST['jmeno'],
    'id_nadrazena' => $id_nadrazena,
    'uroven' => $_POST['uroven'],
    'top' => $top
    );
    dibi::query('INSERT INTO [menu]', $arr);
    header("Location: menu.php?message_type=complete&message=Položka menu přidána");
}
Anonymní
Profil *
Nevím jak ostatním, ale mě takovýhle návrh databáze příjde jako úplný nesmysl, už jenom z důvodu, že prostě pak vznikaj takovéhle problémy a člověk se v tom prostě nevyzná. Předělej celý návrh, vytvoř si tři tabulky v první měj totálně nadřazenou položku(pokud jsem to pochopil správně tak v tvém případě je to daný stát - Slovensko, Chorvatsko), pak další tabulku která bude podřazená předešlé položce(v tomhle případě nějaký region či co to je a s nadřazenou položkou to prostě propoj se státem přes ID) a pak poslední tabulku kde bude podřazená položka všemu ostatnímu(v tvém případě přímo nějaký přesný místo či co to je a prostě to propoj jen s nadřazenou položkou, která je o 1 stupeň výše, s nejvyšší položkou to již propojovat nemusíš, protože nadřazená položka již propojená je)
Fisir
Profil
Reaguji na Anonymního:
Tohle je nesmysl. A když bude potřeba další úroveň? Bude se vytvářet další tabulka? Struktura databáze by se neměla měnit v závislosti na vkládaných datech (divně řečeno), dle mého názoru je tvůj návrh databáze špatný, sir_lamoidův naopak správný.
Jenicek
Profil
teda chvilku mi trvalo než jsem pochopil jak to vůbec myslíš...
osobně také zastávám názor že když s tím týden nebudeš dělat tak se z toho pak picneš...
no asi hledáš tento výpis?
SELECT * FROM (SELECT * FROM menu ORDER BY `menu`.`id_nadrazena` ASC) AS menu ORDER BY `menu`.`top` ASC



Fisir:
3 databáze je nesmysl ale tento zápis je dost nepřeledný :)
sir_lamoid
Profil
Jenicek:


Nepomohlo :( jak bys navrhoval ty to rozložení databáze :( Máme tam naházeno asi 200 zájezdů :(


Nebude nejjdenodušší udělat ještě jeden sloupec pořadí a podle něj to prostě řadit?
Kajman
Profil
sir_lamoid:

Pokud vypisujete celé menu, bude nejjednodušší načíst data z db pro celé menu do php pole. A to pak zpracovat.

Zjednodušeně něco jako
<?php
function menu_part($id, $potomci, $polozky, $level=0)
{
    $output='';
    if(isset($polozky[$id]))
    {
        $output.='<tr><td>'.str_repeat('&nbsp;&nbsp;',$level).htmlspecialchars($polozky[$id]['popisek']).'</td></tr>';
    }
    if(isset($potomci[$id]) && $level<50)
    {
        foreach($potomci[$id] as $potomek)
        {
            $output.=menu_part($potomek, $potomci, $polozky, $level+1);
        }
    }
    return $output;
}
$sql=dibi::query('SELECT * FROM menu ORDER BY id_nadrazena ASC, top ASC');
$potomci=$polozky=array();
while ($row = $sql->fetch())
{
    $potomci[($row['id_nadrazena']==$row['id']?0:$row['id_nadrazena'])][]=$row['id'];
    $polozky[$row['id']]=$row;
}
echo menu_part(0, $potomci, $polozky);
sir_lamoid
Profil
Kajman:
Nenačítám celé menu, mám 2 menu . Jedno horizontální kde jsou vypsány jen položky 1 urovne(slovensko, Chorvatsko...) a pak u každé položky mám druhé menu s položkama 2 a 3 urovně
Ale děkuji za pomoc při řešení. Nakonec jsem to udělal pomocí pořadových čísel

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: