Here is the problem:
I need to know if there is a way to do an upward rowspan on a <th> element on a form.
I am reading some rows inside a DB that I need to put inside an html table.
I am doing something like:
echo "<table>";
while($result = $resultSet->fetch())
{
echo "<tr>";
echo "<td>$result['Name']</td>";
echo "<td>$result['Job']</td>";
echo "</tr>";
}
ehco "</table>";
First steps are easy until I needed to 'span' together two adjacent cells that contains the same value.
For exemple if someone have the same name but had two jobs I would like them to have something like :
echo "<tr>";
echo "<td rowspan='2'>$result['Name']</td>";
echo "<td>$result['Job']</td>";
echo "</tr>";
But I can't predict how many jobs someone have (except they all have at least one and that they are all in order).
exemple of record in MySQL table
Name/**/Jobs
Paul/**/Jobs1
Simon/**/Jobs23
Simon/**/Jobs45
Roger/**/Jobs67
(All simon's jobs are 'behind one another', they are grouped. If Paul had a second job it would be the second record in the table 'pushing' simons jobs down).
So I need to change the rowspan value of the first element to fit how many jobs that person have.
This is why I would need to know if it is possible to do a upward span because i could just display every on of them and count how many jobs each person have and do a rowspan that would merge the table cell upward.
It would certainly be easier then fetching every row in the DB then looping throught them all and checking how many jobs a person have to 'span' the cells now and then display them all and then skipping them. and so on.
Thanks
A situation like this calls for pre-processing. Like so:
$people = array();
while($result = $resultSet->fetch())
{
if( !isset($people[$result['Name']])) $people[$result['Name']] = array();
$people[$result['Name']][] = $result['Job'];
}
echo "<table>";
foreach($people as $name=>$jobs)
{
echo "<tr>";
echo "<td rowspan=\"".count($jobs)."\">".$name."</td>";
echo "<td>".array_shift($jobs)."</td>";
echo "</tr>";
foreach( $jobs as $otherjob)
{
echo "<tr><td>".$otherjob."</td></tr>";
}
}
echo "</table>";
Done!
What you're looking for doesn't exist in HTML. But you can do it like this:
$currName = $result['Name'];
echo "<tr>";
if($currName==$prevName)
{
echo "<td> </td>";
}
else
{
echo "<td>$result['Name']</td>";
}
echo "<td>$result['Job']</td>";
echo "</tr>";
$prevName = $currName;
Rather than using rowspan, just nest a table in the second column with all of the jobs for that person.
echo "<tr>";
echo "<td>$result['Name']</td>";
echo "<td>";
echo "<table>"
foreach($jobs as $job): //$jobs holds the job values for the current name
echo "<tr><td>";
echo $job;
echo "</td></tr>";
endforeach;
echo "</table>";
echo "</td>";
echo "</tr>";
Note: you will need to preprocess the result set to get a 2D array for this method (see answer from Niet the Dark Absol).
Related
I have two MySQL tables with number of columns. The table structure is given below,
1.pictures
postedON
caption
imageName
thumbName
imageLocation
thumbLocation
2.Videos
postedOn
category
Link
I am using the folowing PHP function to fetch data from DB using a select command.
function select($table){
if($this->db_connection){
$query = 'SELECT * FROM '. $table;
$result = mysqli_query($this->db_connection,$query) or die($this->db_connection->error);
//print_r($result);
//echo "Affected rows: " . mysqli_affected_rows($this->db_connection);
//var_dump($result);
echo "<table>";
echo "<tr>";
echo "<th>Date Posted</th>";
echo "<th>Category</th>";
echo "<th>Link</th>";
echo "</tr>";
while($row = $result->fetch_assoc()){
echo "<tr>";
echo "<td>" . $row['postedOn'] . "</td>";
echo "<td>".$row['category']. "</td>";
echo "<td>" . $row['link'] . "</td>";
echo "</tr>";
}
echo "</table>";
}else{
echo "db_connection is = " . $this->db_connection;
}
}
}
The problem with this function as you can see, it can only serve only one table and not dynamic. Can someone please explain the way to dynamically fetch data from different table with different number of columns using only one PHP function? Thanks
Try using mysqli_fetch_fields()
<?php
function select($table){
if($this->db_connection){
$query = 'SELECT * FROM '. $table;
$result = mysqli_query($this->db_connection,$query) or die($this->db_connection->error);
$fieldinfo = mysqli_fetch_fields($result);
echo "<table>";
echo "<tr>";
foreach ($fieldinfo as $val)
{
echo "<th>".$val->name."</th>";
}
echo "</tr>";
while($row = $result->fetch_assoc()){
echo "<tr>";
foreach ($fieldinfo as $val)
{
echo "<td>" . $row[$val->orgname] . "</td>";
}
echo "</tr>";
}
echo "</table>";
}else{
echo "db_connection is = " . $this->db_connection;
}
}
It could be hard to explain given all the wrong premises you approach is based on, but I'll try.
First of all, you have to understand that a query like SELECT * FROM table has a very little use, next to none. Most of time you are always have some WHERE or at least LIMIT clause. So, such a function will have no use at all.
Next, you have to learn by heart that database interaction should never be intermixed with any output stuff like HTML.
Given these two premises above, your function should accept a fill qualified query as a parameter and return an array with data as a result.
For which array, in turn you can write a helper function to display its contents in the form of HTML table.
But again, such a generalized output function will be of little use as well, because, as you can see from your own example, different fields will need different formatting. So it's better to write output each time by hand.
I'm putting together something that's mean to allow for a user to book seats for a cinema showing. The row and seat numbers for every showing are stored in the database. I'm currently extracting them in the following method so that users can click on a seat button to select that seat for their booking:
echo "<form>";
echo "<table>";
while($row = mysqli_fetch_assoc($result)){
$rownum = $row['row'];
$seat = $row['seat'];
echo "<tr><td><button type=\"submit\" name=\"seatsel\" value=\"$rownum$seat\">$rownum$seat</button></td></tr>";
}
echo "</table>";
Right now this just outputs html showing all of the buttons as a single row in the table. I'd like the output to show seating across a single table row for every one of the table rows in the cinema screen. I'm not sure how to do this exactly given that each row is of differing lengths. E.g row A has twelve seats while row C has eight.
What would be the best way of accomplishing this?
You could easily update your code so that you will get a new table row every time the mysql row has another value. One thing to note is that you might want to add (depending on whether you're already sorting your results) the following ORDER BY row,seat.
echo "<form>";
echo "<table>";
echo "<tr>";
while($row = mysqli_fetch_assoc($result)){
if (!isset($oldrownumber)) $oldrownumber = $row['row'];
else if ($oldrownumber != $row['row']) {
echo "</tr><tr>";
$oldrownumber = $row['row'];
}
$rownum = $row['row'];
$seat = $row['seat'];
echo "<td><button type=\"submit\" name=\"seatsel\" value=\"$rownum$seat\">$rownum$seat</button></td>";
}
echo "</tr>";
echo "</table>";
I use a MySql query to select data from my DB and then print it in the form of a HTML Table. It works perfectly, fine but sometimes the table consists of hundreds of rows and the webpage looks incredibly akward. Is there a way to split the table side by side into 2 or 3 halves.
Present Output
Desired output
PHP
<?php
....
echo "<h3>Classes attended :</h3>";
echo "<table class='dates' border='1'>";
foreach ($results as $dates) {
echo "<tr><td width='50%'>";
echo $dates->db_date;
echo "</td>";
echo "<td width='50%'>";
echo $dates->day_name;
echo "</td>";
echo "</tr>";
}
echo "</table>";
?>
What would be the best way to achieve it?
Help would be appreciated.
You can use PHP to determine in your loop if the loop index is divisible by a certain number using something like this:
echo "<h3>Classes attended :</h3>";
echo "<table class='dates' border='1'>";
$rowCount = 1;
$numRows = count($results);
$maxRows = 12;
foreach ($results as $dates) {
echo "<tr><td width='50%'>";
echo $dates->db_date;
echo "</td>";
echo "<td width='50%'>";
echo $dates->day_name;
echo "</td>";
echo "</tr>";
if($rowCount % $maxRows == 0 && $rowCount != $numRows) {
echo "</table><table class='dates' border='1'>";
}
$rowCount ++;
}
echo "</table>";
That's the basics of doing this. Basically in your loop you're testing each index to see if it's divisible by $maxRows, and if so then you're going to close your table and open a new one. You'll have to add the styling to place the tables side by side.
If you wanted to expand upon this concept you can set $maxRows to be an evaluation of $numRows. For instance if you wanted to split the items as close as possible to half in order to show just two tables, you could do... $numRows = count($results); $maxRows = round($numRows / 2);
Inspired by Robert Wade's answer:
<?php
....
echo "<h3>Classes attended :</h3>";
$i=0;
$maxRows=10;
foreach ($results as $dates) {
$a=$i/$maxRows == 0 ? "<table class='dates' border='1'>":"";
$b=$i/$maxRows == 0 ? "</table>":"";
echo $a;
echo "<tr><td width='50%'>";
echo $dates->db_date;
echo "</td>";
echo "<td width='50%'>";
echo $dates->day_name;
echo "</td>";
echo "</tr>";
echo $b;
$i++;
}
?>
At last, add some css style to the tables.
You can also use array_chunk() for splitting your results. Or instead of displaing a lot of tables next to each other you can make pagination and get only some range in your query. For example:
SELECT * FROM `clients` LIMIT 5, 10
Selects 10 rows beggining from row 5. Now, when you change your page, just change limit values.
I tried to print the Mysql fetched rows into html table using php. However, when using the following code, the first fetched row is repeatedly printing. It looks like the $row hold the first fetched value. I found a similar problem here. But I would like to know about working with the for loop. Thanks
for ($j=0;$j<=$len2;$j++)
{
$sql = "SELECT * FROM database_search WHERE gene_id LIKE'%$key%'";
$qry = $dbo->prepare($sql);
$qry->execute();
$row = $qry->fetch(PDO::FETCH_ASSOC);
$val = array_values($row);
echo "<tr>";
for ($k=0;$k<=4;$k++)
{
$x=$val[$k];
echo "<td style=font-size:7.9px>$x</td>";
}
echo "</tr>";
}
<table>
<?php
while($row = $qry->fetch(PDO::FETCH_ASSOC)){
echo '<tr>';
foreach($row as $cell){ echo '<td>'.$cell.'</td>'; }
echo '</tr>';
}
?>
</table>
After fetching the query as $row variable, you need to use the following code instead
foreach($row as $tr) {
echo "<tr>";
echo "<td style=font-size:7.9px>".$tr['col1']."</td>";
echo "<td style=font-size:7.9px>".$tr['col2']."</td>";
echo "</tr>";
}
This is possible that $row only have one record fetching from database and than your for ($k=0;$k<=4;$k++) loop print that only one record 5 time
because you are using print under this loop, this loop will run 5 time.
Try the following code.
foreach($row as $val) {
echo "<tr>";
echo "<td style=font-size:7.9px>".$val['column Name']."</td>";
echo "</tr>";
}
I would like to add a row, after the loop, the number of rows before the LAST row is random based on the user's orders. so for example the user ordered 10, i would like to add another row, to the list. even if the order is 3 there would still be another row at the end.
while ($row=mysql_fetch_array($result)){
echo "<tr>";
echo "<td>".$row['prod_name']."</td>";
echo "<td>".$row['quantity']."</td>";
echo "<td>₱".number_format(($row['price']*$row['quantity']),2)."</td>";
echo "</tr>";
if($row['carrier']=="LBC"){
echo "<tr>";
echo "<td>Shippment Option Chosen: ".$row['carrier']."</td>";
echo "<td></td>";
echo "<td>₱250.00</td>";
echo "</tr>";
}
}
echo "</table>";
?>
Here, i made it create another row, but it creates a row after each row, i just need to add 1 row at the end of the table. Thank you :)
Hmm Why not just add a new query? I fixed your codes. and added these.
$qryx = "SELECT DISTINCT customers.serial,customers.name,customers.payment,customers.carrier,customers.tracking_no, orders.date, order_detail.productid, order_detail.quantity, order_detail.price, order_detail.orderid, inventory.prod_name
FROM customers
RIGHT JOIN orders on customers.serial=orders.serial
RIGHT JOIN order_detail on orders.serial=order_detail.orderid
LEFT JOIN inventory on order_detail.productid=inventory.prod_id
where customers.email='{$_SESSION['email']}'
AND order_detail.orderid='{$_REQUEST['orderid']}'
GROUP BY customers.carrier";
$resulty = #mysql_query($qryx);
while ($rowz=mysql_fetch_array($resulty)){
if($rowz['carrier']=="LBC"){
echo "<tr>";
echo "<td>Shippment Option Chosen: ".$rowz['carrier']."</td>";
echo "<td></td>";
echo "<td>₱250.00</td>";
echo "</tr>";
}
}
I changed the name of the qry, result, and row. and added DISTINCT and GROUP BY to remove redundancy.
You should add a line right before your
echo "</table>";
line, but after the closing bracket before it. That last closing bracket is where your loop ends. It should look like this:
while ($row=mysql_fetch_array($result)){
echo "<tr>";
echo "<td>".$row['prod_name']."</td>";
echo "<td>".$row['quantity']."</td>";
echo "<td>₱".number_format(($row['price']*$row['quantity']),2)."</td>";
echo "</tr>";
if($row['carrier']=="LBC"){
echo "<tr>";
echo "<td>Shippment Option Chosen: ".$row['carrier']."</td>";
echo "<td></td>";
echo "<td>₱250.00</td>";
echo "</tr>";
}
}
echo "<tr>";
echo "<td>LAST LINE...</td>";
echo "<td></td>";
echo "<td></td>";
echo "</tr>";
echo "</table>";
?>
You can use mysqli_num_rows to get the no. of rows. Then you can add a counter in the while loop. When the counter = mysqli_num_rows, you can echo the row you wanted to echo at last
Example:
$totalrows=mysqli_num_rows($result);
$counter=1;
while ($row=mysql_fetch_array($result)){
//echo the row data
if($counter==$totalrows)
{
//echo the extra row which you wanted.
}
}
echo "</table>";