Display php nested array results continuously in two column table - php

I have a nested array grouping three other arrays: $online, $busy and $offline, in order to display results in this exactly order.
$conteudo = array($online, $ocupado, $offline);
The desired result would be a table in two columns to display results in continuous flow like this:
online1 | online2
online3 | busy1
busy2 | offline1
offline2| offline3
offline4|
I've been trying lots of foreach loops and playing around changing the html tags, but the closest I can arrive of the desired result is this:
<table width='100%' cellpadding='5' border="1">
<?php
$i = 1; //contador de colunas
$max_colunas = 2; // numero de colunas
foreach ($conteudo as $row) {
echo "<tr>";
foreach ($row as $col) {
foreach ($col as $cell) {
if ($i == 1) {
echo "<td>" . $cell . "</td>";
} elseif ($i == $max_colunas){
echo "<td>" . $cell . "</td></tr>";
$i = 0;
} else {
echo "<td>" . $cell . "</td>";
}
$i++;
}
}
echo "</tr>";
}
This code will output a table like this:
onine1 | online2 |online3
busy1 | busy2 |
offline1|offline2 |offline3|offline4
I can't find out why it ignores completely $max_colunas, seems like it prints all the elements inside the array in row.
If I remove lines:
echo "<tr>";
echo "</tr>";
from beginning and end of foreach it will output all in a row like this:
onine1 | online2 |online3 | busy1 | busy2 |offline1|offline2 |offline3|offline4
Any suggestions to get the desired output format will be so appreciated.
Edited on 17/01:
This is how I'm getting the arrays from:
//group people
$online = array(); //group online
$ocupado = array(); //group ocupado
$offline = array(); //group offline
//select people to group
$atendentes = mysql_query("SELECT nome FROM atendentes ORDER BY nome") or die(mysql_error());
$atendentedb = array();
//put selected people in array
while ($row = mysql_fetch_assoc($atendentes)) {
$atendentedb[] = array('nome' => $row["nome"], 'online' => false);
}
//take people online now and check in selected people
$names = modWhosonlineCustom::getOnlineUserNames();
foreach ($names as $name):
//foreach ($atendentedb as $atendente):
for($i = 0; $i < count($atendentedb); $i++):
$att = strtolower($name->username);
if ($atendentedb[$i]['nome'] == $att):
$atendentedb[$i]['online'] = true;
break;
endif;
endfor;
endforeach;
//check each selected people
foreach ($atendentedb as $atendente) :
//save temporary data
$online_ = $atendente['online'];
$nome_ = $atendente['nome'];
//if selected people online
if ($online_) :
//take status to show
$status = mysql_query("SELECT status FROM atendentes WHERE nome = '$nome_' LIMIT 1") or die(mysql_error());
while ($row = mysql_fetch_assoc($status)):
$statusdb = $row["status"];
endwhile;
//verify and save deppending on status
switch ($statusdb):
//if online
case "disponivel":
$descricao = mysql_query("SELECT hp_online FROM atendentes WHERE nome = '$nome_' LIMIT 1") or die(mysql_error());
while ($row = mysql_fetch_assoc($descricao)):
$online[] = array('info'=>$row['hp_online']);
endwhile;
break;
//if busy
case "ocupado":
$descricao = mysql_query("SELECT hp_busy FROM atendentes WHERE nome = '$nome_' LIMIT 1") or die(mysql_error());
while ($row = mysql_fetch_assoc($descricao)):
$ocupado[] = array('info'=>$row['hp_busy']);
endwhile;
break;
endswitch;
//if offline
else:
$descricao = mysql_query("SELECT hp_offline, horario FROM atendentes WHERE nome = '$nome_' LIMIT 1") or die(mysql_error());
while ($row = mysql_fetch_assoc($descricao)):
$offline[] = array('info'=>$row['hp_offline'], 'horario'=>$row['horario']);
endwhile;
endif;
endforeach;
EDITED
So after following help instructions from DaveRandom I got to this code, which is really a drop away from the right format, except for the "mysterious" behaviour with results coming from array $offline, that are displaying all in "block" (all cells in a row, or all cells in a column) while the other arrays are displaying perfectly(??).
//group people
$online = $ocupado = $offline = array();
//select people to group
$query = "SELECT nome, status, hp_online, hp_busy, hp_offline, horario
FROM atendentes
ORDER BY nome";
$atendentes = mysql_query($query) or die(mysql_error());
$atendentedb = array();
// put selected people in array
while ($row = mysql_fetch_assoc($atendentes)) {
$atendentedb[strtolower($row['nome'])] = array_merge($row, array('online' => FALSE));
}
//take people online now and check in selected people
$names = modWhosonlineCustom::getOnlineUserNames();
foreach ($names as $name) {
$uname = strtolower($name->username);
if (isset($atendentedb[$uname])) $atendentedb[$uname]['online'] = TRUE;
}
//check each selected people
foreach ($atendentedb as $name => $atendente) {
//if selected people online
if ($atendente['online']) {
//verify and save deppending on status
switch ($atendente['status']) {
//if online
case 'disponivel':
$atendentedb[$name]['info'] = $online[] = $atendente['hp_online'];
break;
//if busy
case 'ocupado':
$atendentedb[$name]['info'] = $ocupado[] = $atendente['hp_busy'];
break;
}
//if offline
} else {
$atendentedb[$name]['info'] = $offline[] = $atendente['hp_offline'];
$atendentedb[$name]['info'] = $offline[] = $atendente['horario'];
}
}
//*******Display Results
$conteudo = array_merge($online, $ocupado, $offline);
$max_colunas = 2; // numero de colunas
// Start the table
echo '<table width="100%" cellpadding="5" border="1">'."\n";
// Loop all the objects
for ($i = 0, $j = 0; isset($conteudo[$i]); $i++) {
if ($j == 0) {
// Output the beginning of a row
echo " <tr>\n";
}
// Always output a data cell
echo " <td>$conteudo[$i]</td>\n";
if (++$j >= $max_colunas) {
// Output the end of a row and reset the cell counter
echo " </tr>\n";
$j = 0;
}
}
if ($j) {
// We may end up with an incomplete row at the end, so pad it with empty cells
// and close the row
while ($j++ < $max_colunas) {
echo " <td></td>\n";
}
echo " </tr>\n";
}
// Close the table
echo "</table>";

