I am struggling with an array I want to turn into a nested < select >
I need:
<select>
<option value="1">Top1</option>
<option value="2">Top2</option>
<option value="9">Top3</option>
<option value="7"> - - Top3.1</option>
<option value="5"> - - Top3.2</option>
<option value="12">- - - - Top3.2.1</option>
<option value="6">Top4</option>
<option value="4">Top5</option>
<option value="8"> - - Top5.1</option>
<option value="3"> - - Top5.2</option>
I can't work with optgroup, because everything is selectable. As far as I know, you can't select optgroup labels.
My array looks like this:
[44] => Array
(
[id] => 1
[name] => Test
[slug] => test
[parent] => 0
)
[45] => Array
(
[id] => 2
[name] => Test-Sub
[slug] => test-sub
[parent] => 1
)
[46] => Array
(
[id] => 3
[name] => Test-Sub-Sub
[slug] => test-sub-sub
[parent] => 2
)
I am feeling like I have tried dozens of variantions, but I can't build my form select right.
That was my last try:
function toDropdown($arr)
{
foreach ($arr as $row) {
$cat[$row['id']] = $row['name'];
if ($row['parent'] != 0) {
$cat[$row['id']] = '--' . $row['name'];
}
}
return $cat;
}
But this way, it is ordered by the ID and the nesting loses its meaning.
I'll try to go on, but if someone can help I appreciate any help!
EDIT: PHP Data
My function to get all categories from the DB:
function get_categories($parent = 'all')
{
$this->db->select('categories.id, categories.name, categories.slug, categories.parent');
$this->db->from('categories');
if ($query = $this->db->get())
{
return $query->result_array();
}
return FALSE;
}
My view.php, where I output all data:
$query = $this->datei_model->get_categories('all');
foreach ($query as $row)
{
$parents[] = $row;
}
$tree = buildTree($parents);
print("<select>\n");
printTree($tree);
print("</select>");
Try this;
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>");
Output;
<select>
<option value='1'>Test 1</option>
<option value='2'>- Test 1.1</option>
<option value='3'>- Test 1.2</option>
<option value='4'>-- Test 1.2.1</option>
<option value='5'>-- Test 1.2.2</option>
<option value='6'>--- Test 1.2.2.1</option>
<option value='7'>Test 2</option>
<option value='8'>- Test 2.1</option>
</select>
And in your case;
<select>
<option value='1'>Baden-Württemberg</option>
<option value='2'>- DMP-Verträge</option>
<option value='50'>- Sprechstundenbedarf</option>
<option value='52'>- Richtgrößen</option>
<option value='53'>- Prüfungen</option>
<option value='54'>- DMP-Verträge</option>
<option value='55'>- Sonstige Verträge</option>
<option value='3'>Berlin</option>
<option value='62'>- DMP-Verträge</option>
<option value='63'>- Prüfungen</option>
<option value='64'>- Richtgrößen</option>
<option value='65'>- Sonstige Verträge</option>
<option value='66'>- Sprechstundenbedarf</option>
<option value='4'>Brandenburg</option>
<option value='67'>- DMP-Verträge</option>
<option value='68'>- Prüfungen</option>
<option value='69'>- Richtgrößen</option>
<option value='70'>- Sonstige Verträge</option>
<option value='71'>- Sprechstundenbedarf</option>
<option value='5'>Bremen</option>
<option value='72'>- DMP-Verträge</option>
<option value='73'>- Prüfungen</option>
<option value='74'>- Richtgrößen</option>
<option value='75'>- Sonstige Verträge</option>
<option value='76'>- Sprechstundenbedarf</option>
<option value='7'>Hessen</option>
<option value='6'>Hamburg</option>
<option value='8'>Mecklenburg-Vorpommern</option>
<option value='9'>Niedersachsen</option>
<option value='10'>Nordrhein</option>
<option value='11'>Rheinland-Pfalz</option>
<option value='12'>Saarland</option>
<option value='13'>Sachsen</option>
<option value='14'>Sachsen-Anhalt</option>
<option value='15'>Schleswig-Holstein</option>
<option value='16'>Thüringen</option>
<option value='17'>Westfalen-Lippe</option>
<option value='51'>Richtgrössen</option>
<option value='56'>Bayern</option>
<option value='57'>- DMP-Verträge</option>
<option value='58'>- Prüfungen</option>
<option value='59'>- Richtgrößen</option>
<option value='60'>- Sonstige Verträge</option>
<option value='61'>- Sprechstundenbedarf</option>
</select>
this just litle change of the original code that answered by Qeremy
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 (isset($t['_children'])) {
printTree($t['_children'], $r+1, $t['parent']);
}
}
}
Now the dashed name works great.
*sorry for my english
In Qeremy's code just change this line and the code will not be giving you any incrementing dashes
$t['parent'] == $p
to ->
$t['parent'] == 0