Limit maximum number of <td> elements of a table per line - php

I want to build a page where I need to show all the members from a database. But when I print them, it shows them on the same line, no matter how much the members are. And I want to limit the number of members per line to 5. How can I do this?
Thank you in advance!
<table id="members-table">
<tr>
<?php
$queryContent = "SELECT * FROM users WHERE member='yes'";
$result = mysqli_query($db_connection, $queryContent);
while($row = mysqli_fetch_assoc($result)) {
echo '<td>
<div class="card">
<img src="img/img_avatar2.png" alt="Avatar">
<div class="container">
<h4><b>' .$row['ShownName']. '</b></h4>
<p style="font-family:Roboto;">Architect & Engineer</p>
</div>
</td>';
}
?>

First, you should consider not using table elements to align your content. This is an outdated practice and not recommended. Check out this StackOverflow question for some great advice on the subject. In short, using tables for laying out your page contents comes from the earlier days of the web before we had things like flexbox and grid layouts.
To answer your question, though, you should implement a $loop_count variable, and echo "</tr><tr>" each time $loop_count > 0 AND $loop_count % 5 == 0.

You have to write a <tr> tag on each 5 loops, except for the first loop.
Add $num=0. Then, in the loop, check if $num is greater than 1 (not for the first loop), and the modulo % with five is zero.
<table id="members-table"><tr>
<?php
$queryContent = "SELECT * FROM users WHERE member='yes'";
$result = mysqli_query($db_connection, $queryContent);
$num = 0;
while($row = mysqli_fetch_assoc($result)) {
if ($num++ % 5 == 0 && $num > 1) echo '</tr><tr>'; // Change is here
echo '<td>
<div class="card">
<img src="img/img_avatar2.png" alt="Avatar">
<div class="container">
<h4><b>' .$row['ShownName']. '</b></h4>
<p style="font-family:Roboto;">Architect & Engineer</p>
</div>
</td>';
}
?></tr></table>

The devil is in the detail on this one. Because you are building a table (which must have an equal number of columns in each row) you need to write conditionals to build a complete structure.
First, a set of conditionals to separate the data into rows of 5 cells
Second, a conditional after the loop to ensure that the final table row contains the correct number of cells.
Code: (Demo)
$resultset=[
['ShownName'=>'A'],
['ShownName'=>'B'],
['ShownName'=>'C'],
['ShownName'=>'D'],
['ShownName'=>'E'],
['ShownName'=>'F'],
['ShownName'=>'G']
];
echo "<table>";
$counter=0;
foreach($resultset as $row){ // you while loop
if($counter%5==0){
if($counter){
echo "</tr>";
}
echo "<tr>"; // start new row
}
echo "<td>";
echo "<div class=\"card\">";
echo "<img src=\"img/img_avatar2.png\" alt=\"Avatar\">";
echo "<div class=\"container\">";
echo "<h4><b>{$row['ShownName']}</b></h4>";
echo "<p style=\"font-family:Roboto;\">Architect & Engineer</p>";
echo "</div>";
echo "</div>";
echo "</td>";
++$counter;
}
if($mod=$counter%5){
$colspan=5-$mod;
echo "<td",($colspan>1?" colspan=\"$colspan\"":""),"></td>"; // complete the row with appropriately sized cell
}
echo "</tr>";
echo "</table>";
Output:
<table>
<tr>
<td>
<div class="card">
<img src="img/img_avatar2.png" alt="Avatar">
<div class="container">
<h4><b>A</b></h4>
<p style="font-family:Roboto;">Architect & Engineer</p>
</div>
</div>
</td>
<td>
<div class="card">
<img src="img/img_avatar2.png" alt="Avatar">
<div class="container">
<h4><b>B</b></h4>
<p style="font-family:Roboto;">Architect & Engineer</p>
</div>
</div>
</td>
<td>
<div class="card">
<img src="img/img_avatar2.png" alt="Avatar">
<div class="container">
<h4><b>C</b></h4>
<p style="font-family:Roboto;">Architect & Engineer</p>
</div>
</div>
</td>
<td>
<div class="card">
<img src="img/img_avatar2.png" alt="Avatar">
<div class="container">
<h4><b>D</b></h4>
<p style="font-family:Roboto;">Architect & Engineer</p>
</div>
</div>
</td>
<td>
<div class="card">
<img src="img/img_avatar2.png" alt="Avatar">
<div class="container">
<h4><b>E</b></h4>
<p style="font-family:Roboto;">Architect & Engineer</p>
</div>
</div>
</td>
</tr>
<tr>
<td>
<div class="card">
<img src="img/img_avatar2.png" alt="Avatar">
<div class="container">
<h4><b>F</b></h4>
<p style="font-family:Roboto;">Architect & Engineer</p>
</div>
</div>
</td>
<td>
<div class="card">
<img src="img/img_avatar2.png" alt="Avatar">
<div class="container">
<h4><b>G</b></h4>
<p style="font-family:Roboto;">Architect & Engineer</p>
</div>
</div>
</td>
<td colspan="3"></td>
</tr>
</table>

