0

I am attempting to take an array of values and build a php form from those values.

The array is at the bottom to keep the question clear. The array structure is:

- Item
- Item
- Item with Child   
        -Item 
        -Item
        - Item with Child   
            -Item 
            -Item

Here is what I want to output each item but if the item has a child, just output the name of the parent and create fields for the children.

enter image description here

I created this:

 function renderTest2(array $data)
    {
        $html = '<ul>';
        foreach ($data as $item) {
            $html .= '<li>';

            foreach ($item as $key => $value) {

                if (is_array($value)) {
                    $html .= renderTest2($value);
                } else {
                    if (array_key_exists('children', $item)) {
                        $html .= $item['name'];
                    } else {
                        $html .= $item['name'] . "<input type=\"text\" value=\"\"> <br/>";
                    }

                }
            }
            $html .= '</li>';
        }
        $html .= '</ul>';

        return $html;
    }

Which gave me this output:

enter image description here

But I don't understand why it is duplicating items. What am I doing wrong?

Here is the test array I used:

$aFullArray = array();

$aFullArray[] = array("name" => "Adam", "address" => "123 main", "phone" => "000-000-0000");
$aFullArray[] = array("name" => "Beth", "address" => "123 main", "phone" => "000-000-0000");


    $aChildren = array();
    $aChildren [] = array("name" => "Mike", "address" => "123 main", "phone" => "000-000-0000");
    $aChildren[] = array("name" => "Nancy", "address" => "123 main", "phone" => "000-000-0000");


    $subChild = array();
    $subChild [] = array("name" => "Peter", "address" => "123 main", "phone" => "000-000-0000");
    $subChild [] = array("name" => "Paul", "address" => "123 main", "phone" => "000-000-0000");

    $aChildren [] = array("name"     => "Oscar", "address" => "123 main", "phone" => "000-000-0000",
                          "children" => $subChild);

    $aFullArray[] = array("name"     => "Charlie", "address" => "123 main", "phone" => "000-000-0000",
                          "children" => $aChildren);

    $aFullArray[] = array("name" => "Danny", "address" => "123 main", "phone" => "000-000-0000");
1
  • Could it be, since each output from the foreach() is duplicate twice, that the structure of your foreach reads each type in the array, so since you've got a "name", "address" and "phone" the foreach() grabs all three of them, and then gets told show the "name" foreach() value you've come accross wich equals 3 times. Commented Dec 1, 2017 at 15:05

3 Answers 3

2
function renderTest2(array $data)
{
    $html = '<ul>';
    foreach ($data as $item) {
        $html .= '<li>';
        if (array_key_exists('children', $item)) {
            $html .= $item['name'];
            $html .= renderTest2($item['children']);
        } else {
            $html .= $item['name'] . "<input type='text' value=''> <br/>";
        }
        $html .= '</li>';
    }
    $html .= '</ul>';

    return $html;
}

you are looping two times which is not required and if it has children pass children array only

Explanation:

  1. Loop through an array and if it has children key do recursion
  2. If not found generate li element
Sign up to request clarification or add additional context in comments.

1 Comment

facepalm It's something so simple sometimes. Thank you!
0

Looking at the code i saw the following mistake:

foreach() do foreach() so a multiple foreach() loop would be the mistake you've made.

try this code:

by calling foreach() only once and using

if (array_key_exists('children', $item)) {
   $html .= $item['name'];
   $html .= renderTest2($item['children']);
}

together in one foreach() the double loop isn't needed and recursion is avoided

The full code then would be:

<?php
$aFullArray = array();


$aFullArray[] = array("name" => "Adam", "address" => "123 main", "phone" => "000-000-0000");
$aFullArray[] = array("name" => "Beth", "address" => "123 main", "phone" => "000-000-0000");


$aChildren = array();
$aChildren [] = array("name" => "Mike", "address" => "123 main", "phone" => "000-000-0000");
$aChildren[] = array("name" => "Nancy", "address" => "123 main", "phone" => "000-000-0000");


$subChild = array();
$subChild [] = array("name" => "Peter", "address" => "123 main", "phone" => "000-000-0000");
$subChild [] = array("name" => "Paul", "address" => "123 main", "phone" => "000-000-0000");

$aChildren [] = array("name"     => "Oscar", "address" => "123 main", "phone" => "000-000-0000",
    "children" => $subChild);

$aFullArray[] = array("name"     => "Charlie", "address" => "123 main", "phone" => "000-000-0000",
    "children" => $aChildren);

$aFullArray[] = array("name" => "Danny", "address" => "123 main", "phone" => "000-000-0000");

function renderTest2(array $data)
{
    $html = '<ul>';
    foreach ($data as $item) {
        $html .= '<li>';
        if (array_key_exists('children', $item)) {
            $html .= $item['name'];
            $html .= renderTest2($item['children']);
        } else {
            $html .= $item['name'] . "<input type='text' value=''> <br/>";
        }
        $html .= '</li>';
    }
    $html .= '</ul>';

    return $html;
}
echo renderTest2($aFullArray);

Hope this helps!

Comments

0

As the original code was not making use of various elements within the source arrays I simplified for testing porpoises. Hopefully the following makes sense, it seems to generate the list in the desired manner.

$html = $family = $children_family_1 = $children_family_2 = array();




$family[] = array("name" => "Adam");
$family[] = array("name" => "Beth");
$family[] = array("name" => "Danny");

$children_family_2[] = array("name" => "Peter");
$children_family_2[] = array("name" => "Paul");

$children_family_1[] = array("name" => "Mike");
$children_family_1[] = array("name" => "Nancy");

$children_family_1[] = array("name" => "Oscar", "children" => $children_family_2 );
$family[] = array("name" => "Charlie", "children" => $children_family_1 );



function familytree( $input=array(),&$html ){
    $html[]='<ul>';
    foreach( $input as $index => $arr ){
        if( array_key_exists( 'children', $arr ) && is_array( $arr['children'] ) ){

            $html[]="<li>Parent: {$arr['name']}</li>";
            $html[]="<li>";

            /* recurse array to repeat structure */
            familytree( $arr['children'], &$html );

            $html[]="</li>";
        } else {
            $html[]="<li><input type='text' name='name[]' value='{$arr['name']}' /></li>";
        }
    }
    $html[]='</ul>';

    return implode( PHP_EOL, $html );
}

echo familytree( $family, $html );

The generated html:

<ul>
    <li><input type="text" name="name[]" value="Adam"></li>
    <li><input type="text" name="name[]" value="Beth"></li>
    <li><input type="text" name="name[]" value="Danny"></li>
    <li>Parent: Charlie</li>
    <li>
        <ul>
            <li><input type="text" name="name[]" value="Mike"></li>
            <li><input type="text" name="name[]" value="Nancy"></li>
            <li>Parent: Oscar</li>
            <li>
                <ul>
                    <li><input type="text" name="name[]" value="Peter"></li>
                    <li><input type="text" name="name[]" value="Paul"></li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.