looping issue with array - php

<?php
?>
<html>
<head>
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>
</th>
<?php
for($i = 1; $i <=31;$i++){
echo '<th>'.$i.'</th>';
}
?>
</tr>
</thead>
<tbody>
<td>
Item A
</td>
<?php
$qty_n_day = '1/2,3/6';
$qty_day = explode(',', $qty_n_day);
foreach ($qty_day as $qd) {
list($qty,$day) = explode('/', $qd);
for($i = 1; $i <=31;$i++){
if($day == $i)
echo '<td>'.$qty.'</td>';
else
echo '<td>-</td>';
}
}
?>
</tbody>
</table>
</body>
</html>
Output result
My expected result
The 31 column indicate as days.
I stored quantity and days together, and then extract it after into
a list.
After that, i want to compare it with day column and show qty value
for the column.
How can i do that? Is my logic wrong?

Try this way, creating an associative array first with the day and value:
<?php
$qty_n_day = '1/2,3/6';
$qty_day = explode(',', $qty_n_day);
$days = [];
foreach ($qty_day as $day) {
if (($res = explode('/', $day))) {
$days[$res[1]] = $res[0];
}
}
/*
the array should stay like this
$days = [
2 => 1,
6 => 3
];
*/
for($i = 1; $i<=31;$i++){
if (isset($days[$i])) { // if the key exists set the value
echo '<td>' . $days[$i] . '</td>';
} else {
echo '<td>-</td>';
}
}
?>

You have to change the order of your loops:
Your foreach loop loops through the quantities and contains the for loop, that loops through the days. This leads to the behavior, that the for loop runs completely through for each quantity, therefore echoing 31 days.
This means that for 2 quantities 62 days are printed.
You need to flip the loops and add a conditional output to them:
for ($i = 1; $i <= 31; $i++) {
$quantity = '-';
foreach ($qty_day as $qd) {
list($qty,$day) = explode('/', $qd);
if ($day == $i) {
$quantity = $qty;
break;
}
}
echo '<td>' . $quantity . '</td>';
}

The problem arises from the fact that you are performing two iterations, the first one processing 2 cycles and the second one processing 31 cycles... for a total of 62 elements being generated.
I propose you a much more compact solution, that builds up the final array first and then simply prints it:
<?php
$arr = array_fill(1, 31, "-");
$qty_n_day = '1/2,3/6';
$qty_day = explode(',', $qty_n_day);
foreach ($qty_day as $qd)
{
list($qty,$day) = explode('/', $qd);
$arr[$day] = $qty;
}
for ($i = 1; $i <= 31; ++$i)
{
echo '<td>'.$arr[$i].'</td>';
}
?>

Related

How to display stars (1 to 5) from the value present in database

I have developed a page that shows the details of user achievements. I have a table that holds the level of the user.
Users( id, username, password, sum_score, level)
Based on the value present in level(i.e., from 0 to 5) I would like to like to display stars in the user page.
I tried something like :
$stars = "";
$s = 1;
while ($s<=$lvl['level']) {
$stars.="★";
$s++;
}
echo "$stars";
The above code produces star based on the level.(i.e., if the level is 1 it shows one star on the page). But I want to display 5 stars and fill the stars based on the level in the table. Can Someone help me out.
Instead of using while, you can use a simple for loop in this case.
Assuming $lvl['level'] is properly getting database's data (i.e., 5), you can loop until 5 compare it with $lvl['level'] value, and display the star based on the if statement's result. Like so:
$stars = "";
for ($i = 1; $i <= 5; $i++) {
$i <= $lvl['level'] ? $stars .= "★" : $stars .= "☆";
}
echo $stars;
str_repeat is one option.
// stub for your record
$lvl = [
'level' => 4
];
// render
$maxStars = 5;
$stars = (int)$lvl['level'];
$output =
str_repeat('★', $stars) .
str_repeat('☆', $maxStars - $stars) .
' stars';
echo $output;
Output: https://3v4l.org/UFprQ
If you add some classes and holders and add one if statement in the loop
<?php
$lvl = ["id" => 1, "level" => 4];
$stars = "";
for ($i = 1; $i < 6; $i++) {
$stars .= '<span' . (($i <= $lvl["level"]) ? ' class="fill"' : '') . '>';
$stars .='★</span>';
}
echo '<div class="star"><div class="rating">' . $stars . '</div></div>';
Here is the snippet, HTML code is the output of the PHP:
.star {
width: 200px;
position: relative;
color: #bdbdbd;
}
.rating span {
font-size: 30px;
margin-left: -4px;
white-space: nowrap;
overflow: hidden;
}
.rating span:before {
content: "\2605";
position: absolute;
color: gray;
}
.rating span.fill:before {
content: "\2605";
position: absolute;
color: gold;
}
<!-- this will be the output generated from php code used above !-->
<div class="star">
<div class="rating"><span class="fill">★</span><span class="fill">★</span><span class="fill">★</span><span>★</span><span>★</span></div>
</div>

