Query result:
+--------+-----------+--------------+-----------+
| rol_id | pos_name | role_name | sys_name |
+--------+-----------+--------------+-----------+
| 2 | A Manager | Role A | System A |
| 1 | A Manager | Role B | System A |
| 105 | A Manager | Role A | System B |
| 106 | A Manager | Role B | System B |
| 107 | A Manager | Role C | System B |
| 108 | A Manager | Role D | System B |
| 4 | A Manager | Role A | System C |
| 25 | A Manager | Role A | System C |
| 100 | A Manager | Role A | System C |
Required output:
Position Name "A Manager" can access
"System A"
"Role A"
"Role B"
"System B"
"Role A"
"Role B"
"Role C"
"Role D"
etc.
Current code, using a for loop to grab the system names:
$posname = mysqli_fetch_array($posresult);
echo $posname['pos_name']. '<br/>';
echo 'A total of ' .$result->num_rows. ' rows were returned<br/>';
$numResults = $result->num_rows;
$all_results = array();
while ($row = mysqli_fetch_assoc($result)) {
// Append all rows to an array
$all_results[] = $row;
}
for($i = 0; $i < $numResults; $i++){
echo $all_results[$i]["sys_name"];
echo '<br/>';
}
I was intending to learn nested loops next, to put the roles under each system.
But the above lists each system for every row in the array (expected behaviour with the current code), how could I group the output so it looks as above, with each system listed once and each role associated with it printed beneath it?
EDIT
Thought I was making progress but now getting all roles under each system: -
$posname = mysqli_fetch_array($posresult);
echo $posname['pos_name']. '<br/>';
echo 'A total of ' .$result->num_rows. ' rows were returned<br/><br/>';
$numResults = $result->num_rows;
$all_results = array();
while ($row = mysqli_fetch_assoc($result)) {
// Append all rows to an array
$all_results[] = $row;
}
$j = 0;
while ($j < $numResults) {
$sysName = $all_results[$j]["sys_name"];
echo $sysName;
echo '<br/>';
for($i = 0; $i < $numResults; $i++){
if ($all_results[$i]["sys_name"] = $all_results[$j]["sys_name"]){
echo $all_results[$i]["role_name"];
echo '<br/>';
}
}
echo '<br/><hr/>';
$j++;
EDIT: var output. System is the same in each row, which is strange because it isn't if you run the query in MySQL?
array
(0 =>array
('rol_id' => '2','pos_name' => 'Manager A','role_name' => 'Role A','sys_name' => 'System A',),
1 =>array
('rol_id' => '1','pos_name' => 'Manager A','role_name' => 'Role B','sys_name' => 'System A',),
2 =>array
('rol_id' => '105','pos_name' => 'Manager A','role_name' => 'Role A','sys_name' => 'System A',),
3 =>array
('rol_id' => '106','pos_name' => 'Manager A','role_name' => 'Role B','sys_name' => 'System A',),
4 =>array
('rol_id' => '107','pos_name' => 'Manager A','role_name' => 'Role C','sys_name' => 'System A',),
EDIT 2: IF I grab var_export after setting the array, the systems are correct. The above is if I var_export after the loops at the bottom of the code
EDIT 3: So I was using = instead of == in my IF statement! I'm not quite there, but the output is looking a lot better. Will update when I work the last part out. Thanks for the comment below
EDIT FINAL: The below gives what I want, I now see what #ADyson was saying below about comparing the last row with the current. I've used $control for this. Had to play around with where to increment it, but it works now. Thanks all
$all_results = array();
while ($row = mysqli_fetch_assoc($result)) {
// Append all rows to an array
$all_results[] = $row;
}
//var_export($all_results);
$j = 0;
$control = $j;
//$all_results[$row['sys_name']][] = $row;
while ($j < $numResults) {
if ($control == $j){
echo 'System Name: ' . $all_results[$j]["sys_name"];
echo '<br/>';
for($i = 0; $i < $numResults; $i++){
if ($all_results[$i]["sys_name"] == $all_results[$j]["sys_name"]){
echo 'Role: ' . $all_results[$i]["role_name"];
echo '<br/>';
$control++;
}
}
echo '<br/>';
}
$j++;
}
$all_results = array();
while ($row = mysqli_fetch_assoc($result)) {
// Append all rows to an array
$all_results[] = $row;
}
//var_export($all_results);
$j = 0;
$control = $j;
//$all_results[$row['sys_name']][] = $row;
while ($j < $numResults) {
if ($control == $j){
echo 'System Name: ' . $all_results[$j]["sys_name"];
echo '<br/>';
for($i = 0; $i < $numResults; $i++){
if ($all_results[$i]["sys_name"] == $all_results[$j]["sys_name"]){
echo 'Role: ' . $all_results[$i]["role_name"];
echo '<br/>';
$control++;
}
}
echo '<br/>';
}
$j++;
}
Thanks to #ADyson, see first comment for the great guidance. The $control is how I implemented the suggestion
Related
I want to export my code to excel however the header is also dynamic. Here is my code, i need assistance in exporting my data. This code below shows a dynamic table i showed in user view and needs to be exported. The view is:
"title: course/section"
"header: student id | student name | program | term | dynamic date 1 | Remarks (remarks why u are absent) including date 1 | date 2 | Remarks (remarks why u are absent) including date 2 | and so on.."
"table data: 20122222 |pinky webb |computer science | 3 | Absent | With medical certificate | present | no remark | present | no remark | late | no remark | and do on... "
"table data 2: 20122333 |Mane Sharpay|computer science | 3 | Absent | With medical certificate | present | no remark | Late | no remark | late | no remark | and so on... "
and so on...
basically, it shows the student and its attendance per date horizontally with a dynamic header of dates. sorry if im noob hehe but ill give a thumbs up i promise for ur effort
<?php
$query = "SELECT course_id, sections_id from current_att_view inner join professor_tbl on current_att_view.professor_id = professor_tbl.professor_id where professor_live_account = '".$_SESSION['username']."' group by course_id, sections_id";
$result1 = mysqli_query($link, $query);
while ($col1 = mysqli_fetch_array($result1))
{
$reslt;
echo '<h3 class="course-sect">'.$col1[0].'/'.$col1[1].'</h3>';
$qry = "Call Get_Attendance_Course_Section('".$_SESSION['username']."','".$col1[0]."','".$col1[1]."')";
$reslt = mysqli_query($link, $qry);
echo '<table class="table table-bordered">';
echo '<tr>';
if (!$reslt) {
printf("Error: %s\n", mysqli_error($link));
exit();
}
else{
while ($fieldinfo = mysqli_fetch_field($reslt)) {
if($fieldinfo->name != "Course" && $fieldinfo->name != "Section" && $fieldinfo->name != "Course Name" && $fieldinfo->name != "Schedule")
{
echo '<th>';
echo $fieldinfo->name;
echo '</th>';
}
}
echo '</tr>';
while ($rows = mysqli_fetch_array($reslt))
{
for ($i=0; $i < (count($rows)/2); $i++) {
if($i != 3 && $i != 4 && $i != 5 && $i != 6){
echo '<td>';
echo $rows[$i];
echo '</td>';
}
}
echo '</tr>';
}
echo '</table>';
mysqli_next_result($link);
}
}
// $reslt =mysqli_query($link, $qry);
?>
<input type=hidden name=date value='<?php echo date("F d, Y",strtotime($date));?>'>
<input type="hidden" name="outy" value="<?php echo $sql; ?>">
<input type="submit" name="export" value="Export" class="submit" />
I have this table:
img id | img_path | listing_assoc_id|
----------------------------------------
11 |img/img1.jpg | 12 |
12 |img/img2.jpg | 12 |
13 |img/img3.jpg | 12 |
14 |img/img4.jpg | 12 |
15 |img/img5.jpg | 12 |
16 |img/img6.jpg | 12 |
18 |img/img7.jpg | 12 |
21 |img/img8.jpg | 12 |
22 |img/img9.jpg | 12 |
23 |img/img10.jpg| 12 |
24 |img/img11.jpg| 12 |
And I want to display it into a table in html
like this maximum of 5 images per row. I have been fiddling with different loops in combination of different loops like above for a couple hours but haven't found one that works like I need. They are either displaying the same images across the entire row or are messed up in some other way. Obviously need to use tr & td elements to format table correctly.
What I need:
<tr>
<td>img1</td> <td>img2</td> <td>img3</td> <td>img4</td> <td>img5</td>
</tr>
<tr>
<td>img6</td> <td>img7</td> <td>img8</td> <td>img9</td> <td>img10</td>
</tr>
<tr>
<td>img11</td>
</tr>
Some of the code that doesn't work:
$query = "SELECT * FROM listings_gallery WHERE listing_assoc_id = " 12 " ORDER BY img_id ASC";
$image_set = mysqli_query($connection, $query);
echo '<tr>';
while($img = mysqli_fetch_assoc($image_set)){
while($img['img_id'] < 5){
echo "<td><img src='" . $img['img_path'] . "'></td>";
}
echo '<tr>';
}
I wouldn't actually depend on the image ID. You could use % 5 to do this, but the IDs may be out of order, etc. Instead, you can just fetch everything into an array and use array_chunk
$img = array();
while ($img = mysqli_fetch_assoc($image_set)) {
$imgs[] = $img;
}
foreach (array_chunk($imgs, 5) as $img_chunk) {
echo "<tr>";
foreach ($img_chunk as $img) {
echo "<td>$img</td>";
}
echo "</tr>";
}
This is probably about as simple as it gets but it's not as memory efficient as could be. You could also maintain your own counter and check % 5 for that to break out of the inner loop.
$images_rows = mysqli_query($connection, $query);
$images = array();
while ($image = mysqli_fetch_assoc($images_rows)) {
$images[] = $image;
}
echo '<table><tr>';
$ct = 0;
$ctt = 0;
$size = sizeOf($images) - 1;
foreach($images as $image){
if($ct == 5) {
echo '<tr>';
$ct = 0;
}
echo "<td><img src='" . $image['img_path'] . "'></td>";
$ct++;
$ctt++;
echo ($ct == 5 && $ctt != $size) ? '</tr>': '';
}
echo '</tr></table>'
I am trying to create reports based on data from a log in the database that looks like:
id | student | type | marks
1 23494 CAT1 50
2 23495 CAT1 20
3 23494 CAT2 35
4 23495 MIDTERM 40
My select statement so far looks like this:
$res = #mysqli_query ($dbc, "SELECT id, student, type, GROUP_CONCAT(marks) AS mark, GROUP_CONCAT(type) AS types FROM log WHERE class = '1' AND term = '2' GROUP BY student DESC");
// Fetch and print all the records....<br>
while ($row = mysqli_fetch_array($res, MYSQLI_ASSOC)) {
echo '<tr>
<td align="left">'. $row['student'] .'</td>';
//$exams = split(",", $row['exams']); // 4,3,1,2
$marks = split(",", $row['mark']); // 10,20,40,50
foreach( $marks as $mark ) {
echo '
<td align="left">' . $mark . '</td>
';
}
echo '</tr>';
} //End LOOP
//Then i end table
So far the data displays like so:
STUDENT | CAT1 | CAT2 | MIDTERM
23494 50 35
23495 20 40
The problem is that the code is not arranging 'marks' according to 'type' (look at MIDTERM output for id 4 and corresponding display).
Question:
How do i display the results by student, followed by marks in the appropriate cell/group like so:?
STUDENT | CAT1 | CAT2 | MIDTERM
23494 50 35
23495 20 40
Thanks in Advance Guys.
First, try to keep logic away from layout. It's generally good practice to first gather the data you need, and then display it.
Using GROUP_CONCAT can make things more complicated, since you do not know how many results you will get for each student, nor will you be able to easily identify which marks are of what type.
With that in mind I've created a solution. You'll still need to extend the query of course.
$query = 'SELECT student, type, marks FROM log';
$res = mysqli_query($query);
$studentMarks = array();
while ($row = mysqli_fetch_array($res, MYSQLI_ASSOC))
{
$studentMarks[$row['student']][$row['type']] = $row['marks'];
}
// Now $studentMarks should look like:
// $studentMarks = array(
// 23494 => array('CAT1' => 50, 'CAT2' => 35)
// , 23495 => array('CAT1' => 20, 'MIDTERM' => 40)
// );
echo '<table><thead><tr>';
echo '<td>Student</td><td>CAT1</td><td>CAT2</td><td>MIDTERM</td>';
echo '</tr></thead><tbody>';
foreach($studentMarks as $studentId => $marks)
{
echo '<tr>';
echo '<td>', $studentId, '</td>';
echo '<td>', (isset($marks['CAT1']) ? $marks['CAT1'] : ' '), '</td>';
echo '<td>', (isset($marks['CAT2']) ? $marks['CAT2'] : ' '), '</td>';
echo '<td>', (isset($marks['MIDTERM']) ? $marks['MIDTERM'] : ' '), '</td>';
echo '</tr>';
}
echo '</tbody></table>';
I have a table name category with following cols
cat_id | name | parent
1 | item 1 | 0
2 | item 2 | 1
3 | item 3 | 0
4 | item 4 | 1
5 | item 5 | 3
How i can display it in a menu like this
Item 1
> Item 2
> Item 4
Item 3
> Item 5
Please help
Here is the function that can be used:
// $current_cat_id: the current category id number
// $count: just a counter, call it as 0 in your function call and forget about it
// Gets the drop down list recurssively of categories //
function find_pages_recursive($current_cat_id, $count)
{
global $db; // the database object instance
static $option_results;
// if there is no current category id set, start off at the top level (zero)
if (!isset($current_cat_id))
{
$current_cat_id = 0;
}
$count++;
// query the database for the sub-categories of whatever the parent category is
$query = 'SELECT id, title from pages where parid = ' . $current_cat_id . ' order by id';
$get_options = $db->execute($query);
$num_options = $db->count_select();
// our category is apparently valid, so go ahead :P
if ($num_options > 0)
{
while (list($cat_id, $cat_name) = mysql_fetch_row($get_options))
{
// if its not a top-level category, indent it to show that its a child category
if ($current_cat_id != 0)
{
$indent_flag = '';
for ($x = 2; $x <= $count; $x++)
{
$indent_flag .= '----';
}
$indent_flag .= ' ';
}
$option_results[$cat_id] = $indent_flag . $cat_name;
// now call the function again, to recurse through the child categories
find_pages_recursive($cat_id, $count);
}
}
return $option_results;
}
How To Use It:
echo '<select name="pages" id="pages">' . "\n";
echo '<option value="">--Select Page--</option>' . "\n";
$get_options = find_pages_recursive(0, 0);
if (count($get_options) > 0)
{
foreach ($get_options as $key => $value)
{
$options .= "<option value=\"$key\"";
$options .= ">$value</option>\n";
}
}
echo $options;
echo '</select>' . "\n";
Make sure to connect to the database first :)
I'm building a form with php/mysql. I've got a table with a list of locations and sublocations. Each sublocation has a parent location. A column "parentid" references another locationid in the same table. I now want to load these values into a dropdown in the following manner:
--Location 1
----Sublocation 1
----Sublocation 2
----Sublocation 3
--Location 2
----Sublocation 4
----Sublocation 5
etc. etc.
Did anyone get an elegant solution for doing this?
NOTE: This is only psuedo-code.. I didn't try running it, though you should be able to adjust the concepts to what you need.
$parentsql = "SELECT parentid, parentname FROM table";
$result = mysql_query($parentsql);
print "<select>";
while($row = mysql_fetch_assoc($result)){
$childsql = "SELECT childID, childName from table where parentid=".$row["parentID"];
$result2 = mysql_query($childsql);
print "<optgroup label=\".$row["parentname"]."\">";
while($row2 = mysql_fetch_assoc($result)){
print "<option value=\"".$row["childID"]."\">".$row["childName"]."</option>\n";
}
print "</optgroup>";
}
print "</select>";
With BaileyP's valid criticism in mind, here's how to do it WITHOUT the overhead of calling multiple queries in every loop:
$sql = "SELECT childId, childName, parentId, parentName FROM child LEFT JOIN parent ON child.parentId = parent.parentId ORDER BY parentID, childName";
$result = mysql_query($sql);
$currentParent = "";
print "<select>";
while($row = mysql_fetch_assoc($result)){
if($currentParent != $row["parentID"]){
if($currentParent != ""){
print "</optgroup>";
}
print "<optgroup label=\".$row["parentName"]."\">";
$currentParent = $row["parentName"];
}
print "<option value=\"".$row["childID"]."\">".$row["childName"]."</option>\n";
}
print "</optgroup>"
print "</select>";
Are you looking for something like the OPTGROUP tag?
optgroup is definitely the way to go. It's actually what it's for,
For example usage, view source of http://www.grandhall.eu/tips/submit/ - the selector under "Grandhall Grill Used".
You can use and space/dash indentation in the actual HTML. You'll need a recusrive loop to build it though. Something like:
<?php
$data = array(
'Location 1' => array(
'Sublocation1',
'Sublocation2',
'Sublocation3' => array(
'SubSublocation1',
),
'Location2'
);
$output = '<select name="location">' . PHP_EOL;
function build_items($input, $output)
{
if(is_array($input))
{
$output .= '<optgroup>' . $key . '</optgroup>' . PHP_EOL;
foreach($input as $key => $value)
{
$output = build_items($value, $output);
}
}
else
{
$output .= '<option>' . $value . '</option>' . PHP_EOL;
}
return $output;
}
$output = build_items($data, $output);
$output .= '</select>' . PHP_EOL;
?>
Or something similar ;)
Ideally, you'd select all this data in the proper order right out of the database, then just loop over that for output. Here's my take on what you're asking for
<?php
/*
Assuming data that looks like this
locations
+----+-----------+-------+
| id | parent_id | descr |
+----+-----------+-------+
| 1 | null | Foo |
| 2 | null | Bar |
| 3 | 1 | Doe |
| 4 | 2 | Rae |
| 5 | 1 | Mi |
| 6 | 2 | Fa |
+----+-----------+-------+
*/
$result = mysql_query( "SELECT id, parent_id, descr FROM locations order by coalesce(id, parent_id), descr" );
echo "<select>";
while ( $row = mysql_fetch_object( $result ) )
{
$optionName = htmlspecialchars( ( is_null( $row->parent_id ) ) ? "--{$row->descr}" : "----{$row->desc}r", ENT_COMPAT, 'UTF-8' );
echo "<option value=\"{$row->id}\">$optionName</option>";
}
echo "</select>";
If you don't like the use of the coalesce() function, you can add a "display_order" column to this table that you can manually set, and then use for the ORDER BY.