Using the mod operator (%) will do the trick. This will work and not produce extra unnecessary TR's or /TR's (with the exception of a single empty row if the data is blank):
<table id="members-table">
<?php
$queryContent = "SELECT * FROM users WHERE member='yes'";
$result = mysqli_query($db_connection, $queryContent);
$i = 0;
while($row = mysqli_fetch_assoc($result)) {
if ($i % 5 == 0) {
echo "<tr>";
}
echo '<td>
<div class="card">
<img src="img/img_avatar2.png" alt="Avatar">
<div class="container">
<h4><b>' .$row['ShownName']. '</b></h4>
<p style="font-family:Roboto;">Architect & Engineer</p>
</div>
</td>';
if ($i % 5 == 4 || $i - 1 == count($cols)) {
echo "</tr>";
}
$i++;
}
?>

Related

Creating Bootstrap Accordionin in a while loop

I'm trying to create a dynamic content field where each data is in a separate accordion and am having a bit of trouble.
Result is the first accordion only works even i am having different id's for each accordion.
Can anyone help me on this
while ($row = mysqli_fetch_assoc($sql_result))
{
$i=1;
?>
<div class="container-fluid border">
<table width=100%>
<tr>
<td><img src="/images/vehicles/<?php echo strtolower($row['vtype']); ?>.jpg" width="75" heigth="75" alt=""></td>
<td align="center"><b><?php echo $row['vtype']; ?> A/C </b> - <?php echo $row['nos']; ?> Seater<br>
<b>₹ <?php if($duration=='8hrs') { $basefare=$row['8hrs']; } elseif($duration=='10hrs') { $basefare=$row['10hrs']; } else { $basefare=$row['12hrs']; } $base=$basefare+($basefare*5/100); echo number_format($base,2,".",","); ?> </b></td>
<td align="right">Book</td>
</tr>
</table>
</div>
<div id="accordionfare<?php echo $i; ?>">
<div class="card">
<div class="card-header" align="right">
<a class="card-link" data-toggle="collapse" href="#collapsefare<?php echo $i; ?>">Fare Details</a>
</div>
<div id="collapsefare<?php echo $i; ?>" class="collapse" data-parent="#accordionfare<?php echo $i; ?>">
<div class="card-body">
<p align="center"><b>Fare Details: </b>Base Fare: ₹ <?php echo number_format($basefare,2,".",","); ?> | GST # 5%: ₹ <?php echo number_format(round($base*5/100),2,".",","); ?> | Extra Hr Fare: ₹ <?php echo number_format($row['extrahr'],2,".",","); ?>/Hr | Extra Km Fare: ₹ <?php echo number_format($row['extrakm'],2,".",","); ?>/Km</p>
<?php $i++; ?>
</div>
</div>
</div>
</div><br>
<?php
}
?>
I've tested your code replacing your data and it works as expected. Check you PHP error log in case there are errors which might brake the loop in some way.
Here is a sandbox where you can Execute my test code and check the HTML result
P.S. You must have accordions with different ids in order to open each one separately.

I want to create html cards with data from DB

I want to create html cards from a db.
I created num_rows that count how many cards it will make, but when I fetch and then echo it only shows the first row. How do I show all rows?
$cas = 0;
while($cas < $number){
$cas++;
echo "
<div class='tbook' align='center'>
<div class='tr'>
<div class=''>$name</div>
<div class=''>$role</div>
<div class=''>$admin</div>
</div>
</div>
";
}
I think its better idea to use foreach, https://www.php.net/manual/en/control-structures.foreach.php
$rows = getDataFromDatabase();
foreach($rows as $row){
echo "
<div class='tbook' align='center'>
<div class='tr'>
<div class=''>$row['name']</div>
<div class=''>$row['role']</div>
<div class=''>$row['admin']</div>
</div>
</div>
"
}

New containing div after every 3 records

