Avatar billede soduno Novice
22. oktober 2012 - 04:10 Der er 6 kommentarer og
1 løsning

Php multilevel selectbox

Hejsa.

Jeg har lavet fået bikset noget kode sammen som laver en selectbox med multilevel submenu ting.
Dog kan jeg ikke finde ud af hvorfor den ikke sorterer det korrekt. Altså den lægger ikke undermenuerne under hovedmenuerne pænt som de skal under hinanden, men i en stor rodekasse. Hvad kan der være galt? :-)

<?php
                function _buildTree($data, $idParent, $indentSymbol, $level)
                    {
                        $cat = array();
                        foreach($data as $row){
                            if($row['cat_parent'] == $idParent){
                                if($indentSymbol AND $level > 0){
                                    $symbols = array_fill(0, $level, $indentSymbol);
                                    $cat[$row['cat_id']] = implode('', $symbols) . $row['cat_name'];
                                }else{
                                    $cat[$row['cat_id']] = $row['cat_name'];
                                }
                   
                                $cat = $cat + _buildTree($data, $row['cat_id'], $indentSymbol, $level++);
                            }
                        }
                        return $cat;
                    }
                   
                    $result = mysql_query("SELECT cat_id, cat_parent, cat_name FROM categories");
                   
                    $data = array();
                    while($row = mysql_fetch_assoc($result)){
                        $data[] = $row;
                    }
                   
                    $select = '<select>';
                   
                    foreach(_buildTree($data, 0, '-', 0) as $key=>$option){
                        $select .= '<option value=' . $key . '>' . $option . '</option>';
                    }
                   
                    $select .= '</select>';
                   
                    echo $select;
                   
            ?>
Avatar billede tjens Nybegynder
22. oktober 2012 - 23:12 #1
Kan det være fordi du ikke har nogen ORDER BY i din SQL?
Avatar billede inteeeL Nybegynder
22. oktober 2012 - 23:25 #2
Det har noget at gøre med opbygningen af dit data-array, men jeg tror dog ikke, at ORDER vil være løsningen her. Du skal i stedet først hente alle hovedkategorier (oplagre disse i data-arrayet), hvortil der efter hver hovedkategori tilføjes eventuelle underkategorier. Det vil sortere dit array, som du ønsker det. Det kunne se således ud:
<?php

function _buildTree($data, $idParent, $indentSymbol, $level) {
    $cat = array();
    foreach($data as $row){
        if($row['cat_parent'] == $idParent){
            if($indentSymbol AND $level > 0){
                $symbols = array_fill(0, $level, $indentSymbol);
                $cat[$row['cat_id']] = implode('', $symbols) . $row['cat_name'];
            }else{
                $cat[$row['cat_id']] = $row['cat_name'];
            }
   
            $cat = $cat + _buildTree($data, $row['cat_id'], $indentSymbol, $level++);
        }
    }
    return $cat;
}
 
$cat_res = mysql_query("SELECT cat_id, cat_parent, cat_name FROM categories WHERE cat_parent=0");

$data = array();
while($main_cat = mysql_fetch_assoc($cat_res)){
    $data[] = $main_cat;
    //Subcats
    $subcat_res = mysql_query("SELECT cat_id, cat_parent, cat_name FROM categories WHERE cat_parent=$main_cat[cat_id]");
    if(mysql_num_rows > 0) {
        while($sub_cat = mysql_fetch_assoc($cat_res)){
            $data[] = $sub_cat;
        }   
    }
}

$select = '<select>';

foreach(_buildTree($data, 0, '-', 0) as $key=>$option){
    $select .= '<option value=' . $key . '>' . $option . '</option>';
}

$select .= '</select>';

echo $select;

?>

Jeg vil dog anbefale, at du tager et kig på Oles glimrende artikel omkring prepared statements og mySQLi (http://www.eksperten.dk/guide/1480). Det vil øge sikkerheden betydeligt meget - den anvende API af mysql i ovenstående kode er efterhånden forældet og pivåben for angreb udefra. :-)
Avatar billede soduno Novice
23. oktober 2012 - 02:27 #3
#2 Jeg vil gerne tjekke op på prepared statements. Dog den kode du vedlagte virker ikke helt.
Den echo'er stadig kategorierne hulter til bulter, uden de er sammensat som undermenuer :/
Avatar billede inteeeL Nybegynder
24. oktober 2012 - 00:20 #4
Den skulle meget gerne sortere det således, at undermenuerne placeres under hovedmenuerne - uanset hvilken rækkefølge dataene udtrækkes i. Jeg har rodet lidt med det og testet det med arrays, og det så ud til at virke. Prøv nedenstående (jeg har rettet lidt i din funktion):
<?php

function _buildTree($data, $idParent, $indentSymbol, $level) {
    $cat = array();
    foreach($data as $row){
        if($row['cat_parent'] == $idParent){
            $cat[$row['cat_id']] = str_repeat($indentSymbol, $level).' '.$row['cat_name'];
            $cat = $cat + _buildTree($data, $row['cat_id'], $indentSymbol, $level+1);
        }
    }
    return $cat;
}
 
$cat_res = mysql_query("SELECT cat_id, cat_parent, cat_name FROM categories ORDER BY cat_id");

$data = array();
while($row = mysql_fetch_assoc($cat_res)){
    $data[] = $row;
}


$select = '<select>';

foreach(_buildTree($data, 0, '-', 0) as $key=>$option){
    $select .= '<option value=' . $key . '>' . $option . '</option>';
}

$select .= '</select>';

echo $select;

?>
Avatar billede soduno Novice
25. oktober 2012 - 10:07 #5
Fedt. Det virkede.  Tak. Post lige et svar Inteeel :)
Avatar billede inteeeL Nybegynder
25. oktober 2012 - 10:50 #6
Fejlen lå i måden, du forøgede værdien af $level på.
$level++ øger først værdien, næste gang den kaldes.
$level+1 øger værdien med det samme (med 1).
++$level er det samme som $level+1.

Godt det virkede, her er et svar. :-)
Avatar billede soduno Novice
25. oktober 2012 - 10:56 #7
Ahh ja, selvfølgelig. Tak for en forklaring, det er bedre man forstår ens egne fejl end ikke ;)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester