Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to display a list in three columns using php?

For the past couple of hours, I've been unsuccessfully trying to figure out the php code to display a list in three columns so that it has this order

A D G
B E H
C F I

but I'm really lost. Can anyone help me with this? I currently only have code that lists in this order

A B C
D E F
G H I

This is my current code:

echo '<table><tr>';
foreach ($categories as $k => $category) {
    if ($k % 3 == 0 && $k ! = 0) {
        echo '</tr><tr>';
    }
    echo '<td><a href="category.php?category='.$category["id"].'">'.$category["category"].'</a></td>';
}
echo '</table>';
like image 278
Harry M Avatar asked Dec 09 '12 02:12

Harry M


3 Answers

Try this:

$columns = 3;
$rows = ceil(count($categories) / $columns);

echo '<table>';

for ($row = 0; $row < $rows; $row++) {
    echo '<tr>';

    foreach ($categories as $k => $category) {
        if ($k % $rows == $row) {
            echo '<td><a href="category.php?category='.$category["id"].'">'.$category["category"].'</a></td>';
        }
    }

    echo '</tr>';
}

echo '</table>';

It's not very efficient, but right now I can't think on a better way of doing it.

like image 127
rdiazv Avatar answered Nov 15 '22 23:11

rdiazv


If you want to have the list rendered in columns as indicated, you could generate it in the logical order and just uses the CSS columns property to set in columns:

ul {
  -moz-column-count: 2;
  -webkit-column-count: 2;
  column-count: 2;
}

The bad news is that this is not supported by IE 9 and earlier, but the Columns polyfills like css3-multi-column.js might work sufficiently well in simple cases (despite their limitations and issues).

like image 35
Jukka K. Korpela Avatar answered Nov 16 '22 00:11

Jukka K. Korpela


I had this same issue, and I am posting my answer to this old question for the following reasons:

  1. My answer is more general and easy for others to adapt.
  2. My array was associative, with a string key. BTW, my answer will work for both associative and indexed arrays.
  3. I didn't want a complex CSS solution, like some of the other answers on this topic. Actually, the solution I came up with was pretty simple--use multiple tags with style="float:left", inside of a giant table. While I was sceptical that having multiple tbody tags in a single table would pass HTML validation, it in fact did pass without errors.

Some things to note:

  • $numCols is your desired number of columns.
  • Since we are floating items, you may need to set the width and min-width of parent elements and/or add some <br style="clear: both" />, based on your situation.
  • for alternative sorting methods, see http://php.net/manual/en/array.sorting.php

Here is my full answer:

function sortVertically( $data = array() )
{
    /* PREPARE data for printing */
    ksort( $data );     // Sort array by key.
    $numCols    = 3;    // Desired number of columns
    $numCells   = is_array($data) ? count($data) : 1 ;
    $numRows    = ceil($numCells / $numCols);
    $extraCells = $numCells % $numCols;  // Store num of tbody's with extra cell
    $i          = 0;    // iterator
    $cCell      = 0;    // num of Cells printed
    $output     = NULL; // initialize 


    /* START table printing */
    $output     .= '<div>';
    $output     .= '<table>';

    foreach( $data as $key => $value )
    {
        if( $i % $numRows === 0 )   // Start a new tbody
        {
            if( $i !== 0 )          // Close prev tbody
            {
                $extraCells--;
                if ($extraCells === 0 )
                {
                    $numRows--;     // No more tbody's with an extra cell
                    $extraCells--;  // Avoid re-reducing numRows
                }
                $output .= '</tbody>';
            }

            $output .= '<tbody style="float: left;">';
            $i = 0;                 // Reset iterator to 0
        }
        $output .= '<tr>';
            $output .= '<th>'.$key.'</th>';
            $output .= '<td>'.$value.'</td>';
        $output .= '</tr>';

        $cCell++;                   // increase cells printed count
        if($cCell == $numCells){    // last cell, close tbody
            $output .= '</tbody>';
        }

        $i++;
    }

    $output .= '</table>';
    $output .= '</div>';
    return $output;
}

I hope you find this answer useful.

like image 3
Julian Soro Avatar answered Nov 15 '22 22:11

Julian Soro