I would like to create a new containing <div> after 3 results, using PDO result loop.
For my self-study-project I have to made a product page with bootstrap and after every 3rd record I have to make a new row and show again 3 col-md-4's, etc, etc.
Now I have this as my code:
<div class="row">
<?php
while ($row = $stmt->fetch(PDO::FETCH_OBJ)) {
?>
<div class="col-md-4">
<div class="product">
<div class="title"><?php echo $row->pname ?></div>
<div class="img"><img
src="../product/img/<?php echo $row->pnumber ?>/<?php echo $row->pthumbnail ?>.jpg?$pop210x210$"/>
</div>
<div class="vijftien"></div>
<div class="deliver">Levertijd: <strong><?php echo $row->pdelivertime ?></strong></div>
<div class="vijf"></div>
<div class="other"></div>
<div class="row">
<div class="col-md-6">
<div class="price"><?php echo $row->pprice ?></div>
</div>
<div class="col-md-6">
<div class="order">
<button class="log_in" id="doLogin">Meer informatie</button>
</div>
</div>
</div>
</div>
</div>
<?php } ?>
</div>
I have visited and studied other questions but I do not really get the idea of how they are doing it and how I can implement the correct method into my code.
As tadman stated in the comment under your question. The best approach should use a modulus operator (%) with 3.
Place your separating condition at the start of each iteration. (Demo)
Like this:
$x=0; // I prefer to increment starting from zero.
// This way I can use the same method inside a foreach loop on
// zero-indexed arrays, leveraging the keys, and omit the `++` line.
echo "<div class=\"row\">";
foreach($rows as $row){
if($x!=0 && $x%3==0){ // if not first iteration and iteration divided by 3 has no remainder...
echo "</div>\n<div class='row'>";
}
echo "<div>$row</div>";
++$x;
}
echo "</div>";
This will create:
<div class="row"><div>one</div><div>two</div><div>three</div></div>
<div class='row'><div>four</div><div>five</div><div>six</div></div>
Late Edit, here are a couple of other methods for similar situations which will provide the same result:
foreach(array_chunk($rows,3) as $a){
echo "<div class=\"row\"><div>",implode('</div><div>',$a),"</div></div>\n";
}
or
foreach ($rows as $i=>$v){
if($i%3==0){
if($i!=0){
echo "</div>\n";
}
echo "<div class=\"row\">";
}
echo "<div>$v</div>";
}
echo "</div>";
To clarify what NOT to do...
Sinan Ulker's answer will lead to an unwanted result depending on the size of your result array.
Here is a generalized example to expose the issue:
Using this input array to represent your pdo results:
$rows=["one","two","three","four","five","six"];
Sinan's condition at the end of each iteration:
$i=1;
echo "<div class=\"row\">";
foreach($rows as $row){
echo "<div>$row</div>";
if($i%3==0)echo "</div>\n<div class='row'>"; // 6%3==0 and that's not good here
// 6%3==0 and will echo the close/open line after the content to create an empty, unwanted dom element
$i++;
}
echo "</div>\n\n";
Will create this:
<div class="row"><div>one</div><div>two</div><div>three</div></div>
<div class='row'><div>four</div><div>five</div><div>six</div></div>
<div class='row'></div> //<--- this extra element is not good
You need to add a new closure tag and open new one every 3th iteration.
<div class="row">
<?php
$sql = "SELECT * FROM products";
$stmt = $conn->query($sql);
$stmt->execute();
$i=1;
while ($row = $stmt->fetch(PDO::FETCH_OBJ)) {
?>
<div class="col-md-4">
<div class="product">
<div class="title"><?php echo $row->pname ?></div>
<div class="img"><img
src="../product/img/<?php echo $row->pnumber ?>/<?php echo $row->pthumbnail ?>.jpg?$pop210x210$"/>
</div>
<div class="vijftien"></div>
<div class="deliver">Levertijd: <strong><?php echo $row->pdelivertime ?></strong>
</div>
<div class="vijf"></div>
<div class="other"></div>
<div class="row">
<div class="col-md-6">
<div class="price"><?php echo $row->pprice ?></div>
</div>
<div class="col-md-6">
<div class="order">
<button class="log_in" id="doLogin">Meer informatie</button>
</div>
</div>
</div>
</div>
</div>
<?php
if($i%3==0)echo "</div><div class='row'>";
$i++;
} ?>
$x = 0;
echo "";
foreach($rows as $row)
{
/* added one more condition for removing empty div.... */
if ($x != 0 && $x % 3 == 0 && $x < count($rows))
{
echo "</div>\n<div class='row'>";
}
echo "<div>$row</div>";
++$x;
}
echo "";

