Jump to content

Array to UL LI list


cnkt

Recommended Posts

i have got a array like this:

 

$a = array(
array('title' => 'ROOT 1', 'depth' => '0'),
array('title' => 'CHILD 1 OF ROOT 1', 'depth' => '1'),
array('title' => 'CHILD 2 OF ROOT 1', 'depth' => '1'),
array('title' => 'CHILD 1 OF CHILD 2', 'depth' => '2'),
array('title' => 'ROOT 2', 'depth' => '0'),
);

 

when i output this array with this function:

 

function generateList($arr) {
echo '<ul>';

foreach ($arr as $item) {
	echo '<li>' . str_repeat('-', $item['depth']) . $item['title'] . '</li>';
}

echo '</ul>';
}

 

i get this:

 

ROOT 1
-CHILD 1 OF ROOT 1
-CHILD 2 OF ROOT 1
--CHILD 1 OF CHILD 2
ROOT 2

 

but what i want is a nested XHTML valid UL LI like:

 

<ul>
<li>ROOT 1
<ul>
<li>CHILD 1 OF ROOT 1</li>
</ul>
</li>
</ul>

thanks.

Link to comment
Share on other sites

I think you're going to struggle with this using an array in the way you are -- you need to store the relationship between the child node and the parent node. For things like this, i usually store the parent node as the key of the array, the value of which is all the children. Something like this:

 

$array['root'] = array('ROOT1','ROOT2');
$array['ROOT1'] = array('CHILD 1 OF ROOT 1','CHILD 2 OF ROOT 1');
$array['CHILD 2 OF ROOT 1'] = array('CHILD 1 OF CHILD 2');

 

Then, you can use a recursive function like so:

 

function listElements($array,$index='root'){
echo '<ul>';
foreach($array[$index] as $item){
	echo '<li>';
	echo $item;
	if(isset($array[$item])){
		listElements($array,$item);
	}
	echo '</li>';
}
echo '</ul>';
}

listElements($array);

 

Also, by doing this in a recursive manner, you don't limit yourself with regard to the depth of the list.

 

 

Link to comment
Share on other sites

would it not be more beneficial to store children as an array under the parent node?

 

something like

<?php
$a = array(
array('title' => 'ROOT 1', 'children' => array(
    array('title' => 'CHILD 1 OF ROOT 1', 'children' => NULL),
    array('title' => 'CHILD 2 OF ROOT 1', 'children' => array( 
        array('title' => 'CHILD 1 OF CHILD 2', 'children' => NULL)
                )
            )
array('title' => 'ROOT 2', 'children' => NULL),
);
?>

 

can then use a recursive function to spit out the nested list

 

 

Link to comment
Share on other sites

would it not be more beneficial to store children as an array under the parent node?

 

Quite possibly. It would certainly be more representative of the actual data. It's just, depending on how you store your data, it might be easier to produce my representation of the data rather than yours. If, for example, we just store the parent node alongside the child node in a database, it would be very easy to select all the rows once and run through it producing my array. Unless im missing something simple, i think it'd be more difficult to work out where each row belongs in your array. On the other hand, i suspect your representation would be easier to search and would consume less memory, since we're only passing part of the array into the recursive function each time we call it.

Link to comment
Share on other sites

I'm sorry but the array is not creating by me. We are a team and i'm only responsible of the VIEW part of project. I can't say to developer "give me a nested array". i have to do the UL LI with the DEPTH field of array.

Link to comment
Share on other sites

I'm sorry but the array is not creating by me. We are a team and i'm only responsible of the VIEW part of project. I can't say to developer "give me a nested array". i have to do the UL LI with the DEPTH field of array.

 

I don't see how that's possible. For example. If i tell you a particular element has a depth of 2, can you tell me which parent it has? Sure you can tell me it's parent has a depth of 1, but you can't tell me which parent it belongs to.

 

Unless of course the ordering is guaranteed such that if the depth increases you know that the child belongs to the most recent node with a depth one less than it.

Link to comment
Share on other sites

Hmm...

 

$a = array(
array('title' => 'ROOT 1', 'depth' => '0'),
array('title' => 'CHILD 1 OF ROOT 1', 'depth' => '1'),
array('title' => 'CHILD 2 OF ROOT 1', 'depth' => '1'),
array('title' => 'CHILD 1 OF CHILD 2', 'depth' => '2'),
array('title' => 'ROOT 2', 'depth' => '0'),
);

$prevDepth = null;

foreach ($a as $element) {
if (null === $prevDepth || $element['depth'] > $prevDepth) {
	echo '<ul>';
}
else if ($element['depth'] == $prevDepth) {
	echo '</li>';
}
else if ($element['depth'] < $prevDepth) {
	echo str_repeat('</li></ul>', $prevDepth - $element['depth']) . '</li>';
}

echo "<li>{$element['title']}";

$prevDepth = (int) $element['depth'];
}
echo str_repeat('</li></ul>', $prevDepth+1);

 

Output:

<ul><li>ROOT 1<ul><li>CHILD 1 OF ROOT 1</li><li>CHILD 2 OF ROOT 1<ul><li>CHILD 1 OF CHILD 2</li></ul></li></ul></li><li>ROOT 2</li></ul>

which is valid (X)HTML.

Link to comment
Share on other sites

Hmm...

 

$a = array(
array('title' => 'ROOT 1', 'depth' => '0'),
array('title' => 'CHILD 1 OF ROOT 1', 'depth' => '1'),
array('title' => 'CHILD 2 OF ROOT 1', 'depth' => '1'),
array('title' => 'CHILD 1 OF CHILD 2', 'depth' => '2'),
array('title' => 'ROOT 2', 'depth' => '0'),
);

$prevDepth = null;

foreach ($a as $element) {
if (null === $prevDepth || $element['depth'] > $prevDepth) {
	echo '<ul>';
}
else if ($element['depth'] == $prevDepth) {
	echo '</li>';
}
else if ($element['depth'] < $prevDepth) {
	echo str_repeat('</li></ul>', $prevDepth - $element['depth']) . '</li>';
}

echo "<li>{$element['title']}";

$prevDepth = (int) $element['depth'];
}
echo str_repeat('</li></ul>', $prevDepth+1);

 

Output:

<ul><li>ROOT 1<ul><li>CHILD 1 OF ROOT 1</li><li>CHILD 2 OF ROOT 1<ul><li>CHILD 1 OF CHILD 2</li></ul></li></ul></li><li>ROOT 2</li></ul>

which is valid (X)HTML.

 

thanks. your method works.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.