populate html table in PHP - php

I am at the end of my project, I have all the data from my database and everything is working fine I just can not work out how to display it in a table.
I have generated a table which is the (number of projects) * (the number of people).
The data I have collected is user_id, project_id and hours.
But how do I insert '6' (hours) into user_x's row in the column of the correct project?
I can only think to make x arrays (for the number of projects) of the length for the number of users and evaluate the project code to select the correct array and then use the user id to get the correct position to place the value and simply spit out the array into the td tag
This is incredibly messy, I wonder if I'm going about it completely wrong.
If this is indeed the best way I need to recursively create arrays and write code which references variables that might not even exist. Sounds insane to me
//for the length of projects create arrays that are the length of users and fill with 0's
for ($v = 0; $v < $rows_x; $v++){
$name = "variable{$v}";
$$name = array_fill(0, $rows_u, '0');
EDIT: What I am trying to do is show the number of hours that are booked to projects between two dates. I have gotten all the data correctly but now I need the data to land into a table so you can easily see which user booked to what project.
In an excel world I could use the project number to select the Y axis and the user id to select the X axis. However I don't know the best way to do this in php.
Surely creating an array for each project the length of the users and filling with data if there is data is not the best way.

I don't know if this is what you're looking for, but I insert my values into a table in the process of retrieving them.
You can echo the values into a <td> as long as they are in your SQL SELECT statement.
<table>
<thead>
<tr>
<th>Values1</th>
<th>Values2</th>
</tr>
</thead>
<tbody>
<?php
$sql = "SELECT value1, value2
FROM tbl_Values";
if (!$res = $link->query($sql)) {
trigger_error('Error in query ' . $link->error);
} else {
while ($row = $res->fetch_assoc()) {
?>
<tr>
<td>
<?php echo $row['value1']; ?>
</td>
<td>
<?php echo $row['value2']; ?>
</td>
</tr>
<?php
}
}
?>
</tbody>
</table>
This is the way I put data into my tables, without using arrays.

Related

Grouping database entries into dynamic HTML tables

I have a database where teams will have multiple entries each with different locations. Each entry will have a team name. So for example, team1 might appear several times but each time the location will be different.
The structure of the DB is (each of these represents a column header):
team_name, first_name, last_name, location, arrival_time
My current working code creates HTML tables grouped by team name but currently only creates one row to show the first location and the time of arrival for the first location. I need this to dynamically create more rows to show all locations and arrival times for each team.
The desired result would look like this -
https://codepen.io/TheBigFolorn/pen/LqJeXr
But current result looks like this -
https://codepen.io/TheBigFolorn/pen/qgMppx
And here is an example of how the DB table might look -
https://codepen.io/TheBigFolorn/pen/daqJze
I've tried breaking up the echo and adding a second while loop before the row that I want to apply the above logic to but it seems to break everything. Any input on how I get this to work without having to use separate queries for each team would be very much appreciated. I'm new to php so please go easy on me :)
<?php
$leaders = "SELECT *, COUNT(location) FROM my_example_table GROUP BY team_name";
$result = mysqli_query($connect, $leaders) or die ("<br>** Error in database table <b>".mysqli_error($connect)."</b> **<br>$sql");
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "
<div class='red-border'>
<h2>". $row["team_name"]. "<br><small>Total locations visited: ". $row["COUNT(location)"]. "</small></h2>
</div>
<div class='data-holder'>
<table>
<tr>
<th>Location</th>
<th>Time of arrival</th>
</tr>
<tr><td>". $row["location"]. "</td> <td>". $row["arrival_time"]. "</td></tr>
</table>
</div>
";
}
} else {
echo "0 results";
}
?>
Your problem is due to the GROUP BY, as you've probably realised. This is necessary in order to get a count per team, but causes the number of rows output to be only 1 per team - that's what grouping does. Fundamentally, running an aggregate query such as a COUNT or SUM is incompatible with also outputting all of the row data at the same time. You either do one or the other.
Now, you could run two queries - one to get the counts, and one to get all the rows. But actually you don't really need to. If you just select all the rows, then the count-per-team is implicit in your data. Since you're going to need to loop through them all anyway to output them in the HTML, you might as well use that process to keep track of how many rows you've got per team as you go along, and create the "Total number of locations" headings in your HTML based on that.
Two things are key to this:
1) Making the query output the data in a useful order:
SELECT * FROM my_example_table Order By team_name, arrival_time;
2) Not immediately echoing HTML to the page as soon as you get to a table row. Instead, put HTML snippets into variables which you can populate at different times in the process (since you won't know the total locations per team until you've looped all the rows for that team), and then string them all together at a later point to get the final output:
$leaders = "SELECT * FROM my_example_table Order By team_name, arrival_time;";
$result = mysqli_query($connect, $leaders) or die ("<br>** Error in database table <b>".mysqli_error($connect)."</b> **<br>$sql");
$currentTeam = "";
$locationCount = 0;
$html = "";
$teamHtmlStart = "";
$teamHtmlEnd = "";
if ($result->num_rows > 0)
{
while($row = $result->fetch_assoc())
{
//run this bit if we've detected a new team
if ($currentTeam != $row["team_name"]) {
//finalise the previous team's html and append it to the main output
if ($currentTeam != "") $html .= $teamHtmlStart.$locationCount.$teamHtmlEnd."</table></div>";
//reset all the team-specific variables
$currentTeam = $row["team_name"];
$teamHtmlStart = "<div class='red-border'><h2>".$currentTeam."<br><small>Total locations visited: ";
$locationCount = 0;
$teamHtmlEnd = "</small></h2>
</div>
<div class='data-holder'>
<table>
<tr>
<th>Location</th>
<th>Time of arrival</th>
</tr>";
}
$teamHtmlEnd .= "<tr><td>". $row["location"]. "</td> <td>". $row["arrival_time"]. "</td></tr>";
$locationCount++;
}
//for the final team (since the loop won't go back to the start):
$html .= $teamHtmlStart.$locationCount.$teamHtmlEnd."</table></div>";
echo $html;
}
else {
echo "0 results";
}
Here's a runnable demo (using some static data in place of the SQL query): http://sandbox.onlinephpfunctions.com/code/2f52c1d7ec242f674eaca5619cc7b9325295c0d4

