1

I have table that is dynamically created from an array. Using PHP, how can I dynamically add rowspan when the data is repeated? I would like 'Youth Classes' to be displayed only once and have a rowspan=2.

Array
(
    [0] => Array
        (
            [Type] => Youth Classes
            [Class] => Preschool Class
            [Day] => Saturday
        )

    [1] => Array
        (
            [Type] => Youth Classes
            [Class] => Grade School
            [Day] => Friday
        )
)

<?php
/*Load csv file into array*/
$file = 'list.csv';
$rows = array_map('str_getcsv', file($file));
$headers = array_shift($rows);
$csv = array();
foreach($rows as $row) {
    $csv[] = array_combine($headers, $row);
}

/*Build Table*/
echo "\t\t<table class='table'>\n";
echo "\t\t\t<tr>\n";
    foreach ($headers as $header) {
        echo "\t\t\t\t<th>";
        echo $header;
        echo "</th>\n";
    }
    echo "\t\t\t</tr>\n";
foreach ($csv as $row) {
    echo "\t\t\t<tr>\n";
    foreach ($row as $cell) {
        echo "\t\t\t\t<td>";
        echo $cell;
        echo "</td>\n";
    }
    echo "\t\t\t</tr>\n";
}
echo "\t\t</table>\n";
?>
1
  • This should works for only two rows, or more? Commented Mar 4, 2018 at 22:25

2 Answers 2

2

On each row, you could check if the "above-cell" is the same, and cancel to write if it is. And, you could count the number of "below-cells" are the same to compute the number of rowspan you have to write.

The code below works if two or more rows are the same.

/*Build Table*/
echo "\t\t<table class='table'>\n";

// Your header code skipped here...

foreach ($csv as $rid => $row) { // Add key $rid here
    echo "\t\t\t<tr>\n";
    foreach ($row as $cid => $cell) { // Add key $cid here

        // If above cell is the same, skip.
        if ($rid > 0 && isset($csv[$rid-1]) && $csv[$rid-1][$cid] == $cell) 
            continue;

        // Check amount of "below cells" that are the same :
        $rspan = 1 ; $idx = 1 ;
        while (isset($csv[$rid + $idx]) && $csv[$rid + $idx][$cid] == $cell) {
            $rspan++;
            $idx++;
        }

        // Write rowspan if needed.
        echo "\t\t\t\t<td".($rspan > 1 ? ' rowspan="' . $rspan . '"' : '') . ">";
        echo $cell;
        echo "</td>\n";
    }
    echo "\t\t\t</tr>\n";
}
echo "\t\t</table>\n";

Outputs :

    <table class='table'>
        <tr>
            <td rowspan="2">Youth Classes</td>
            <td>Preschool Class</td>
            <td>Saturday</td>
        </tr>
        <tr>
            <td>Grade School</td>
            <td>Friday</td>
        </tr>
    </table>
Sign up to request clarification or add additional context in comments.

Comments

0

I would group your csv data into a multi-dimensional array then count the number of rows in each category. This will dictate the value to feed rowspan and if rowspan even needs to be written at all.

Code: (Demo)

$csv=<<<CSV
Youth Classes,Grade School,Monday
Adult Classes,Grade School,Tuesdayday
Youth Classes,Grade School,Friday
Youth Classes,Preschool Class,Saturday
CSV;

foreach (explode("\n", $csv) as $line) {
    $row = str_getcsv($line, ",");
    $grouped[array_shift($row)][] = $row;
}
//var_export($grouped);

echo "<table>\n";
foreach ($grouped as $category => $group) {
    $rows=sizeof($group);
    foreach ($group as $i => $row) {
        echo "\t<tr>\n";
            if(!$i){  // if this is the first row of the subarray (in other words: [0])
                echo "\t\t<th" , ($rows>1 ? " rowspan=\"$rows\"" : "") , ">$category</th>\n";
            }
            echo "\t\t<td>" , implode("</td>\n\t\t<td>", $row) , "</td>\n";
        echo "\t</tr>\n";
    }
}
echo "</table>";

Source Output:

<table>
    <tr>
        <th rowspan="3">Youth Classes</th>
        <td>Grade School</td>
        <td>Monday</td>
    </tr>
    <tr>
        <td>Grade School</td>
        <td>Friday</td>
    </tr>
    <tr>
        <td>Preschool Class</td>
        <td>Saturday</td>
    </tr>
    <tr>
        <th>Adult Classes</th>
        <td>Grade School</td>
        <td>Tuesdayday</td>
    </tr>
</table>

Rendered Output: (courtesy of phptester.com)

enter image description here

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.