Display top 10 results in codeigniter and display 1st, 2nd and 3rd top values

I am getting output page like this (Shown in below screenshot)
I want gold image to be display to top scorers and silver to second topper and bronze to others
I am using code like this
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-tasks"></i> ScoreBoard</h3>
</div>
<div class="panel-body">
<div class="col-sm-12">
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered">
<tbody>
<?php
$total_exams1 = $this->db->select('title_id')
->from('exam_title')
->count_all_results();
$b1 = $this->db->select('*, (sum(result.result_percent)) / '.$total_exams1.' as percent')
->group_by('users.user_id')
->from('result')
->order_by("percent", "desc" )
->join('users', 'users.user_id = result.user_id', 'left')
->join('states', 'users.state = states.state_id', 'left')
->join('user_zone', 'users.user_zone = user_zone.user_zone_id', 'left')
->limit("10")
->get()
->result();
$j = 1;
foreach($b1 as $z) {
?>
<tr class="<?= ($i & 1) ? 'even' : 'odd'; ?>">
<td style="width:5%;"><?php echo $j; ?></td>
<?php if($z->image == "") { ?>
<td class="hidden-x" style="width:35%;">
<img class="userImgTop10n" src="<?php echo base_url('user-avatar/avatar-placeholder.jpg') ?>" alt="Profile Picture" />
<div class="image_righ">
<b><?php echo $z->user_name; ?></b><br>
<?php echo $z->state_name; ?><br>
<?php echo $z->user_zone_name; ?>
</div>
</td>
<?php } else { ?>
<td class="hidden-x" >
<img class="userImgTop10n" src="<?php echo base_url("user-avatar/".$z->image); ?>" alt="Profile Picture" />
<div class="image_righ">
<b><?php echo $z->user_name; ?></b><br>
<?php echo $z->state_name; ?><br>
<?php echo $z->user_zone_name; ?>
</div>
</td>
<?php } ?>
<?php
$exams_attended1 = $this->db->select('title_id')
->where('user_id', $z->user_id)
->from('result')
->group_by('user_id')
->count_all_results();
?>
<td class="hidden-xxs"><b><?php echo $exams_attended1; ?></b><br>Exams Attended</td>
<td class="hidden-xxs"><b><?php echo $total_exams1; ?></b><br>Total Exams</td>
<td class="hidden-x">
<b><?php echo round($z->percent, 2); ?> %</b><br>Avg Result
<div class="badge_righ">
<?php if($j == 1) { ?>
<span><img class="userBadge" src="<?php echo base_url('Badge_Gold.png') ?>" alt="Badge Gold" /></span>
<?php }
if($j == 2) { ?>
<span><img class="userBadge" src="<?php echo base_url('Badge_Silver.png') ?>" alt="Badge Gold" /></span>
<?php } if($j > 2) { ?>
<span><img class="userBadge" src="<?php echo base_url('Badge_Bronze.png') ?>" alt="Badge Gold" /></span>
<?php } ?>
</div>
</td>
</tr>
<?php
$j++;
}
?>
</tbody>
</table>
</div>
</div>
</div>
</div>
in the above screenshot first 3 rows should be gold images (because of same marks).
You can create a temporary array containing unique reverse sorted average scores. Then, when giving medals, instead of checking for places (1st, 2nd, 3rd...), check if the score matches the 1st, 2nd or 3rd score from that temporary array.
For the screenshot you posted, the array would look like:
$scores = [92.5, 90, 87.5];
and the gold medals would be all the scores with the score of $scores[0], the silver ones are $scores[1] and the bronzes would be $scores[2] (unless you want everyone else to get bronze).

How to make each row of array display individually on another page?

