Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Hello I find php function that outputs html select list from array.

function buildTree(Array $data, $parent = 0) {
    $tree = array();
    foreach ($data as $d) {
        if ($d['parent'] == $parent) {
            $children = buildTree($data, $d['id']);
            // set a trivial key
            if (!empty($children)) {
                $d['_children'] = $children;
            }
            $tree[] = $d;
        }
    }
    return $tree;
}


$rows = array(
    array ('id' => 1, 'name' => 'Test 1', 'parent' => 0),
    array ('id' => 2, 'name' => 'Test 1.1', 'parent' => 1),
    array ('id' => 3, 'name' => 'Test 1.2', 'parent' => 1),
    array ('id' => 4, 'name' => 'Test 1.2.1', 'parent' => 3),
    array ('id' => 5, 'name' => 'Test 1.2.2', 'parent' => 3),
    array ('id' => 6, 'name' => 'Test 1.2.2.1', 'parent' => 5),
    array ('id' => 7, 'name' => 'Test 2', 'parent' => 0),
    array ('id' => 8, 'name' => 'Test 2.1', 'parent' => 7),
);

$tree = buildTree($rows);
// print_r($tree);

function printTree($tree, $r = 0, $p = null) {
  foreach ($tree as $i => $t) {
    $dash = ($t['parent'] == 0) ? '' : str_repeat('-', $r) .' ';
    printf("\t<option value='%d'>%s%s</option>\n", $t['id'], $dash, $t['name']);
    if ($t['parent'] == $p) {
        // reset $r
        $r = 0;
    }
    if(isset($t['_children'])){
        printTree($t['_children'], ++$r, $t['parent']);
    }
  }
}


print("<select>\n");
printTree($tree);
print("</select>");

but I need to rewrite to return result like this:

$select = "<select>";
$select .= printTree($list);
$select .= "</select>";

echo $select;
// or better
return $select;

The problem is with recursion, solution is to fill each option in array, but I don't know how to do that in recursive functions, and also

printf("\t<option value='%d'>%s%s</option>\n", $t['id'], $dash, $t['name']);

prints directly when foreach loop iterate.

Thanks.

share|improve this question
add comment

1 Answer

So i figure out where was my mistake, that was simply because i fill an array with html option tag eg.

<option value="0">Start</option>

but with php function print_r() i see nothing in array value exepts when i inspect DOM element.

so here is my final solution: this function fill values in multi dimensional array, to further needs

# edited printTree() function, renamed to toSEL()
# $array - data array like above, 
# $r - to correct iterate, $p - parent id, 
# $currentID - what id is selected

function toSEL($array, $r = 0, $p = null, $currentID=null){
    foreach($array as $value){
        $dash = ($value[parent] == 0) ? '' : str_repeat('-', $r) .' ';
        if($value[id]==$currentID){
            $html[] = '<option value="'.$value[id].'" selected="selected">'.$dash.$value[name].'</option>';
        }else{
            $html[] = '<option value="'.$value[id].'">'.$dash.$value[name].'</option>';
        }

        if($value['parent'] == $p){
            // reset $r
            $r = 0;
        }
        if(!empty($value[children])){
            $html[] = toSEL($value[children], ++$r, $value[parent], $currentID);

        }

    }

    return $html;
}

to convert from multi dimensional array to one dimension

$aNonFlat = toSEL($list, 0, null, $currentID);

$result = array();
array_walk_recursive($aNonFlat,function($v, $k) use (&$result){ $result[] = $v; });

then if needs to output HTML use some simple loop.

$html = '<select>';
foreach($result as $res){
    $html .= $res;  
}
$html .='</select>';
echo $html;
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.