I've recently posted a similar question but that was to create one row of cells across and after it reaches 3 columns, it creates a new row, so I can have 3 columns of infinite rows. That was solved.
Now what I need is this (GIVEN A and B should be records from the database using $row = mysql_fetch_array($results) so basically it would be something like $row['username']; for A and B ).
<tr>
<td><img src="images/ava/A.png" /></td>
<td>A</td>
<td width="2px" rowspan="3"></td>
<td><img src="images/ava/B.png" /></td>
<td>B</td>
</tr>
<tr>
<td><div class="gauge"><div class="innergauge"></div>A</div></td>
<td><div class="gauge"><div class="innergauge"></div>B</div></td>
</tr>
<tr>
<td>A</td>
<td>B</td>
</tr>
As what you can see, the record I got from my database has to fill in to this format, where A is one record and B is another, then if there is record C, this whole thing should repeat again to form a second row.
Build each section as you go, combine them at the end. Here's how you do sections 1 and 3, the middle section is left as an exercise:
$section1 = '<tr>';
$section2 = // start $section2
$section3 = '<tr>';
$i = 0;
while($row = mysql_fetch_array(...)){
if($i > 0){
// won't happen the first time through the loop
$section1.= '<td width="2px" rowspan="3"></td>';
}
$section1 .= '<td><img src="images/ava/'.$row['username'].'"/></td>';
$section1 .= '<td>'.$row['username'].'</td>';
// now do $section2
$section3 .= '<td>'.$row['username'].'</td>';
$i++;
}
$section1 .= '</tr>';
// finish $section 2
$section3 .= '</tr>';
// now output
echo $section1 . $section2 . $section3;
Related
I am working on an homework assignment, and I am having a hard time with it. Any help is appreciated!
For the Module 2 Exercise, students will write a PHP program named "moduletwo.php" that generates an HTML table with the following requirements:
A function called "makeTable($headerArray, $numRows)" that creates a table with headers as they appear in the array and however many rows are specified.
If a number of rows is not specified, use a default of 5
Even number rows should use the class "dark"
Odd number rows should use the class "light"
There should be a column that has only the row number
Create an array of table headers (these can be whatever you want, but be creative here, and do not just use "Heading 1" or generic term)
This function will be used in the body of the HTML document to create an empty table with the array of headers
The HTML document should be complete, including DOCTYPE and all necessary elements.
Write a CSS file named "moduletwo.css" to go along with this that creates the "dark" and "light" classes with background colors of your choosing, but that must be readable and reflect the "dark" and "light" names. Link to this in the head section of the page."
this is what i have so far:
<?php
function makeTable($headerarray, $numrows)
{
echo "<table>"; # echo the table begining
foreach ($headerarray as $header) { # loop through the erray to print the th tag
echo "<th>" . $header . "</th>";
}
foreach ($numRows as $row) { #loop $numrows times to create that number of empty rows
echo "<tr>";
echo "<td>";
echo "</td>";
echo "</tr>";
}
echo "</table>"; # echo table ending;
}
$headers = array(
"Book Title",
"Book Author",
"Publication Date",
"Book Pages",
"Finished Book"
);
makeTable($headers, 5); #create a table with 5 empty rows under the header
?>
I'm struggling with creating the rows.
First, I want to say that I do not recommend copying this exactly and using it for your homework. You should read the comments and attempt to understand why it does what it does. I've done my best to comment the code so you can learn it.
Newbie Friendly
//define default `$numrows` in function declaration
function makeTable($headerarray, $numrows = 5) {
//create table beginning
echo "<table>";
//create first row, which is your header
//this needs to be done OUTSIDE of the header loop, as there is only 1 set of headers.
echo "<tr>";
//loop through headers using FOREACH
foreach($headerarray as $header) {
//add <th> element for each header
echo "<th>" . $header . "</th>";
}
//end table row (header)
echo "</tr>";
//define ODD class. The first loop is ALWAYS ODD.
$class = 'light';
//get a count of columns
$numcolumns = count($headerarray);
//loop a specific number of times (number of rows), using a FOR loop
for ($row = 1; $row <= $numrows; $row++) {
//create table row inside FIRST FOR LOOP. This creates a row each time.
//also add `$class` to row.
echo "<tr class=\"" . $class . "\">";
//loop a specific number of times (number of columns). This creates a column each time.
for ($column = 1; $column <= $numcolumns; $column++) {
//create a <td> element (cell)
echo "<td>";
if($column == 1) { //if column is 1
//use row number as cell content
echo "Row " . $row;
} else { //if column IS NOT 1
//use column number as content
echo "Column " . $column; #show column number as content
}
//end <td> element (cell)
echo "</td>"; #end row
}
//end table row
echo "</tr>";
//AT THE END OF ROW LOOP, switch `$class` to 'dark' if it is currently 'light'
//or switch it to 'light' if it is currently 'dark'
//since this is at the end of the row loop, it takes effect on the next loop. That means it should alternate between the 2
/***
This solution has several benefits. First, you don't need to know if the current row is even or odd.
second, you could use this to check if the row is even/odd IF YOU NEED TO
(if `$class` is 'light', you know the row is ODD)
**/
if($class == 'light') {
$class = 'dark';
} else {
$class = 'light';
}
}
//end table
echo "</table>";
}
Which results in this HTML using your example data.
<table>
<tr>
<th>Book Title</th>
<th>Book Author</th>
<th>Publication Date</th>
<th>Book Pages</th>
<th>Finished Book</th>
</tr>
<tr class="light"><td>Row 1</td>
<td>Column 2</td>
<td>Column 3</td>
<td>Column 4</td>
<td>Column 5</td>
</tr>
<tr class="dark"><td>Row 2</td>
<td>Column 2</td>
<td>Column 3</td>
<td>Column 4</td>
<td>Column 5</td>
</tr>
<tr class="light"><td>Row 3</td>
<td>Column 2</td>
<td>Column 3</td>
<td>Column 4</td>
<td>Column 5</td>
</tr>
<tr class="dark"><td>Row 4</td>
<td>Column 2</td>
<td>Column 3</td>
<td>Column 4</td>
<td>Column 5</td>
</tr>
<tr class="light"><td>Row 5</td>
<td>Column 2</td>
<td>Column 3</td>
<td>Column 4</td>
<td>Column 5</td>
</tr>
</table>
The CSS part is pretty simple, you just need to define a dark and light rule.
tr.light {
background-color: LIGHT_COLOR;
}
tr.dark {
background-color: DARK_COLOR;
}
A more advanced approach
If I had to do this, I'd probably do something like this:
function makeTable($headerarray, $numrows = 5) {
$headers = "";
foreach($headerarray as $head) {
$headers .= "<th>{$head}</th>";
}
$body = "";
$numcolumns = count($headerarray);
for ($row = 1; $row <= $numrows; $row++) {
$tmp = "<tr>";
for ($col = 1; $col <= $numcolumns; $col++) {
$content = $col == 1 ? "Row {$row}" : "Column {$col}";
$tmp .= "<td>{$content}</td>";
}
$body .= $tmp . "</tr>";
}
$html = "
<table>
<thead>
<tr>
{$headers}
</tr>
</thead>
<tbody>
{$body}
</tbody>
</table>
";
return $html;
}
This function returns the table instead of directly echoing it. This allows you to do more stuff with the HTML at the very end if you need to. You would use this function like this:
$headers = array(
"Book Title",
"Book Author",
"Publication Date",
"Book Pages",
"Finished Book"
);
echo makeTable($headers, 5);
I also completely removed the classes from the rows, because it's easier to do with CSS alone, which will react better to rows being removed by javascript or whatever. It can be applied like this:
tbody > tr:nth-child(even) {
background-color: DARK_COLOR;
}
tbody > tr:nth-child(odd) {
background-color: LIGHT_COLOR;
}
I have the following code inside a WHILE loop following a MySQL query:
$values=array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30);
echo "<tr>
<td class='results'>$values</td>
<td class='results'>working query</td>
</tr>"
I need the $values variable to populate and increase by 1 for each row obtained from the query.
Desired result:
1 | data
2 | data
3 | data
You didn't post the while loop, so I just assume how it looks like. You can just add a simple counter variable and increase for every row returned from DB:
$i = 1;
while ($row = mysqli_fetch_assoc($res)) {
echo "<tr>
<td class='results'>$i</td>
<td class='results'>working query</td>
</tr>";
$i++;
}
use that code please
<table>
<?php
$values=array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30);
foreach($values as $v){
echo "<tr>
<td class='results'>$v</td>
<td>|</td>
<td class='results'>working query</td>
</tr>";
}
?>
</table>
My database colleague built a couple of views and SP's for me so I can focus on html/php.
One is a query that shows a "total" row at the bottom of the table.
I want to:
Exclude this last row on my <tbody>
Show this single row in my <tfoot>
Why don't I just show everything in <tbody> since the totals row will always show at the bottom anyway? Because I want my <tfoot>'s <td>'s colspan to be different, for presentation purposes.
How can I do this using php alone?
I'm using basic PDO:
foreach($table as $row) {
echo '<tr>
<td>'.$row['Item'].'</td>
<td>'.$row['Amount'].'</td>
</tr>';
}
This should work as long as the last row is not exactly the same as any other row.
$last_row = end($table);
echo '<tbody>';
foreach ($table as $row) {
if ($row === $last_row) continue;
echo '<tr>
<td>'.$row['Item'].'</td>
<td>'.$row['Amount'].'</td>
</tr>';
}
echo '</tbody>';
echo '<tfoot>
<tr>
<td>'.$last_row['Item'].'</td>
<td>'.$last_row['Amount'].'</td>
</tr>
</tfoot>';
If it's possible that the last row is not unique you can use the key instead:
$last_key = count($table) - 1;
echo '<tbody>';
foreach ($table as $key => $row) {
if ($key === $last_key) continue;
echo '<tr>
<td>'.$row['Item'].'</td>
<td>'.$row['Amount'].'</td>
</tr>';
}
echo '</tbody>';
echo '<tfoot>
<tr>
<td>'.$table[$last_key]['Item'].'</td>
<td>'.$table[$last_key]['Amount'].'</td>
</tr>
</tfoot>';
$total = 0;
foreach($table as $row) {
$total += $row['Amount'];
echo '<tr>
<td>'.$row['Item'].'</td>
<td>'.$row['Amount'].'</td>
</tr>';
}
echo '<tr>
<td>Total:</td>
<td>'.$total.'</td>
</tr>';
You don't need to use thead or tfoot if you do not intend to use them to style your content or in some cases SEO purposes.
How can I remove the last element in a do-while generated table?
In my case the last tr/td where div.dividing_line is stored.
The code:
$ArrayLength = 6;
$i = 1;
do {
echo '
<tr>
<td valign="middle">Data_Position</td>
<td valign="middle">Data_Item</td>
<td valign="middle">Data_Pieces</td>
<td valign="middle">Data_Price</td>
</tr>
<tr>
<td colspan="4"><div class="dividing_line"></div></td>
</tr>
';
++$i;
} while ($i < $ArrayLength+1);
For example: If I have an array with 6 items, normally the do-while will do the job, so finally there will be 6 tr's with data and 6 tr's with the dividing_line.
What I need is 6 tr's of data and 5 tr's of dividing_line. Is that possible?
Try this-
$ArrayLength = 6;
$i = 1;
do {
echo '
<tr>
<td valign="middle">Data_Position</td>
<td valign="middle">Data_Item</td>
<td valign="middle">Data_Pieces</td>
<td valign="middle">Data_Price</td>
</tr>';
if($i != $ArrayLength) {
echo '<tr>
<td colspan="4"><div class="dividing_line"></div></td>
</tr>
';
}
++$i;
} while ($i < $ArrayLength+1);
Use an extra if Statement to check whether you are at the last element:
if (%i < $ArrayLength) { echo '<tr>...dividing_line</tr>'; }
$ArrayLength = 6;
$i = 1;
do {
echo '
<tr>
<td valign="middle">Data_Position</td>
<td valign="middle">Data_Item</td>
<td valign="middle">Data_Pieces</td>
<td valign="middle">Data_Price</td>
</tr>';
if($i < $ArrayLength)
{
echo '
<tr>
<td colspan="4"><div class="dividing_line"></div></td>
</tr>';
}
++$i;
} while ($i < $ArrayLength+1);
I think your approach just needs an additional step.
It could be something like this:
$data = null;
foreach ($rows as $row) {
$data[] = "<tr><td valign=\"middle\">Data_Position</td><td valign=\"middle\">Data_Item</td><td valign=\"middle\">Data_Pieces</td><td valign=\"middle\">Data_Price</td></tr>";
}
print implode("<tr><td colspan=\"4\"><div class=\"dividing_line\"></div></td></tr>", $data);
This way, you could accomplish what you want without any more logic. Of course, it can be changed or re-design, but I think this way will provide you with a simple yet elegan solution to your problem.
Hope it helps :P
I have code which retrieves information about players from a MySQL database. I want to apply a special case to the HTML output if their ranking changes. I want it to look like this: http://i27.tinypic.com/f406tz.png
But i cant get it to be like i want, instead it prints the rank on every row:
$old_rank = '';
while ($g = mysql_fetch_object($q)) {
if ($g->rankname != $old_rank) {
echo "<tr><td>$g->rankname</td>\n";
$old_rank = "<tr><td> </td>\n";
}
echo " <td>$g->name</td></tr>\n";
}
What I want:
<tr>
<td>One</td>
<td>Kraven the Hunter</td>
</tr>
<tr>
<td> </td>
<td>Kull the Conqueror</td>
</tr>
<tr>
<td> </td>
<td>Zazi The Beast</td>
</tr>
<tr>
<td>Vice-leader</td>
<td>Igos du Ikana</td>
</tr>
<tr>
<td> </td>
<td>Saint Sinner</td>
</tr>
<tr>
<td> </td>
<td>Midvalley the Hornfreak</td>
</tr>.......................
What I get:
<tr><td>One</td>
<td>Tester</td></tr>
<tr><td>One</td>
<td>Kraven the Hunter</td></tr>
<tr><td>One</td>
<td>Kull the Conqueror</td></tr>
<tr><td>One</td>
<td>Zazi The Beast</td></tr>
<tr><td>Vice-Leader</td>
<td>Midvalley the Hornfreak</td></tr>
<tr><td>Vice-Leader</td>
<td>Saint Sinner
</td></tr>
<tr><td>Vice-Leader</td>
<td>Igos du Ikana</td></tr>
$old_rank is never equal to $g->rankname because the way you are setting $old_rank, it will contain HTML tags, and the $g->rankname that you get from the DB will never have HTML tags.
Try changing your if statement to something like this:
if ($g->rankname != $old_rank) {
echo "<tr><td>$g->rankname</td>\n";
$old_rank = $g->rankname;
} else {
echo "<tr><td> </td>\n";
}
It prints the rank name if it's a new rank name, else it prints empty space.
The following (notwithstanding typos) separates out the display logic from the database loop. This has the advantages:
- You don't need to depend on the order of the results returned
- You don't need to maintain dodgy logic (like 'old_rank')
- You can display them more nicely (with a rowspan for repeated ranks
I believe the total code is more compact too.
// fill ranks array
$ranks = array();
while ( $g = mysql_fetch_object($q) ) {
if ( !in_array($g->rankname, $ranks) ) {
$ranks[htmlentities($g->rankname)] = array();
}
$ranks[$g->rankname][] = htmlentities($g->name);
}
// do other program logic here
// end of program
?>
<!-- display the page -->
<table>
<tr>
<th>Rank</th><th>Users</th>
</tr>
<?php foreach($ranks as $rankName => $userList): ?>
<tr>
<td rowspan="<?php echo (string)sizeof($userList); ?>">
<?php echo $rankName; ?>
</td>
<td> <?php echo implode('</td></tr><tr><td>', $userList); ?> </td>
</tr>
<?php endforeach; ?>
</table>
I prefer breaking things up a bit more than that. Keeping things separate makes it easier to modify. This should work.
$old_rank = '';
while ($g = mysql_fetch_object($q)) {
echo '<tr>' . "\n";
echo '<td>';
if ($g->rankname != $old_rank) {
$old_rank = $g->rankname;
echo $old_rank;
} else {
echo ' ';
}
echo '</td>';
echo '<td>' . $g->name . '</td>' . "\n";
echo '</tr>' . "\n";
}