Bharanikumar
Bharanikumar

Reputation: 25733

Split records into two columns

I have a "student" table, having around 5,000 records, in my DB. I want to display those records in two divs. How do I do that without executing the query twice; only using a single query?

display example http://www.freeimagehosting.net/uploads/f1c6bb41eb.gif

Upvotes: 5

Views: 15613

Answers (8)

Anurag
Anurag

Reputation: 141859

Just use CSS3. Not sure how widely it is supported but saves a lot of headache and is a lot more powerful when making changes.

Use column-count, and column-width to control the number of columns and width of each column. Here's some sample code and some pretty impressive results. Prefix -webkit and -moz for now until its standardized across all browsers.

.multi-column {
    /* Standard */
    column-count: 2;
    column-width: 150px;
    /* Webkit-based */
    -webkit-column-count: 2;
    -webkit-column-width: 150px;
    /* Gecko-based */
    -moz-column-count: 2;
    -moz-column-width: 150px;
}

Applied to this <div>

<div class="multi-column">
    Ethelred of Wessex
    Louis XII of France
    George Frideric Handel
    George Washington
    Charles Deslandes
    Andrew Jackson
    Alfred Vail 
    William McKinley
    Woodrow Wilson
    Abdul-Aziz ibn Saud
    Fidel Castro
    Charles de Gaulle
    Leonardo da Vinci
</div>

Don't you wanna see how it looks like after all this hard work?

alt text


But what if there were 3 columns? No problem.

alt text


But there's no way it can handle 4 columns you'd say:

alt text


Enough! I gotta stop adding these now

alt text


God please make it STOP!!

alt text

Upvotes: 9

Fivell
Fivell

Reputation: 11929

Try something like this

// connection goes there
$q = "SELECT `name` FROM students";
$result = mysql_query($q);
$students = array();
while($row=mysql_fetch_assoc($result)) {
       $students[] = $row['name'];
}
$students_count = sizeof($students);
// chunkes into a two parts , want more columns ? just change "2" to other number
$students_chuncked =  array_chunk($students,ceil($students_count/2),true); 

//now display
foreach ($students_chuncked as $student_div_data){
   echo '<div>',explode($student_div_data,'<br/>'),'</div>';
}

Upvotes: 0

vince
vince

Reputation: 11

Why dont you try this code, its simple using only css, easy to understand, working in ie and mozilla...

<style type="text/css">

    .ulcol
    {
    float: left;
    width: 400px;
    margin: 0;
    padding: 0;
    list-style: none;
    }

    .licol
    {
    float: left;
    width: 200px; /*half width of the ulcol width*/
    margin: 0;
    padding: 0;
    } 

    </style>

    <?php

    $query = mysql_query("select * from table_name") or die("Error Occured,check again");

    echo '<ul class="ulcol">';

    while($row = mysql_fetch_assoc($query))
    {
    $vartitle       =   $row[db_row_title];
    echo '<li class="licol">';
    echo $vartitle
    echo '</li>';
    }
    echo '</ul>';
    ?>

Upvotes: 1

marcos
marcos

Reputation: 21

get_column() function could help, it will calculate column for each item you want to show.

this sample script show how to print in two columns, but you can change it in two minutes to fix your needs if you need other number of columns.

<?php


// sample query, get members 
$query = mysql_query("select name from persons");


// count total number of items to show
$total = mysql_num_rows($query);


// initiate row counter
$counter = 1;

// initiate columns contents
$column_1 = '';
$column_2 = '';
while($row = mysql_fetch_assoc($query)){

    // caluculate column for current element from total items to be showed number of     columns and current item
    $column = get_column($total, 2, $counter);

    if($column == 1){
        $column_1 .= $row['name'].'<br>';
        }

    if($column == 2){
        $column_2 .= $row['name'].'<br>';
        }


    $counter++;
    }

// show content in two table comments
echo "<table>
        <tr>
          <td>$column_1</td>
          <td>$column_2</td>
        </tr>
      </table>";

?>

and the function is:

<?php
/**
 * Calculate column number where an item should be displayed on a "newspaper style"
 * or "phoneguide style" report  according its postion
 * used to put same number of items on each column
 * 
 * receive 3 numbers: $vp_total_size: total number of items on report
 *                    $vp_columns   : number of columns of report
 *                    $vp_element   : element position for item (1 to  $vp_total_size)
 *
 * by Marcos A. Botta <marcos DOT botta AT gmail DOT com>
 * 02/02/2007
 * 
 */
function get_column($vp_total_size, $vp_columns, $vp_element){

    if($vp_element <= 0){
        return 1;
        }

    if($vp_element < $vp_columns &&
       $vp_columns >= $vp_total_size){
    return $vp_element;
        }

    $vl_avg_items_by_column    = $vp_total_size / $vp_columns;

    $vl_items_on_first_columns = ceil($vl_avg_items_by_column);
    $vl_items_on_last_columns  = floor($vl_avg_items_by_column);

    $vl_column_limit = ($vl_avg_items_by_column - $vl_items_on_last_columns) *     $vp_columns;


    $vl_allocated_items = 0;

    for($i=1;$i<$vp_columns;$i++){

        if($i < $vl_column_limit ||
           "$i" == "$vl_column_limit"){
            $vl_items_on_current_column = $vl_items_on_first_columns;

            }
        else{
            $vl_items_on_current_column = $vl_items_on_last_columns;
            }


        $vl_allocated_items += $vl_items_on_current_column;

        if($vp_element <= $vl_allocated_items){
            return $i;
            }


        }

    return $vp_columns;
    } // get_column()

?>

good luck!

Upvotes: 2

fiskah
fiskah

Reputation: 5902

My implementation:

<?php
$students = array(1,2,3,4,5);
$split = floor(count($students)/2);

echo '<div id="parent"><div id="col-1">';

$i = 0;
foreach($students as $student)
{
  echo 'Student #' . $student . '<br />';
  if($i == $split)
  {
    echo '</div><div id="col-2">';
  }
  $i++;
}

echo '</div></div>';

Using the CSS3 Webkit/Moz only features are in my opinion very bad practice.

Upvotes: 1

gb.
gb.

Reputation: 656

I prefer to minimize any early use of "echo", because tomorrow you will want to move this in a function or a method, where "echo" should be avoided. Moreover, with the "echo" in the loop you've lost the array structure inherent to databases, and you need this structure to manipulate your data. So I would rather fill an array, process it, then implode to output.

And I would use styled bullet points to display the items, because you apparently want to display a list of items. In pseudo php code:

while row = fetch(sql)
  lines[] = "<li>row_data</li>"
end

// work on the lines array, eg insert "</ul><ul>" in the middle
echo "<ul>".implode("\n",lines)."</ul>"

Upvotes: 0

naivists
naivists

Reputation: 33501

Just find where the "middle" is and output the end tag of the div tag and the start tag of the second div:

<? 
$rowcount = mysql_num_rows($recordset);
echo "<div id='div1'>";
$i = 0;
while ($d = mysql_fetch_object($recordset)) {
  echo $d->somefield;
  $i++;

  if ($i == floor($rowcount / 2)) {
      //we have reached the mid-point, let's close the first DIV
      echo "</div><div id='div2'>";
  }
}
echo "</div>";
?>

Upvotes: 8

lemon
lemon

Reputation: 9205

Maybe split the array into two then implode them and then print both halves on each div.

Upvotes: 0

Related Questions