I would say that the first thing to do here is to "flatten" the array - having the multiple dimensions makes this a lot more complicated than it needs to be. So rather than creating $conteudo like this:
$conteudo = array($online, $ocupado, $offline);
...do this instead:
$conteudo = array_merge($online, $ocupado, $offline);
Then you can do this:
$max_colunas = 2; // numero de colunas
// Start the table
echo '<table width="100%" cellpadding="5" border="1">'."\n";
// Loop all the objects
for ($i = 0, $j = 0; isset($conteudo[$i]); $i++) {
if ($j == 0) {
// Output the beginning of a row
echo " <tr>\n";
}
// Always output a data cell
echo " <td>$conteudo[$i]</td>\n";
if (++$j >= $max_colunas) {
// Output the end of a row and reset the cell counter
echo " </tr>\n";
$j = 0;
}
}
if ($j) {
// We may end up with an incomplete row at the end, so pad it with empty cells
// and close the row
while ($j++ < $max_colunas) {
echo " <td></td>\n";
}
echo " </tr>\n";
}
// Close the table
echo "</table>";
See it working
EDIT
Try this code for generating your arrays. Note that the structure of your output arrays has been altered to fit my code sample above - if you use this data anywhere else in you script, you will need to modify that code as well. I have modified this so that there is only one database query, which would seem to be all that is required. I have also modified it so that the $atendentedb holds all the user data, including the status and info keys, and all rows contain a horario key.
Because of the fact that your input arrays originally contained more data than the ones created by this code will, the code may need further modification - but try this out and see how you get on.
//group people
$online = $ocupado = $offline = array();
//select people to group
$query = "SELECT nome, status, hp_online, hp_busy, hp_offline, horario
FROM atendentes
ORDER BY nome";
$atendentes = mysql_query($query) or die(mysql_error());
$atendentedb = array();
// put selected people in array
while ($row = mysql_fetch_assoc($atendentes)) {
$atendentedb[strtolower($row['nome'])] = array_merge($row, array('online' => FALSE));
}
//take people online now and check in selected people
$names = modWhosonlineCustom::getOnlineUserNames();
foreach ($names as $name) {
$uname = strtolower($name->username);
if (isset($atendentedb[$uname])) $atendentedb[$uname]['online'] = TRUE;
}
//check each selected people
foreach ($atendentedb as $name => $atendente) {
//if selected people online
if ($atendente['online']) {
//verify and save deppending on status
switch ($atendente['status']) {
//if online
case 'disponivel':
$atendentedb[$name]['info'] = $online[] = $atendente['hp_online'];
break;
//if busy
case 'ocupado':
$atendentedb[$name]['info'] = $ocupado[] = $atendente['hp_busy'];
break;
}
//if offline
} else {
$atendentedb[$name]['info'] = $offline[] = $atendente['hp_offline'].' '.$atendente['horario'];
}
}

