Jump to content

[SOLVED] help with recursive function


digitalgod

Recommended Posts

hey guys,

 

I'm trying to build a recursive function to display all of my categories and subcategories but I keep running into some logic problems...

 

what I basically need it to do is echo something like this

<li><span class="folder">Folder 1</span></li>
  <li><span class="folder">Folder 2</span>
    <ul>
      <li><span class="folder">Subfolder 2.1</span>
        <ul id="folder21">
          <li><span class="folder">Subfolder 2.1.1</span></li>
        </ul>
      </li>
      <li><span class="folder">Subfolder 2.2</span></li>
    </ul>
  </li>

 

so main folder that don't have any children are between <li></li> tags, folders that do have children have <ul></ul> before the closing </li>

I can't figure this out and I know it shouldn't be that hard but it's getting late and I'm extremely tired...

 

this is what I have right now and it's no where near what I want it to do

 

function recursiveTree($parent, $level) {

   $result = mysql_query('SELECT * FROM image_category '.
			 'WHERE parent_id="'.$parent.'";');
   $result_count = mysql_num_rows($result);
   
   // display each child
   while ($row = mysql_fetch_array($result)) {
   $new_level = $level + 1;
  	   
   if ( $new_level == 1 )
   {
   	echo '<li><span class="folder">'.$row['title'].'<ul>';
   } else
   {
   	echo '<li><span class="folder">'.$row['title'];
	if ( $result_count == 1 || $result_count == $new_level )
	{
		echo '<ul>';
	} else
	{
		echo '</li></ul>';
	}
   }
   
   recursiveTree($row['image_category_id'], $level+1);
   }
} 

 

Link to comment
Share on other sites

function recursiveTree($parent) {

  $result = mysql_query('SELECT * FROM image_category '.
			 'WHERE parent_id="'.$parent.'";');
  $result_count = mysql_num_rows($result);
  
  // display each child
  echo '<ul>';
  while ($row = mysql_fetch_array($result)) {
      if ($parent !== $row['image_category_id']) { // or something else that changes and means that we are going a level deeper
   recursiveTree($row['image_category_id']);
      } else {
          echo '<li><span class="folder">' . $row['title'] . '</span></li>';
      }
  }
  echo '</ul>';
}

 

post your table fields

Link to comment
Share on other sites

hey ignace, that actually won't echo out anything because main folders have no parent_id so they're parent_id value is 0 if that makes any sense... That's why I had $level, to keep track of how deep it goes in one branch

 

that table image_category has

 

image_category_id | parent_id | title | description | created

 

 

 

Link to comment
Share on other sites

it's a pretty simple matter, but it can be tricky to nail down.  the solution is to wrap a <ul> around the entire list if it is a child of something, since all children have parents:

 

<?php
function recursiveTree($parent = 0) {

   // if this is a child, add a set of <ul> tags
   if ($parent > 0)
   {
      echo '<ul>';
   }

   $result = mysql_query('SELECT * FROM image_category '.
			 'WHERE parent_id="'.$parent.'";');
   
   // display each child
   while ($row = mysql_fetch_array($result)) {
  	echo '<li><span class="folder">'.$row['title'].'</span>';
  	recursiveTree($row['category_id']);
  	echo '</li>';
   }

   // if this is a child, finish off the <ul> tag
   if ($parent > 0)
   {
      echo '</ul>';
   }
}
?>

 

give that a whirl.  to be honest, i'm not incredibly experienced with recursives so i can't promise that will solve your problem.  worth a shot though.

Link to comment
Share on other sites

thanks akitchin! I've always hated recursives...

 

my only problem though is that it creates unnecessary markup ( I'm a neat freak as well as a web standards freak hehe) but I've lost so much time trying to get those damn <ul> tags to close at the right place that I don't really mind.

 

One question though, is there a way to keep the generated markup nice and clean, because right now it prints everything on one line and adding \n isn't helping...

Link to comment
Share on other sites

try adding chr(10) and chr(13) whenever you want a linebreak (and a tab character to move it across).  those two together are a newline and a return carriage.  some browsers need both to render the line break.

 

as for unnecessary markup, is that not what you wanted in terms of the <ul></ul> tags?  it (should) generate one set for each child, regardless of level.  is that not what it is spitting out?

Link to comment
Share on other sites

thanks for the tip!

 

Here I'll show you what I mean by unnecessary markup:

 

<ul id="browser" class="filetree">
  <li><span class="folder">main</span>
    <ul>
      <li><span class="folder">sub-main</span>
        <ul> <!-- unnecessary -->
        </ul> <!-- unnecessary -->
      </li>
    </ul>
  </li>
  <li><span class="folder">main #2</span>
    <ul>
      <li><span class="folder">test #2</span>
        <ul>
          <li><span class="folder">test #4</span>
            <ul>
              <li><span class="folder">test #5</span>
                <ul> <!-- unnecessary -->
                </ul> <!-- unnecessary -->
              </li>
            </ul>
          </li>
        </ul>
      </li>
      <li><span class="folder">test #3</span>
        <ul> <!-- unnecessary -->
        </ul> <!-- unnecessary -->
      </li>
    </ul>
  </li>
</ul>

Link to comment
Share on other sites

my bad - move the if() statement to below the query (but before the while loop) and check mysql_num_rows() on the resource to verify that it's got more than 0.  if it fails on either parent > 0 or num_rows > 0, then it shouldn't display <ul> (nor </ul>).

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.