This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I want to populate a two column HTML layout from a database using PHP. The records returned will be in date ordered descending, and I want to populate the columns so that the first record goes in column one and the next in column two then back to column one and so on.
I'm working on the theory that I should take the MySQL result and run through it splitting it into two arrays, by putting the first record in the first array and the second in the second array and so on then using those arrays to output to the columns.
The columns are defined as follows;
<div id="leftcol">
</div>
<div id="rightcol">
</div>
EDIT
while($row = mysql_fetch_array($result))
{
$lcol = $lcol + 1;
$vis = 0;
$uri = substr($row[1], 0, strpos($row[1], "&"));
$sql = "SELECT * FROM `readart` WHERE `url`=\"".$uri."\"";
$result2 = mysql_query($sql);
while($row2 = mysql_fetch_assoc($result2))
{
$vis = $row2['visits'];
}
$tit = myTruncate2($row[4], 91);
echo '<div class="newitem">';
echo '<img style="float:left;margin:6px;margin-right:20px;" src="newslogo/'.$row[2].'.png" width="40px" height="40px" />';
echo '<span id="header">'.$tit.'</span><br>';
//echo $row[6];
echo '<span id="date">'.date("D, j F g:i A", $row[6]);
if($vis > 0){echo ' - Viewed '.$vis.' times';}
echo '</span><hr>';
echo '<p id="textbody">';
echo $row[5];
echo '<br><br>Read More';
echo '</p><br></div>';
}
<?php
$row = array();
$rowCount = $mysql_row_count($result);
while ($row[] = mysql_fetch_array($result));
echo "<div idi\"leftcol\">";
for ($i = 0; $i < $rowCount; $i+=2)
echo $row[$i]; //Change this to whatever you want to echo or however you want to echo it
echo "</div>";
echo "<div idi\"rightcol\">";
for ($i = 1; $i < $rowCount; $i+=2)
echo $row[$i]; //Change this to whatever you want to echo or however you want to echo it
echo "</div>";
?>
EDIT
Here's what i came up with your code... I'm not sure if it will work right away since i haven't tested it. But I hope it gives you an idea of how to do it now.
<?php
function echoData($right, $row, $rowCount)
{
for ($i = $right; $i < $rowCount; $i += 2)
{
$lcol = $lcol + 1;
$vis = 0;
$uri = substr($row[$i][1], 0, strpos($row[$i][1], "&"));
$sql = "SELECT * FROM `readart` WHERE `url`=\"".$uri."\"";
$result2 = mysql_query($sql);
while($row2 = mysql_fetch_assoc($result2))
{
$vis = $row2['visits'];
}
$tit = myTruncate2($row[$i][4], 91);
echo '<div class="newitem">';
echo '<img style="float:left;margin:6px;margin-right:20px;" src="newslogo/'.$row[$i][2].'.png" width="40px" height="40px" />';
echo '<span id="header">'.$tit.'</span><br>';
//echo $row[6];
echo '<span id="date">'.date("D, j F g:i A", $row[$i][6]);
if($vis > 0){echo ' - Viewed '.$vis.' times';}
echo '</span><hr>';
echo '<p id="textbody">';
echo $row[$i][5];
echo '<br><br>Read More';
echo '</p><br></div>';
}
}
**Here you should put the query code**
$sql = "SELECT e.t.c e.t.c";
$result = mysql_query($sql);
$rowCount = mysql_num_rows(result);
$row = array();
while($row[] = mysql_fetch_array($result));
echo "<div id='leftside'>";
echoData(0, $row, $rowCount);
echo "</div>";
echo "<div id='rightside'>";
echoData(1, $row, $rowCount);
echo "</div>";
do this
$rightCol = "";
$leftCol = "";
$c = 0;
foreach($data as $box){
if ($c%2){
$leftCol.= $box;
} else {
$rightCol.= $box;
}
$c++;
}
Then for your html do this
<div id="leftcol">
<?= $leftCol ?>
</div>
<div id="rightcol">
<?= $rightCol ?>
</div>
Related
(1) class
(2) studentmark
(3) skill
PHP code:
<?php
//DB CONNECTION
//---(1)Get skillname---
$q = "SELECT skillName FROM skill ORDER BY skillName asc";
$r = mysqli_query($dbc, $q);
$num_rows = mysqli_num_rows($r);
while($row = mysqli_fetch_array($r, MYSQLI_ASSOC))
{
$skills[] = $row['skillName'];
}
//---(2)Get classname---
$q1 = "SELECT className FROM class";
$r1 = mysqli_query($dbc, $q1);
$num_rows1 = mysqli_num_rows($r1);
while($row1 = mysqli_fetch_array($r1, MYSQLI_ASSOC))
{
$className[] = $row1['className'];
}
//---(3)Create table---
echo '<table border="1" style="border-collapse: collapse; text-align: center">';
echo '<tr>';
for($a = 0; $a < $num_rows; $a++)
{
echo '<th colspan="2">'.$skillName[$a].'</th>';
}
echo '</tr>';
for($b = 0; $b < $num_rows; $b++)
{
echo '<th>Student Name</th>';
echo '<th>Grade</th>';
}
echo '</tr>';
//---(4)Get student name and grade---
for($s = 0; $c < $num_rows1; $c++)
{
$q2 = "SELECT GROUP_CONCAT(sm.studentName) as studentName,
GROUP_CONCAT(sm.studentGrade) as studentGrade,
s.skillName
FROM studentmark sm
LEFT JOIN skill s ON sm.skillID = s.skillID
WHERE sm.className = '".$className[$c]."'
GROUP BY s.skillID";
$r2 = mysqli_query($dbc, $q2);
$num_rows2 = mysqli_num_rows($r2);
$value = array();
while($row2 = mysqli_fetch_array($r2, MYSQLI_ASSOC))
{
$value[] = $row2;
}
echo '<tr>';
for($d = 0; $d < $num_rows2; $d++)
{
echo '<td>'.$value[$d]['studentName'].'</td>';
echo '<td>'.$value[$d]['studentGrade'].'</td>';
}
echo '</tr>';
}
echo '</table>';
?>
From above code, my output is below:
I am almost finished. I can show the student name and grade in 1 row.
Now, the last thing I want to do is put them into suitable skill name like below:
I want to compare the $skills and s.skillname on $q2.
Below is my logic:
if($value[X]['skillName'] == $skills[X])
{
//put student name and grade inside
}
else
{
//empty cell
}
But I don't know where should I open for loop and put my logic in (4). Can someone help me?
So I'm definitely messing up your nice clean code for the sake of not looping through the data multiple times. I also display the classnames cause that seems like useful info.
I changed some variable names cause I found it easier to remember what each variable was for. Also, note how the student info query is only executed once. Normaly (read: I can't think of a reason why you wouldn't but I'm CMA), you want to minimize the number of times you query the database
The code below will replace the entire script you posted.
<?php
//DB CONNECTION
$dbc = // magic connection sauce you already have
// get skills and stash how many there are
$q_class = "SELECT skillName FROM skill ORDER BY skillName asc";
$r_class = mysqli_query($dbc, $q_class);
$num_skills = mysqli_num_rows($r_class);
// start table code so that we can echo the skillname headers
echo '
<table border="1" style="border-collapse: collapse; text-align: center">
<thead>
<tr>
<th rowspan=2>Classes</th>';//header for class name column
$header = array();
while($row = mysqli_fetch_array($r_class, MYSQLI_ASSOC))
{
$skills[] = $row['skillName'];
// store both thead rows at the same time so that we can echo them out properly later
$header['first'][] = '
<th colspan="2">' . $row['skillName'] . '</th>';
$header['second'][] = '
<th>Student Name</th>
<th>Grade</th>';
}
echo '
' . implode($header['first']) . '
</tr>
<tr>' . implode($header['second']) . '
</tr>';
// clean-up
mysqli_free_result($r_class);
// get class names and stash how many there are
$classes = array();
$query_class = "SELECT className FROM class";
$r_class = mysqli_query($dbc, $query_class);
$num_classes = mysqli_num_rows($r_class);
while($row = mysqli_fetch_array($r_class, MYSQLI_ASSOC))
{
$classes[] = $row['className'];
}
// clean-up
mysqli_free_result($r_class);
echo '
</thead>
<tbody>';
// pull query out of loop so that you'll only have to execute it once.
$studentInfoQuery = "
SELECT
GROUP_CONCAT(sm.studentName) as studentName,
GROUP_CONCAT(sm.studentGrade) as studentGrade,
s.skillName,
sm.className
FROM studentmark sm
LEFT JOIN skill s ON sm.skillID = s.skillID
GROUP BY sm.className,s.skillID";
$r_students = mysqli_query($dbc,$studentInfoQuery);
$num_studentRows = mysqli_num_rows($r_students);
$studentRows = array();
while($row = mysqli_fetch_array($r_students, MYSQLI_ASSOC)) {
// with our query, we only find 1 cell-pair per skill per class
$studentRows[$row['skillName']][$row['className']] = '
<td>' . $row['studentName'] . '</td>
<td>' . $row['studentGrade'] . '</td>';
}
// everybody do their share! // actually, more clean-up
mysqli_free_result($r_students);
for($j = 0; $j < $num_classes; $j++) {
echo "
<tr>
<th>" . $classes[$j] . "</th>";
for($i = 0; $i < $num_skills; $i++) {
// always echo out a cell, even if we have student info for it
// example: if(isset($studentRows['Listening']['1A'])) echo it out else echo cell
if(isset($studentRows[$skills[$i]][$classes[$j]]))
echo $studentRows[$skills[$i]][$classes[$j]];
else
echo "
<td colspan=2>No skill-class-student value</td>";
}
echo "
</tr>";
}
echo '
</tbody>
</table>';
?>
Results:
You are doing fine(although the things can be optimized) up to the last loop of step 4 in your design.
The problem you face right there is that you have a set of results which represent each class in it's rows. Now you need to spread them out in to skill table, importantly, without leaving vertical gaps.
The solution is to do it in a two dimension array in the memory and then create the table from it - because each cell in the memory is easily addressable than cells in an html table.
Memory table is going to be something like this:
|Skill 1 | Skill 2 | Skill3|
|stdnt 1 |stdnt 2,3|stdnt 4|
| | |stdnt 5|
Please note how I have used array_search to get the index of a particular skill and use it in array_push to insert the student in to the correct child array. Then I have just translated it in to an HTML table
I'm replacing your last loop with the following code:
//This is our memory table. Let's create it and add number of child arrays
//equal to number of skills.
$memTable = array();
for ($i = 0; $i <= sizeOf($skills) - 1; $i++) {
$memTable[$i] = array();
}
//Lets spread out your student information in to this 2d array now
foreach ($value as $student) {
//Get the index of the skill
$skillIndex = array_search($student['skillName'], $skills);
//Now go to appropriate child array and insert your student there
array_push($memTable[$skillIndex], $student);
};
//Lets create the table now
$emptyCount = 0;
$currentRow = 0;
//Do until all the skill arrays are empty for a row
while ($emptyCount < 3) {
echo "<tr>";
$emptyCount = 0;
foreach ($memTable as $skillLevel) {
if (sizeof($skillLevel) - 1 < $currentRow) {
$emptyCount ++;
echo "<td> </td>";
echo "<td> </td>";
}
else {
echo "<td>" . $skillLevel[$currentRow]['studentGrade'] . "</td>";
echo "<td>" . $skillLevel[$currentRow]['studentGrade'] . "</td>";
}
}
$currentRow++;
echo "</tr>";
};
Please note that the skills will be rendered in the table according to the order they are in the $skills array. Please ask me questions if there is any place that is not clear to you. You might need to adjust some String names to adopt in to your code.
UPDATE
while ($emptyCount < sizeof($skills)) is more accurate.
I tried many hours to simplify this code:
<?
echo '<div class="eme3-left">'."\n".'<table>'."\n";
for ($n=1,$i=10; $n<=100,$i<=100;$n+=10,$i+=10)
{
echo '<tr>
<td class="dick-grau">'.$n.' → '.$i.'</td>
<td>'.$n.' = '.decbin($n).'<sub>2</sub></td>
<td>'.($n+1).' = '.decbin($n+1).'<sub>2</sub></td>
<td>'.($n+2).' = '.decbin($n+2).'<sub>2</sub></td>
<td>'.($n+3).' = '.decbin($n+3).'<sub>2</sub></td>
<td>'.($n+4).' = '.decbin($n+4).'<sub>2</sub></td>
<td>'.($n+5).' = '.decbin($n+5).'<sub>2</sub></td>
<td>'.($n+6).' = '.decbin($n+6).'<sub>2</sub></td>
<td>'.($n+7).' = '.decbin($n+7).'<sub>2</sub></td>
<td>'.($n+8).' = '.decbin($n+8).'<sub>2</sub></td>
<td>'.($n+9).' = '.decbin($n+9).'<sub>2</sub></td>';
};
echo '</tr></table>'."\n".'</div>';
?>
How to add the if condition from the third code for the second for loop ?
<?php
echo '<div class="eme3-left">'."\n".'<table>'."\n";
for ($n=1,$i=10; $n<=100,$i<=100; $n+=10, $i+=10) {
echo '<TR>'."\n".'<td class="dick-grau">'.$n.' → '.$i.'</td>';
for ($t = 1; $t<=10; $t++) {
echo '<td>'.$t.' = '.decbin($t).'<sub>2</sub></td>'."\n";
}
echo "</tr>";
}
echo '</table>'."\n".'</div>';
?>
In another version the following loop works perfectly, but when I add it to the code above, the if-condition don't work.
for($i=1;$i<=100;$i++){
echo '<td>'.$i.' = '.decbin($i).'<sub>2</sub></td>'."\n";
if($i%10 == 0)
echo '</tr>'."\n";
}
Maybe their are more suggestions for improvements.
This is not a complete example but should get you there.
<?php
$ints = range(1,100);
$ints_grouped_by_10 = array_chunk($ints,10);
foreach($ints_grouped_by_10 as $int_group){
echo "<tr>";
echo '<td class="dick-grau">'.reset($int_group).' → '.end($int_group).'</td>';
foreach($int_group as $int){
echo "<td>{$int} = ".decbin($int)."</td>";
}
echo "</tr>";
}
?>
[Edit] added the legend (1 -> 10, 11 -> 20)
echo '<div class="eme3-left">'."\n".'<table>'."\n";
for ( $n=1 ; $n <= 100 ; $n+=10 )
{
echo '<tr>
<td class="dick-grau">'.$n.' → '.($n+9).'</td>';
for ( $j = 0 ; $j < 10 ; $j++ )
echo '<td>'.($n + $j).' = '.decbin($n+$j).'<sub>2</sub></td>';
echo '<tr>';
}
echo '</table>'."\n".'</div>';
I am trying to make a function in PHP which writes out a table, and looks in the database to find what cells should have info. the grid will always be the same size, but the content may be in different places.
I've gotten it to be able to look in the database, though it seems to only highlight the first cell, rather than the correct coordinates.
require("sql.php");
$sql = <<<SQL
SELECT *
FROM `maps`
WHERE `objpresent` = 1
SQL;
if(!$result = $db->query($sql)){
die('There was an error running the query [' . $db->error . ']');
} // ran the query
$xobj = array();
$yobj = array();
while($row = $result->fetch_assoc()){
//echo $row['x'] . $row['y'] . $row['object'] . '<br />';
$xobj[] += $row['x'];
$yobj[] += $row['y'];
}// get the rows
//find whether the row is obstructed
for($a=0; $a<=20-1; $a++) //rows (y)
{
for($i=0; $i<=25-1; $i++) //cols (x)
{
echo "<td>"; //between these write the apt content
// if (empty($xobj[$i]) || empty($yobj[$a]) ){
// echo '0';
//} //detect whether there is even a record for this space
if(!empty($xobj[$i]))
{
if(!empty($yobj[$a]))
{
echo $xobj[$i]; //debug
if($xobj[$i] == $i)
{
//echo $xobj[$i];
echo "A";
}
}
}
//echo "<td><img src='emptysym.png'></img></td>";
echo "</td>"; //add textual descriptions for now, add icons later
}
echo "</tr>";
}
this is my current(though rather messy) code.
if there is a row with the column x saying 2, and the column y saying 3, then it should put a letter at (2,3.
is it possible to fix this, or is there a better method for this?
Use a 2-dimensional array whose indexes are the x and y values from the database:
$xyobj = array();
while($row = $result->fetch_assoc()){
$xyobj[$row['x']][$row['y']] = true;
}
Then your output loop should be:
for ($y = 0; $y < 20; $y++) {
echo '<tr>';
for ($x = 0; $x < 25; $x++) {
echo '<td>';
if (isset($xyobj[$x][$y])) {
echo 'A';
}
echo '</td>';
}
echo '</tr>';
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I am making a loop that displays a table with 12 columns. It starts with the number 1912 and ends with 2013. The problem is, when it loops to 1920, it has no remainder and starts a new row. I need to get the code to make a new row after the 12th column.
This is the result I'm getting:
And here is what I have so far:
<?php
$columns = 12;
$Year = 1912;
echo "<table width="755" border="1">";
echo "<tr>";
while ($Year <= 2013) {
if (!($Year % $columns)) {
echo "</tr><tr>";
}
echo "<td>$Year</td>";
++$Year;
}
echo "</tr>";
echo "</table>";
?>
<?php
$columns = 12;
$Year = 1912;
$i=1;
echo "<table width=\"755\" border=\"1\">";
echo "<tr>";
while ($Year <= 2013)
{
if ($i==13)
{
echo "</tr><tr>";
$i=1;
}
echo "<td>$Year</td>";
$Year++;
$i++;
}
echo "</tr>";
echo "</table>";
?>
SOLUTION 1
You need to append and prepend columns for the years where this matches, like so:
And here's the code for doing so:
<?php
$columns = 12;
$startingYear = 1912;
$endingYear = 2013;
$realStartingYear = $startingYear;
$realEndingYear = $endingYear;
//Find the real starting year by going back a year until we hit the right one
while ($realStartingYear % $columns) {
$realStartingYear--;
}
//Find the real ending year by going forward a year until we hit the right one
while ($realEndingYear % $columns) {
$realEndingYear++;
}
echo '<table width="755" border="1">';
echo "<tr>";
for ($year = $realStartingYear; $year < $realEndingYear; $year++) {
if (!($year % $columns)) {
echo "</tr><tr>";
}
echo "<td>" . ($year >= $startingYear && $year <= $endingYear ? $year : "") . "</td>";
}
echo "</tr>";
echo "</table>";
?>
If you want to show the other columns as well, just change
echo "<td>" . ($year >= $startingYear && $year <= $endingYear ? $year : "") . "</td>";
to
echo "<td>" . $year . "</td>";
SOLUTION 2
You want to start the table with 1912, like so:
The code will be a lot simpler:
<?php
$columns = 12;
$startingYear = 1912;
$endingYear = 2013;
echo '<table width="755" border="1">';
for ($i = $startingYear; $i <= $endingYear; $i += $columns) {
echo "<tr>";
for ($j = 0; $j < $columns; $j++) {
echo "<td>" . ($i + $j) . "</td>";
}
echo "</tr>";
}
echo "</tr>";
echo "</table>";
?>
You want to wrap every 12 columns, just keep track of the current column and use that to determine when you should end the row (e.g. every 12th column) --
$col = 1;
while ($Year <= 2013 && $col++) {
if (!($col % $columns)) {
//...
Using $Year to determine when to wrap just complicates things.
Trying to test which row the loop is on and if it's greater than or equal to six, plug the $TESTIMAGE variable into the span element for the next iteration.
When I run the code, it plugs the variable into everything following the first row.
While($row = mysql_fetch_array($result))
{
//assign variables
$title = $row['title'];
$url = $row['location'];
$image = "/waves/files/images/games/$title.png";
echo "
<span class='dropt'>
<a href=$url>$title</a>
<span class='$TESTIMAGE'>
<img src='$image'>
</span>
</span>
<br />
";
//Test to see which row we're on -- adjust image position
If (mysql_num_rows($result) >= 6)
{
$TESTIMAGE = "image_display_up";
}
}
use an increasing index:
$i = 0;
while($row = mysql_fetch_array($result)){
$i += 1;
}
That is because mysql_num_rows() will return the same exact value for each iteration of the loop, as the number of rows in the result change will not change.
You would need to implement a counter to do what you are wanting to do.
try it like this:
$i = 1;
While($row = mysql_fetch_array($result)) {
if(!($i%6)) { // will enter here on the 6th try.
//assign variables
$title = $row['title'];
$url = $row['location'];
$image = "/waves/files/images/games/$title.png";
echo "
<span class='dropt'>
<a href=$url>$title</a>
<span class='$TESTIMAGE'>
<img src='$image'>
</span>
</span>
<br />
";
}
if($i!=6) // this way it remains on 6
$i++;
}
$i=0;
While($row = mysql_fetch_array($result)) {
//assign variables
$title = $row['title'];
$url = $row['location'];
$image = "/waves/files/images/games/$title.png";
$TESTIMAGE = ($i++ >= 6) ? "image_display_up" : "";
echo "
<span class='dropt'>
<a href=$url>$title</a>
<span class='$TESTIMAGE'>
<img src='$image'>
</span>
</span>
<br />
";
}
The call to mysql_num_rows($result) always returns the same number. You want to increment an index on each iteration instead:
$idx = 0
while (blah) {
if ($idx >= 6)
{
$TESTIMAGE = "image_display_up";
}
$idx += 1
}