I think you should update counter inside
foreach ($col as $cell) { } so it will count elements of the inner arrays and also move decalration of <tr> there.
if (!is_int($i/2)) { print '<tr><td>' }

Related

How to get id while in a loop in php

Wanted to get 2 values id and name but im confuse how get it, i wanted to show the id in the link. heres the sample code.
echo "<table width=\"100%\" border=\"1\" cellpadding=\"5\" cellspacing=\"2\" bordercolor=\"#FFFFFF\">";
$count = 1;
$id=$_GET['id'];
$col1 = $col2 = array();
$rowcount = round(mysqli_num_rows($nquery) / 2);
while($crow = mysqli_fetch_assoc($nquery)) {
if($count > $rowcount) $col2[] = $crow['title'];
else $col1[] = $crow['title'];
$count++;
}
$counter = 0; // Arrays start with 0
foreach($col1 as $crow) { // $col1 will always be >= $col2
$row2 = (isset($col2[$counter])) ? $col2[$counter] : "";
echo "<tr><td><a href='index.php?page=".$id."'>" . $crow . "</td><td>" . $row2 . "</td></tr>";
$counter++;
}
echo "</table>";
?>`
id wont show up on the link. Hope someone can help. Thanks
You're trying to get $id values from the query string (that's what the $_GET superglobal is) and not from the database.
If both elements (ID and name) are coming from the same database query, you may try something like this:
$crow = mysqli_fetch_assoc($nquery);
foreach ($crow as $row)
{
echo $row['id'].' is the ID and '.$row['title'].' is the title';
}
if you remain within the foreach loop, you can use $row['id'] and $row['title'] to build the table element and link you're trying to obtain.

How to get a html-table from an sql-query with various numbers of columns?

I have a html-form to read out data from an SQL-database. The number of selections is completely free, which means that there are no obligatory fields.
I would like to show the results that meet all selected criteria in a html-table. Here is my code:
<?php
include("../files/zugriff.inc.php");
if (isset($_POST["submit"])) {
$sent = $_POST['sent'];
$datenWerte = array();
$fruitname = $_POST["fruitname"];
$fruitgroup = $_POST["fruitgroup"];
$vegetablegroup = $_POST["vegetablegroup"];
$country = $_POST["country"];
$season = $_POST["season"];
$diameter = $_POST["diameter"];
$color = $_POST["color"];
if(!empty($fruitgroup)) {
$datenWerte['fruitgroup'] = $fruitgroup;
}
if(!empty($vegetablegroup)) {
$datenWerte['vegetablegroup'] = $vegetablegroup;
}
if(!empty($country)) {
$datenWerte['country'] = $country;
}
if(!empty($season)) {
$datenWerte['season'] = $season;
}
if(!empty($diameter)) {
$datenWerte['diameter'] = $diameter;
}
if(!empty($color)) {
$datenWerte['color '] = $color;
}
foreach ($datenWerte as $key => $value) {
$spalten[] = $key;
$werte[] = "'$value'";
}
echo "<b>Results:</b><br><br>";
$sql = "SELECT * FROM fruitdatabase WHERE (" . implode(", ",
$spalten) . ") = (" . implode(", ", $werte) . ")";
$result = mysqli_query($db, $sql);
$data = array();
while($row = $result->fetch_object()){
$data[] = $row;
}
// Numeric array with data that will be displayed in HTML table
$aray = $data;
$nr_elm = count($aray); // gets number of elements in $aray
// Create the beginning of HTML table, and of the first row
$html_table = '<table border="1 cellspacing="0" cellpadding="2""><tr>';
$nr_col = count($spalten); // Sets the number of columns
// If the array has elements
if ($nr_elm > 0) {
// Traverse the array with FOR
for($i=0; $i<$nr_elm; $i++) {
$html_table .= '<td>' .$aray[$i]. '</td>'; // adds the value in
column in table
// If the number of columns is completed for a row (rest of
division of ($i + 1) to $nr_col is 0)
// Closes the current row, and begins another row
$col_to_add = ($i+1) % $nr_col;
if($col_to_add == 0) { $html_table .= '</tr><tr>'; }
}
// Adds empty column if the current row is not completed
if($col_to_add != 0) $html_table .= '<td colspan="'. ($nr_col -
$col_to_add). '"> </td>';
}
$html_table .= '</tr></table>'; // ends the last row, and the table
// Delete posible empty row (<tr></tr>) which cand be created after last
column
$html_table = str_replace('<tr></tr>', '', $html_table);
echo $html_table; // display the HTML table
}
mysqli_close($db);
?>
Unfortunately, it´s not working. Could somebody please help me to find the error?
Than you very much in advance!

Warp two row with a class after query

I want to warp every two row with a class. So I saw some guideline from here and googling and found foreach array_chunk to do this. And I tried as below which can't display any result. Without foreach its work well. Were is my wrong here please?
In the above picture that I want to do; my every two category warp with a class. And add a divider after each top category.
Here is my tried:
echo '<ul class="dropdown-menu dropdown-menu-large row">';
$sql = "SELECT id,name FROM main_cata ORDER BY id ASC";
$execute = $dbh->query("$sql");
$rowcount = $execute->num_rows ;
$row = $dbh->query($sql) ;
while ($row = $execute->fetch_assoc()) {
foreach (array_chunk($row, 2, true) as $array){
echo'<li class="col-sm-3">';
foreach($array as $rows){
echo '<ul><li class="dropdown-header">'.$rows->name.'</li>';
$sql2 = "SELECT id,name,page FROM catagory WHERE m_cata = '".$rows->id."' ORDER BY id ASC";
$execute2 = $dbh->query("$sql2");
$rowcount2 = $execute2->num_rows ;
$row = $dbh->query($sql) ;
while ($row = $execute2->fetch_assoc()) {
$cid = $row['id'];
$cname = $row['name'];
$page = $row['page'];
echo '<li>'.$cname.'</li>';
}
echo '<li class="divider"></li></ul>';
}
echo '</li>';
}
}
echo '</ul>';
while ($row = $execute->fetch_assoc()) {
fetch_assoc returns 1 row (id, name) from the query, then you are using the result and spliting in 2 (https://secure.php.net/manual/pt_BR/mysqli-result.fetch-assoc.php), What you can do is, make a counter instead of the array chunk that resets every time it reachs 2.
foreach (array_chunk($row, 2, true) as $array){
The content of $row is, for example, array('id' => 1, 'name' => 'Category 1').
foreach($array as $rows){
You are iterating again without needing to.
A simple version:
counter = 0;
echo "<ul>";
while (row = execute->fetch_assoc()) {
if (counter == 0) {
echo "init li";
}
echo "subinit li";
get subcategories
while (row2 = execute2->fetch_assoc()) {
print content
}
echo "subend li";
if (counter == 2) {
counter == 0;
echo "end li";
} else {
counter++;
echo "divider";
}
}
echo "</ul>";

Get Multiple Rows in PHP / MYSQL

I am trying to pull the image link for 10 different rows based on ids in an array. It seems to break when the query is in the loop..Any ideas how i can accomplish this?
$array = array(54, 319, 342, 298, 281, 190,178,158,138,7);
$shuffleKeys = array_keys($array);
shuffle($shuffleKeys);
$newArray = array();
foreach($shuffleKeys as $key) {
$newArray[$key] = $array[$key];
}
for($i=0;$i<=count($newArray);$i++){
$query = "SELECT logoName,logoImageLink, logoImageLink2, countryImg, logoArtist, afterText, country FROM logos WHERE id = $array($i) ";
$result = mysql_query($query);
/* fetch rows in reverse order */
for ($i = mysql_num_rows($result) - 1; $i >= 0; $i--) {
if (!mysql_data_seek($result, $i)) {
echo "Cannot seek to row $i: " . mysql_error() . "\n";
continue;
}
if (!($row = mysql_fetch_assoc($result))) {
continue;
}
$imageLink = $row['logoImageLink'];
echo "<li class=\".$array($i).\" ><img src=\".$imageLink.\" /></li>";
}
You can use the MySQL IN clause and do this in a single select.
$ids = join(',',$newArray);
$query = "SELECT logoName,logoImageLink, logoImageLink2, countryImg, logoArtist, afterText, country FROM logos WHERE id IN ($ids)";
$result = $mysqli->query($query);
while ($row = $result->fetch_assoc()) {
$imageLink = $row['logoImageLink'];
echo "<li><img src=\"$imageLink\"/></li>";
}

Create an HTML table like this one

i posted a question a while ago and i got my answer but now i kind of want a followup to this problem so i have a table like the one in the picture but i want to add total to each row or in fact a group how can i do that.
This is the php code to create this table how to edit it to add the total.
$sql = mysql_query(
"SELECT s.login AS 'from', r.login AS 'to',COUNT(*) as'message_count'
FROM messages AS m,groups AS s,groups AS r
WHERE m.Group_ID = s.id
AND m.To_Group_ID = r.id
AND m.Simulation_ID = ".$_SESSION['sim_id']."
AND s.kind_of_user NOT IN (3,1)
AND r.kind_of_user NOT IN (3,1)
AND m.Group_ID IN
(SELECT Group_ID FROM simulationgroups
WHERE Simulation_ID = ".$_SESSION['sim_id'].")
AND m.To_Group_ID IN
(SELECT Group_ID FROM simulationgroups
WHERE Simulation_ID = ".$_SESSION['sim_id'].")
GROUP BY m.Group_ID, m.To_Group_ID
ORDER BY s.id DESC"
) or die (mysql_error());
$data = array();
while($row = mysql_fetch_assoc($sql))
{
$data[$row['to']][$row['from']] += $row['message_count'];
}
// Print headers
$columns = array_keys($data);
echo "<table class='msg_dynamics' cellspacing=0
cellpadding=0 border=1px><tr><th><<</th>";
foreach($columns as $_column)
{
echo "<th width='10%'>{$_column}</th>";
}
echo "<th width='10%'>total</th>";
echo "</tr>";
// Print data
foreach($data as $_row_name => $_row_data)
{
// Add the dash (-) for empty cells
$_row_data[$_row_name] = '-';
echo "<tr><td width='10%'>{$_row_name}";
foreach($columns as $_col_name)
{
echo "<td>{$_row_data[$_col_name]}</td>";
}
echo "</td></tr>";
}
echo "<tr><td><b>total</b></td>";
";
You have to implement a total counter like :
// Print data
foreach($data as $_row_name => $_row_data) {
// Add the dash (-) for empty cells
$_row_data[$_row_name] = '-';
$total_row = 0; //initialize
echo "<tr><td width='10%'>{$_row_name}</td>";
foreach($columns as $_col_name) {
echo "<td>{$_row_data[$_col_name]}</td>";
if ($_row_data[$_col_name] != '-') {
$total_row += $_row_data[$_col_name];
$total_col[$_col_name] += $_row_data[$_col_name];
}
}
echo "<td>{$total_row}</td>";
echo "</tr>";
}
echo "<tr><td><b>total</b></td>";
foreach ($total_col as $name => $val) {
echo "<td>$val</td>";
}

Categories