Filling table in a specific way with sql data using loops

I want to put data from the following database table in a html table in a specific way.
Below is my php code:
echo "<table style='border:2px solid black;width:100%;'>";
foreach ($results as $key => $value) {
for ($i = 1; $i < 4; $i++) { // 3 + 1 = 4 (itération sur la valeur de $value['ligne'])
if ($i == $value['ligne']) {
echo "<tr>";
for ($j = 1; $j < 4; $j++) { // itération sur la valeur de $value['colonne']
//if ($j == $value['colonne'] ) {
echo "<td style='padding:1em;border:1px solid black;'>".$value['contenu']."</td>";
//}
}
echo "</tr>";
}
}
}
echo "</table>";
And here is the output that i'm having:
What I want to achieve is having "colonne1" only in the column 1 of the table; "colonne2" only in column 2, etc. In the same way, "Ligne1" should appear only in row 1; "Ligne2" in row 2, which is what i've been able to do. Any idea? Thanks, in advance.
You can use a two dimensional array to achieve the object seeing you’re looking for.
First, build a data structure from the database results.
// assuming you’ve retrieved table into $results
$table =array();
foreach($results as $v) {
$row = $v[‘ligne’];
$col = $v[‘colonne’];
$content = $v[‘contenue’];
$table[$row][$col] = $content;
}
// build html table
?>
Then you can print it out in the view:
<table>
<?php foreach($table as $row_array): ?>
<tr>
<?php foreach($row_array as $col): ?>
<td><?= $col ?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</table>

How do you add all that is left in the table in php after filtering it using ajax?

I am trying to filter out the dates then add the amounts that are left.
Below is the code for the table which consists of amounts and date. There is an input which would ask for the date then filter them out.
<?php $total = 0; ?>
<table id="dateTable">
<tr class="header">
<th style="width:50%;">Amount</th>
<th style="width:50%;">Date</th>
</tr>
#if ( count( $data['getBookValue'] ) )
#foreach( $data['getBookValue'] as $book_value )
#if ($book_value['status'] == 1)
<tr>
<td>
<?php $total += $book_value['amount']; ?>
<?php echo $book_value['amount']; ?>
</td>
<td>
<?php echo $book_value['created_at']->format('m/d/Y'); ?>
</td>
</tr>
#endif
#endforeach
#endif
</table>
This is the script
function filterFunction() {
var input, filter, table, tr, td, i;
input = document.getElementById("event_date_range");
filter = input.value.toUpperCase();
table = document.getElementById("dateTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[1];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
The easiest way is probably to have a running total as you go.
Start a total variable at zero, and as you test each row, if the display is set to "", add the value to the total. Something like this:
totalViewable = 0;
for (i = 0; i < tr.length; i++) {
tds = tr[i].getElementsByTagName("td");
td = tds[1];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
totalViewable += parseFloat(tds[0]);
} else {
tr[i].style.display = "none";
}
}
}

Populating 2D Array in PHP

