Iliya Reyzis
Iliya Reyzis

Reputation: 3677

extract multidimentional array into a nested list

I'm trying to extract a multidimensional array I got from a Nestable Plugin into a Ordered List by the Plugin's HTML structure.

The Recursion I've build is not enought because the OL tag I'm creating is out side the LI that got children. At first glance it looked like an easy task, but I've failed to complete it.

This is what I've wrote so far, I cant understand how do I check if the next loop in the recursion is the LI that have children, so the OL will be inside, with the buttons and the handle div.
(example of the plugin's HTML structure can be seen below)

function buildNestedList($a) {

    if (!is_array($a)) {
        echo ('<li class="dd-item" data-name="'.$a.'"><div class="dd-handle">'.$a.'</div></li>');
        return;
    }

    foreach($a as $k => $v) {
        if(($k=="children")&&(is_string($k))) {
            echo ('<ol class="dd-list">');
        buildNestedList($v);
            echo ("</ol></li>");
        }
        else {
            printAll($v);
        }
    }
}

This is the output of my function:

<div class="dd" id="nestable">
   <ol class="dd-list">
      <li class="dd-item" data-name="item 1">
         <div class="dd-handle">item 1</div>
      </li>
      <li class="dd-item" data-name="item 2">
         <div class="dd-handle">item 2</div>
      </li>
      <li class="dd-item" data-name="item 3">
         <div class="dd-handle">item 3</div>
      </li>
      <ol class="dd-list">
         <li class="dd-item" data-name="item 4">
            <div class="dd-handle">item 4</div>
         </li>
         <li class="dd-item" data-name="item 5">
            <div class="dd-handle">item 5</div>
         </li>
         <li class="dd-item" data-name="item 6">
            <div class="dd-handle">item 6</div>
         </li>
         <ol class="dd-list">
            <li class="dd-item" data-name="item 7">
               <div class="dd-handle">item 7</div>
            </li>
            <li class="dd-item" data-name="item 8">
               <div class="dd-handle">item 8</div>
            </li>
         </ol>
      </ol>
      <li class="dd-item" data-name="item 9">
         <div class="dd-handle">item 9</div>
      </li>
      <li class="dd-item" data-name="item 10">
         <div class="dd-handle">item 10</div>
      </li>
      <li class="dd-item" data-name="item 11">
         <div class="dd-handle">item 11</div>
      </li>
   </ol>
</div>

This is the a example of an Array I've got from DB:

Array
(
    [0] => Array
        (
            [name] => item 1
        )

    [1] => Array
        (
            [name] => item 2
        )

    [2] => Array
        (
            [name] => item 3
            [children] => Array
                (
                    [0] => Array
                        (
                            [name] => item 4
                        )

                    [1] => Array
                        (
                            [name] => item 5
                        )

                    [2] => Array
                        (
                            [name] => item 6
                            [children] => Array
                                (
                                    [0] => Array
                                        (
                                            [name] => item 7
                                        )

                                    [1] => Array
                                        (
                                            [name] => item 8
                                        )

                                )

                        )

                )

        )

    [3] => Array
        (
            [name] => item 9
        )

    [4] => Array
        (
            [name] => item 10
        )

    [5] => Array
        (
            [name] => item 11
        )

)

This is the correct plugin's HTML structure example:

<ol class="dd-list">
   <li class="dd-item" data-name="item 1">
      <div class="dd-handle">item 1</div>
   </li>
   <li class="dd-item" data-name="item 2">
      <button data-action="collapse" type="button">Collapse</button><button data-action="expand" type="button" style="display: none;">Expand</button>
      <div class="dd-handle">item 2</div>
      <ol class="dd-list">
         <li class="dd-item" data-name="item 3">
            <div class="dd-handle">item 3</div>
         </li>
         <li class="dd-item" data-name="item 4">
            <div class="dd-handle">item 4</div>
         </li>
         <li class="dd-item" data-name="item 5">
            <div class="dd-handle">item 5</div>
         </li>
      </ol>
   </li>
   <li class="dd-item" data-name="item 6">
      <button data-action="collapse" type="button">Collapse</button><button data-action="expand" type="button" style="display: none;">Expand</button>
      <div class="dd-handle">item 6</div>
      <ol class="dd-list">
         <li class="dd-item" data-name="item 7">
            <button data-action="collapse" type="button">Collapse</button><button data-action="expand" type="button" style="display: none;">Expand</button>
            <div class="dd-handle">item 7</div>
            <ol class="dd-list">
               <li class="dd-item" data-name="item 8">
                  <div class="dd-handle">item 8</div>
               </li>
            </ol>
         </li>
      </ol>
   </li>
</ol>

Upvotes: 0

Views: 269

Answers (1)

Passerby
Passerby

Reputation: 10070

You have to open and close tags properly.

Use this:

$source=json_decode('[{"name":"item 1"},{"name":"item 2"},{"name":"item 3","children":[{"name":"item 4"},{"name":"item 5"},{"name":"item 6","children":[{"name":"item 7"},{"name":"item 8"}]}]},{"name":"item 9"},{"name":"item 10"},{"name":"item 11"}]',true);

function buildNestedList(array $a)
{
    if(empty($a["name"]))
    {
        echo "<ol>";
        foreach($a as $item)
        {
            buildNestedList($item);
        }
        echo "</ol>";
    }
    else
    {
        echo "<li><div>".$a["name"]."</div>";
        if(!empty($a["children"]))
        {
            buildNestedList($a["children"]);
        }
        echo "</li>";
    }
}
buildNestedList($source);

PHP Live demo

Please be noted that I pretty-print a little bit on the live demo above.

Here is the simple sample of the generated nested list: http://jsfiddle.net/YDnd8/

Upvotes: 1

Related Questions