Search code examples
phpjqueryarrayslistnested-sortable

PHP array to ordered & nested HTML list


I'm using the jQuery nestedSortable plugin in a project. When a list item is moved, I serialize the array and save it to my db. I'm having trouble recreating the HTML list from the PHP array. Probably because it's late. :)

I have the following PHP array:

Array
(
    [list_4] => root
    [list_3] => 4
    [list_1303966373] => 3
    [list_1] => 1303966373
    [list_5] => 1
    [list_2] => 1
    [list_6] => root
)

It should make a list something like...

<ol>
<li id='list_4'>value 4
  <ol>
    <li id='list_3'>value 3
      <ol>
        <li id='list_1303966373'>value 1303966373
          <ol>
            <li id='list_1'>value 1
              <ol>
                <li id='list_5'>value 5</li>
                <li id='list_2'>value 2</li>
              </ol>
            </li>
          </ol>
        </li>
      </ol>
    </li>
  </ol>
</li>
<li id='list_6'>value 6</li>          
</ol>

(Ignore the values, they're just there for show.)

The HTML list could have any depth of nested lists.

My brain is dead and I cannot get it to work. Anyone have a suggestion? I'll owe you cookies for eternity. Also, a castle.

Thanks. :)


Solution

  • Here you have it (tested OK with your sample):

    <?php
      $tree = array(
        "list_4" => "root",
        "list_3" => "list_4",
        "list_1303966373" => "list_3",
        "list_1" => "list_1303966373",
        "list_5" => "list_1",
        "list_2" => "list_1",
        "list_6" => "root",
     );
     function getChildrenLists($tree){
        $tree2 = array();
        foreach($tree as $child => $parent){
           if(!array_key_exists($parent, $tree2)) $tree2[$parent] = array();
           $tree2[$parent][] = $child;
        }
        return $tree2;
     }
    
     function renderTree($tree2, $parent = "root"){
        if($parent != "root") echo "<li id='$parent'> value $parent\n";
        $children = $tree2[$parent];
        if(count($children) > 0){ //If node has children
           echo "<ol>\n";
           foreach($children as $child)
              renderTree($tree2, $child);
           echo "</ol>\n";
        }
        if($parent != "root") echo "</li>\n";
     }
     $tree2 = getChildrenLists($tree); 
     renderTree($tree2);
    
    ?>
    

    I want my cookie! Hehe. Hope it helps.