I can not figure out how to make one row of my table display on another page. What I want to do make each individual row printable. Here is a screen shot.
Here is the php used to display the table (coupon_index.php):
<?php include template("header");?>
<div id="bdw" class="bdw">
<div id="bd" class="cf">
<div id="coupons">
<div class="dashboard" id="dashboard">
<ul><?php echo current_account('/coupon/index.php'); ?></ul>
</div>
<div id="content" class="coupons-box clear">
<div class="box clear">
<div class="box-top"></div>
<div class="box-content">
<div class="head">
<h2>My <?php echo $INI['system']['couponname']; ?></h2>
<ul class="filter">
<li class="label">Category: </li>
<?php echo current_coupon_sub('index'); ?>
</ul>
</div>
<div class="sect">
<?php if($selector=='index'&&!$coupons){?>
<div class="notice">There is no usable <?php echo $INI['system']['couponname']; ?></div>
<?php }?>
<table id="orders-list" cellspacing="0" cellpadding="0" border="0" class="coupons-table">
<tr><th width="300">Deal Item</th><th width="100" nowrap>Voucher's Number</th><th width="60" nowrap>Voucher's Password</th><th width="100" nowrap>Valid Till</th><th width="40">Email Voucher</th></tr>
<?php if(is_array($coupons)){foreach($coupons AS $index=>$one) { ?>
<tr <?php echo $index%2?'':'class="alt"'; ?>>
<td><a class="deal-title" href="/team.php?id=<?php echo $one['team_id']; ?>" target="_blank"><?php echo $teams[$one['team_id']]['title']; ?></a></td>
<td><?php echo $two['id']; ?></td>
<td><?php echo $two['secret']; ?></td>
<td><?php echo date('Y-m-d', $two['expire_time']); ?></td>
<td>Send</td>
</tr>
<?php }}?>
<tr><td colspan="5"><?php echo $pagestring; ?></td></tr>
</table>
</div>
</div>
<div class="box-bottom"></div>
</div>
</div>
<div id="sidebar">
</div>
</div>
</div> <!-- bd end -->
</div> <!-- bdw end -->
<?php include template("footer");?>
and more (index.php):
<?php
require_once(dirname(dirname(__FILE__)) . '/app.php');
need_login();
$daytime = strtotime(date('Y-m-d'));
$condition = array(
'user_id' => $login_user_id,
'consume' => 'N',
"expire_time >= {$daytime}",
);
$count = Table::Count('coupon', $condition);
list($pagesize, $offset, $pagestring) = pagestring($count, 10);
$coupons = DB::LimitQuery('coupon', array(
'condition' => $condition,
'coupon' => 'ORDER BY create_time DESC',
'size' => $pagesize,
'offset' => $offset,
));
$team_ids = Utility::GetColumn($coupons, 'team_id');
$teams = Table::Fetch('team', $team_ids);
include template('coupon_index');
Here is the html(coupon_index.html):
<!--{include header}-->
<div id="bdw" class="bdw">
<div id="bd" class="cf">
<div id="coupons">
<div class="dashboard" id="dashboard">
<ul>${current_account('/coupon/index.php')}</ul>
</div>
<div id="content" class="coupons-box clear">
<div class="box clear">
<div class="box-top"></div>
<div class="box-content">
<div class="head">
<h2>My {$INI['system']['couponname']}</h2>
<ul class="filter">
<li class="label">Category: </li>
${current_coupon_sub('index')}
</ul>
</div>
<div class="sect">
<!--{if $selector=='index'&&!$coupons}-->
<div class="notice">There is no usable {$INI['system']['couponname']}</div>
<!--{/if}-->
<table id="orders-list" cellspacing="0" cellpadding="0" border="0" class="coupons-table">
<tr><th width="300">Deal Item</th><th width="100" nowrap>Voucher's Number</th><th width="60" nowrap>Voucher's Password</th><th width="100" nowrap>Valid Till</th><th width="40">Print Voucher</th></tr>
<!--{loop $coupons $index $one}-->
<tr ${$index%2?'':'class="alt"'}>
<td><a class="deal-title" href="/team.php?id={$one['team_id']}" target="_blank">{$teams[$one['team_id']]['title']}</a></td>
<td>{$one['id']}</td>
<td>{$one['secret']}</td>
<td>${date('Y-m-d', $one['expire_time'])}</td>
<td></td>
</tr>
<!--{/loop}-->
<tr><td colspan="5">{$pagestring}</td></tr>
</table>
</div>
</div>
<div class="box-bottom"></div>
</div>
</div>
<div id="sidebar">
</div>
</div>
</div> <!-- bd end -->
</div> <!-- bdw end -->
<!--{include footer}-->
The simplest solution to output a row per page when printing is simply to use page-break-before or page-break-after CSS properties. That said, you'll need to supress these on either the first or last tr depending on which route you choose.
e.g.:
<style>
#media print {
table tr {page-break-after:always}
}
</style>
you need to pass the database rowID of the coupon in question, or some variation thereof. I would use some hash of it, maybe the MD5 of it, along with a check on the far side that the session person is the owner of that coupon and the coupon is valid...
so your print link would be:
<td>Send</td>
in coupon_index.php i cant understand what $two refers to.
you probably need to better name and indent that piece of code, find a suitable id for the row you want to display, passing this information to the appropriate controller which will load only the relevant row.

Categories