How would I input the same randomized values 27 times into that array $data?
It outputs a correctly formatted table with one row of randomized values, now just need to redo these values 27 times.
The array is two dimensional would that makes things harder?
Any and all help is appreciated very much I am just a beginner.
<html>
<STYLE type="text/css">
td{
border-left: 1px solid #f09d09;
}
th{
border: 1px solid #f09d09;
}
</STYLE>
<body>
<table>
<tr>
<th>Number</th>
<th>Student Number</th>
<th>Coursework Mark</th>
<th>Exam Mark</th>
<th>Module Mark</th>
<th>Module Result</th>
<th>Comments</th>
</tr>
<?php
$examPassmark = 40; //Hardcoded exam pass mark
$courseworkPassmark = 40; // Hardcoded coursework passmark
$n = rand(1,27);
$sn = "B00" . rand(200000,599999); //randomised student number with the prefix B00 e.g B00-299999
$cwm = rand(25,100); //randomised coursework mark
$em = rand(25,100); // randomised exam mark
$mm = round(((($cwm / 200) * 20) + (($em / 200) * 80) * 2)) ; //exam weighting is cw/e = 20/80
$mr = 'Fail';
$stack = array("");
if($em > $examPassmark && $cwm > $courseworkPassmark) //This if statement states that ONLY if both Coursework and the exam are passed will a student pass the module
{
$mr = 'Pass';
}else{
$mr = 'Fail';
}
if($cwm < $courseworkPassmark) //Checks to see if the student passed coursework
{
$com = 'Resit CourseWork';
}
else if($em < $examPassmark) // Checks to see if the student passed the exam
{
$com = 'Resit Exam';
}else{
$com = 'None'; //outputted if both are passed
}
for($i = 0; $i <= 27; $i++)
{
$data = array( array($n, $sn, $cwm, $em, $mm, $mr, $com) //Here we have an two dimensional array that will be filled with the values created above
);
$data[$i] .= $stack;
}
for ($row = 0; $row < 27; $row++) //rows (I use 8 to give each column padding so it isnt squeezed together)
{
for ($col = 0; $col < 7; $col++) //columns output to the number of entries in the array $data
{
echo "<td>".$data[$row][$col]."</td>"; //within each column print out the value held within $data
}
}
echo '</table>'; //end the table
?>
</body>
You were almost there.. with a few modifications to your code, you can get the data correctly into the array, and print it... I'm going to add comments to the modified code, so you can see what I changed, and why.
for($i = 0; $i <= 27; $i++)
{
$data[] = array($n, $sn, $cwm, $em, $mm, $mr, $com, $stack);
// There is no need to use $i in the array assignment here, the array inserts already start at zero
// On top of that, there is no need to have a 3 dimensional array, if you're trying to
// Get the values to correctly print into a table.
// Lastly, you can simply add $stack to the array, rather than having to add it on with another line.
}
for ($row = 0; $row < 27; $row++)
{
echo "<tr>"; // This needs to exist, of course, in order to separate the rows
for ($col = 0; $col < 7; $col++) //columns output to the number of entries in the array $data
{
echo "<td>".$data[$row][$col]."</td>";
// Otherwise, your code here is fine.
}
echo "</tr>"; // see above
}

Mysterious empty database entry

In the comment leaving system on part of my website there is a weird blank entry that always remains above the latest real entry. I've looked in the database directly and there isn't a blank entry. Yet, on the top of all my comments, there is always an empty box that is formatted the same way as the rest of the comments. Where is this coming from and how do I get rid of it? Here is the php:
$query = "SELECT * FROM catharsis";
$result = mysql_query($query);
$num = mysql_numrows($result);
mysql_close();
echo "<h4><center>Let it out.</center></h4>";
echo '<ul class="comments">';
for ($i = 0; $i < $num; $i++) {
$name = mysql_result($result,$num - $i,"message");
echo "<li>$name</li>";
echo '<br>';
}
echo '</ul>';
relevant css:
ul.comments {
list-style-type: none;
position: relative;
right: 2.5em;
}
ul.comments li {
list-style-type: none;
background-color: c0dbff;
border-style: solid;
border-width: 1px;
border-color: black;
padding: .4em;
}
$query = 'SELECT message FROM catharsis ORDER BY id DESC';
$result = mysql_query($query);
mysql_close();
echo '<h4><center>Let it out.</center></h4>';
echo '<ul class="comments">';
while($t = mysql_fetch_array($result)){
echo '<li>'.$t[0].'</li><br>';
}
echo '</ul>';
I believe it comes from the first time this line is executed:
$name = mysql_result($result,$num - $i,"message");
Since your results are indexed from 0 to $num-1 you won't have an entry with the index $num-0.
Change that line to read
$name = mysql_result($result,$num - $i -1,"message");
or start $i at 1 and let it run up to <= $num
Can you confirm that if you echo $num it is zero?
You don't want to be printing a ul when you don't have any li entries anyway so you'd want something like this:
if ($num > 0)
{
echo '<ul class="comments">';
for ($i = 0; $i < $num; $i++) {
$name = mysql_result($result,$num - $i,"message");
echo "<li>$name</li>";
echo '<br>';
}
echo '</ul>';
}

Categories