Row within a row with JSON

I have a webpage where it shows the lists of Projects and the monitoring of its progress/finances for every quarter. As shown below:
As you can see, my table is comprises of Project Name and a lists of sub-title's underneath it. And a series of columns per each quarter. Thru PHP I was able to populate the list of sub-titles under the Project Name, which also being fetched from the server side. Here's the code:
$sql = mysqli_query($con," My SELECT Statement ");
$i=0;
while($row = mysqli_fetch_assoc($sql)){
$ptitle = $row['Title'];
$iname = $row['Item'];
if($i%1)
{
?>
<?php } else { ?>
<tr>
<?php } ?>
<td width="25%"><?php echo $ptitle; ?></td>
<td></td>
</tr>
<tr>
<td><?php echo "<ul style='list-style-type: none;'><li>".nl2br($iname)."</li></ul>"; ?></td>
<td contenteditable="true" name="v1"></td>
Note: ptitle = ProjectName and iname = Semi-title underneath the Project's name.
Now, as you can see, the Project Name column literally "conquer" a single row on the left. Yet, the rows under the column of each quarter, should have its own separately, and must be parallel to the every sub-title underneath the Project Name. (Please refer to the image above for this) the only problem am encountering is... how can I make an editable row from inside a row, without affecting mysqli result? coz basically my table right now is kinda look like this:
Anyone who's more experience on this? I need your help.
PS: ...and oh! You might be wondering why do I include JSON in the title? It is because, I originally use JSON for editing those table rows before I even use mysqli_fetch_array. But when I include the results of the array inside the <table> tag, everything's changed and JSON is no longer working. So as of now, I am force to do it manually, meaning typing each <td contenteditable=true> in all of those rows. Yet, its not the desired output since I need another row within an existing row. Ideas? Anyone?
Figure Two:
Figure Three:
Count the number of lines in $iname, and then use a loop to create that many rows of contenteditable cells. You can also use this in the rowspan attribute of the <td> containing the title and subtitles.
$rows = substr_count($iname, "\n") + 1;
for ($i = 0; $i < $rows; $i++) {
echo "<tr>";
if ($i == 0) { ?>
<td rowspan='<?php echo $rows;?>' width='25%'><?php echo $ptitle . "<br>" . nl2br($iname);?></td>
<?php }
?>
<td contenteditable="true" name="v1"></td><td contenteditable="true" name="v2"></td>...
</tr>
<?php }
DEMO

PHP, looping through query results in SQL

I'm currently having trouble trying to create a loop for my desired outcome.
I'm currently creating a student record card which stores numerous data of different students (fake students).
I have created a query which returns the relevant data I need (see picture one, phpmyadmin)
SELECT mods.mid, mtitle, credits, enrl.ayr
FROM stud, smod, mods, enrl
WHERE stud.sid = '154279' AND stud.sid = smod.sid
AND smod.mid = mods.mid AND stud.sid = enrl.sid
ORDER BY `enrl`.`ayr` DESC
As you can see by the results, there are attributes:
mid
mtitle
credits
ayr
I have ordered by ayr in decending order. I am trying to make a loop that will run through the return on this query and print out each row until the end of whatever the current year is. Almost grouping all rows with the same year e.g. '2001/02' into a sub table which I can then name and print.
As you can see by my second picture of the student records page, I need to be able to print all records for the one year, then create a new header for the next existing year and print all containing rows for that.
{EDIT}
PHP Code:
$query = "SELECT mods.mid, mtitle, credits, enrl.ayr
FROM stud, smod, mods, enrl
WHERE stud.sid = '154279' AND stud.sid = smod.sid AND smod.mid = mods.mid AND stud.sid = enrl.sid
ORDER BY enrl.ayr DESC
";
$scap = '';
$curYear = $row['ayr'];
if($result = $link->query($query)) {
while ($row = $result->fetch_assoc() && $row['ayr'] == $curYear) {
$scap .= "<table id=\"test\" style=\"width:100%\">
<tr>
<td> " . $row['mid'] . " </td> <td> " . $row['mtitle'] . "</td> <td> " . $row['credits'] . " <td> " . $row['ayr'] . "</td>
</tr>
</table>";
}$result->free();
}
Thanks in advance.
Let's say you commit to one query max for the whole page. Like I said in comments
I would have a variable, call it $curYear. Start it out as some junk
string. In your loop, if the cur year thing is different than
$curYear, create a new segment in your output but regardless update
$curYear variable
That was not meant to interfere with your existing source code (that much). It is just a sentinel to alert you to a year change (year/term whatever).
So it starts as some junk value, like "797fsdf*"
Now inside your while, remember, you have ALL the years coming in from that result set for all years.
Do what I said in that pink block above comparing that variable $curYear to
$row['ayr']
When those two values are different, time to do whatever HTML treatment you want (creating a new html table, a new div, who cares). Let's call this the separation thing.
Regardless, after you output the row, make sure you have set $curYear to $row['ayr']. Why is that important? Because the next loop you want to know if you need to do the separation thing.
The tricky part is if you are doing html tables, you have to close out the previous table (prior year) if you are not on your first year

Retrieving and inserting multiple entries in MySQL/PHP

I'm trying to create a form that retrieves data from a database and then allows me to add data to one column for multiple entries.
Every entry has an ID, a lot of other fields, and a category. I am trying to add these categories for every ID in the database using one form.
I came up with the solution below, but (of course)this only inserts the LAST entry in the form, because the variable ID is changed with every new row.
The form I have now shows me what I want to see, but it does not save it the way I need it to.
The question is, (how) can I make a form that has all entries in the database with a dropdown menu next to it,
lets me select the right category from the dropdown, and save it to the database?
The form:
$result = mysqli_query($con,"SELECT * FROM aw");
while($row = mysqli_fetch_array($result))
{
echo '<tr><td><input type="hidden" name="ID" value="'.$row[ID].'."> '.$row[ID].'</td><td>';
echo '
<select name="cat" onchange="this.form.submit()">
<option value="C1">category1</option>
<option value="C2"">category2</option>
</select></td></tr>
';
}
?>
<tr><td><input type="submit" title="SAVE" ></td></tr>
</form>
The insert.php
$sql="REPLACE INTO aw (ID,cat)
VALUES
('$_POST[ID]','$_POST[cat]')";
if (!mysqli_query($con,$sql))
{
die('Error: ' . mysqli_error($con));
}
mysqli_close($con);
?>
I changed my code according to Tom's answer and I now have the following:
This does print the values like they should be, but it still saves only the last entry into the database. I'm sure I must be missing something here..
$name = $_POST['ID'];
$category = $_POST['cat'];
foreach( $name as $key => $n ) {
$sql="REPLACE INTO aw (ID,cat)
VALUES
('$n','$category[$key]')";
print "The id is ".$n.", category is ".$category[$key]."<br>";
}
First of all, use PDO::Mysql, the SQL functions you are using are a bit deprecated and do not focus much on security. At the moment your code is vulnerable to SQL injections and your output is sensitive to XSS attacks (always sanitize output).
I was wrong, MySQL is deprecated but MySQLi is not! I do prefer using PDO::Mysql because of the range of databases it supports (MySQLi only supports a MySQL database, PDO::Mysql supports many more)
Now to your original question, you can create a sort of array. By making name="ID" to name="ID[]" and name="cat" to name="cat[]".
Now you can do
$name = $_POST['ID'];
$category = $_POST['cat'];
foreach( $name as $key => $n ) {
print "The id is ".$n.", category is ".$category[$key];
}
The problem is your using the name elements regardless of how many rows..
So name="ID" & name="cat" needs to change on each row or have an array type
you could use something like name="ID[]" as this would append/ create an array to $_POST['ID']... but you still would want to change your SQL query to handle each of these.
EDIT
If i understand, you want to be able to identify a row from the table so you can use that in the database?? One way todo this is when creating the table.. Give the TR a id/name attribute that is the row id from the database.
Then can simply know by checking that if your using the select menu from row #4, you check the id/name attribute of the current row and you have your database id.
<tr id='my_row_1'>
<td class='colName'>John</td>
<td class='colPhone'>1111</td>
<td class='colOther'>....</td>
</tr>
<tr id='my_row_2'>
<td class='colName'>Bill</td>
<td class='colPhone'>2222</td>
<td class='colOther'>....</td>
</tr>
<tr id='my_row_3'>
<td class='colName'>Roger</td>
<td class='colPhone'>3333</td>
<td class='colOther'>....</td>
</tr>
With something like the above, Say i had a button in on of the columns... When i click on that button.. all i have todo is find the parent TR and get its id value.... Then explode it by "_" and get the last piece to have the id..
So your PHP would generate the id easily... Also, using a form would not be the best case here.. Using multiple forms within a table is... wasteful... sort of ..
I would suggest more so, having a button that simple calls a js function which will then post/ajax/jquery what you need from that row.
--- Trying to understand exactly what you need??

Generate html table with variable rows and cells

I am trying to generate a table that takes data from a mysql database. There are 8 columns but the number of rows is variable depending on the amount of info from the database. The problem I'm running into is that I have two things that are variable and I don't know how to use two while loops (or if that's the right choice).
The code below can generate a table with 8 columns and a variable amount of rows but I don't know how to replace thing with sequential integers. I would like each cell to have just one integer in it sequentially like a while loop until the numbers = $end.
CODE:
<?php
$end=82; //will get all this data from a dabase
$rows=ceil($end/8);
$x=0;
$start=0;
?>
<table>
<?php
While ($x<=$rows){
echo"
<tr>
<td>
thing
</td>
<td>
thing
</td>
<td>
thing
</td>
<td>
thing
</td>
<td>
thing
</td>
<td>
thing
</td>
<td>
thing
</td>
<td>
thing
</td>
</tr>
";
$x++;
}
?>
</table>
This will output eight numbers per row starting at 1 and going to $end. I am unsure of what $maxprobs is here.
<?php
$end=82; //will get all this data from a dabase
$rows=ceil($end/8);
$x=0;
$start=0;
?>
<table>
<?php
while($x<=$rows) {
echo "<tr>";
for ($y = 0; $y < 8; $y++, $start++) {
if ($start <= $end) echo "<td>$start</td>";
}
echo "</tr>";
$x++;
}
?>
</table>
I have to ask - if you're pulling rows from a MySQL database, and you want your table to have a dynamic number of rows depending on the data, is there any specific reason you're not doing it the regular way, with a while loop and a mysql_fetch function?
$data = mysql_query("SELECT row1, row2, ... , row8 FROM table WHERE ...); // Sample query, edited for brevity.
echo "<table>";
while ($result = mysql_fetch_object($data))
(
echo "<tr>";
echo "<td>".$data->row1."</td>;
echo "<td>".$data->row2."</td>;
... // Edited for brevity. Include as many columns as you queried.
echo "<td>".$data->row8."</td>;
echo "</tr>";
}
echo "<table>";
Unless you have a really specific reason not to do it this way, I'd use this method. It's flexible and it will print as many rows as your query returns (meaning that you only need to change your query, not your code).
Additional information on mysql_fetch_object and mysql_query can be found here and here, respectively.
Take a look at the php website, nearly all their entries have examples, the database stuff shows a while loop, this is the best way to do it..
write the table opening tag, plus any headers..
while able to get more database data, get it, and do
display the table row open tag
display the row, by looping through the fields, and outputting them between cell tags
dispaly the end of row tag
now you've finished with your data, write the end of the table
There are a lot of examples about.
for the looping through the field, thats why they invented a "foreach" , eg wether you have 0, or 10000, you can go through each one, even if its not consecutive, so for each "fruit" in apple, pear, bannana..

Categories