With mysql left-join I have a result of 3 tables.
Every group of machine-types has special requirements. Some machine-types have the same requirements, some not.
My problem is, to list them grouped and clear adressable for css-styling. I want to show all groups - with its requirements - but the group as header only one time.
How can I output and place a closing div to the right position?
$lastDate = '';
while($r = $result_all->fetch(PDO::FETCH_OBJ)) {
$aktualisiert = $r->MTypID;
if ( $aktualisiert != $lastDate ){
echo '<div class="machine-type">'.$r->mtype'</div>';
echo '<div class="requirements">';
$lastDate = $aktualisiert;
}
//if ( $aktualisiert = $lastDate ){
echo $r->baustand." ";
//}
}//endwhile
Output should be like this (see *</div>*):
<div class="machine-type">Model 1</div><div class="requirements">Softwareupdate 2.4.0 Valve M4 Tube 20cm *</div>*
<div class="machine-type">Model 2</div><div class="requirements">Softwareupdate 2.4.0 *</div>*
You just need to close the div when $lastDate changes, but not when it is the first row in the output. So after
if ( $aktualisiert != $lastDate ){
add
if ( $lastDate != '' ) echo "</div>";
and then after your loop add
echo "</div>";
With adding of a separator (also a bit tricky), it's more useful.
Here the final code - maybe interesting to somebody...
$lastDate = '';
$separator ='+';
$space =' ';
while($r = $result_all->fetch(PDO::FETCH_OBJ)) {
$aktualisiert = $r->MTypID;
if ( $aktualisiert == $lastDate ) echo $separator.$space;
if ( $aktualisiert !== $lastDate ){
if ( $lastDate !== '' ) echo '</div>'; //<!-- end requirements 1/2 -->
echo '<div class="machine-type">'.htmlspecialchars($r->mtype)'</div>';;
echo '<div class="requirements">';
$lastDate = $aktualisiert;
}
echo htmlspecialchars($r->baustand).' ';
}//endwhile
echo '</div>'; //<!-- end requirements 2/2 -->
Related
I am currently coding a page based on a json query.
Here is a snippet of the code, I don't want to give the top half as that is grabbing the remote json with id's and passwords, but here is the main snippet:
$content_size = 'one_half';
foreach ( $json_decoded['fixtures-results']['matches'] as $match ){
display_match($match);
}
function display_match($match){
global $content_size;
if (strtotime($match['date']) < time()) { goto skip; }
$home_team_name = strtolower($match['home-team']['name']);
$home_team_name = preg_replace('/\s+/', '_',$home_team_name);
$away_team_name = strtolower($match['away-team']['name']);
$away_team_name = preg_replace('/\s+/', '_',$away_team_name);
$match_date = date("M jS, Y", strtotime($match['date']));
echo '<div class="'.$content_size.'">';
echo '<div class="latest_results" style="background:#ffffff">';
echo '<h6>'.$match_date.', '.$match['status']['full'].'</h6>';
echo '<div class="latest_results_col"><img src="/team_logos/'.$home_team_name.'.png"><span>'.$match['home-team']['name'].'</span></div>';
echo '<div class="latest_results_col goalscore2">vs</div>';
echo '<div class="latest_results_col"><img src="/team_logos/'.$away_team_name.'.png"><span>'.$match['away-team']['name'].'</span></div>';
echo '<div class="clear">';
echo '<span>Location:'.$match['venue'].'</span>';
echo '</div>';
echo '</div>';
echo '</div>';
if ($content_size == "one_half") { $content_size = "one_half_last"; goto skip; }else{ $content_size = "one_half"; goto skip; }
skip:
}
What i want is the first div class to be one_half then the next one as one_half_last then back to one_half and so on.
The result is the first div has the class one_half but the second has no class, then the third has one_half and so on, so you see it seems to be working, except its missing the second, fourth, sixth ect class.
Any help would be greatly received.
Kind Regards,
Adam
I am not sure what happened, and why it corrected itself, but here is the code i ended up using.
$content_size = 'one_half';
foreach ( $json_decoded['fixtures-results']['matches'] as $match ){
display_match($match);
}
function display_match($match){
global $content_size;
if(!$content_size){ $content_size = "one_half"; }
if (strtotime($match['date']) < time()) { goto skip; }
$home_team_name = strtolower($match['home-team']['name']);
$home_team_name = preg_replace('/\s+/', '_',$home_team_name);
$away_team_name = strtolower($match['away-team']['name']);
$away_team_name = preg_replace('/\s+/', '_',$away_team_name);
$match_date = date("M jS, Y", strtotime($match['date']));
$home_team_name_2 = team_name_2($match['home-team']['name']);
$away_team_name_2 = team_name_2($match['away-team']['name']);
echo '<div class="'.$content_size.'">';
echo '<div class="latest_results" style="background:#ffffff">';
echo '<h6>'.$match_date.', '.$match['status']['full'].'</h6>';
echo '<div class="latest_results_col"><img src="/team_logos/'.$home_team_name.'.png"><span>'.$home_team_name_2.'</span></div>';
echo '<div class="latest_results_col goalscore2">vs</div>';
echo '<div class="latest_results_col"><img src="/team_logos/'.$away_team_name.'.png"><span>'.$away_team_name_2.'</span></div>';
echo '<div class="clear">';
echo '<span>Location:'.$match['venue'].'</span>';
echo '</div>';
echo '</div>';
echo '</div>';
if ($content_size == "one_half") { $content_size = "one_half last_column"; goto skip; }else{ $content_size = "one_half"; goto skip; }
skip:
}
If anyone has any idea what I did differently I am happy to hear as I am not sure what i did.
I have this code that's creating an extra empty div when there are extactly 3, 6, 9, etc items.
<?php
$i = 1;
echo '<div class="three-item-wrapper">';
if( have_rows('upcoming_stops_asia') ): while ( have_rows('upcoming_stops_asia') ) : the_row();
?>
<div class="item">Content</div>
<?php
if($i % 3 == 0) {echo '</div><div class="three-item-wrapper">';}
$i++; endif; endwhile; endif;
echo '</div>';
?>
I'm not sure how to fix it.
You are ending the current div and starting a new one when you get to a multiple of 3. If there are no more after that, then the div will of course be empty. One solution would be to accumulate the results and output them in a div only as required:
<?php
if( have_rows('upcoming_stops_asia') ) {
$results = [];
while ( have_rows('upcoming_stops_asia') ) {
the_row();
// Add to the collection of results
$results[] = '<div class="item">Content</div>';
if( count($results) == 3 ) {
// Output three results and reset
echo '<div class="three-item-wrapper">' . implode($results) . '</div>';
$results = [];
}
}
// Output any additional results; no div generated if there aren't any
if( !empty(results) ){
echo '<div class="three-item-wrapper">' . implode($results) . '</div>';
}
}
?>
I am currently trying to create a class schedule which I pull from my Sql Server database with PHP and I am trying to get the layout output as well as the data as I am grouping the resources.
These groupings are nested such as:
-DAY
--TIME
---CLASS
----STUDENTS
And should output like this:
However, I am getting this:
My current output is working, however, it is only on the first loop, then everything goes haywire. I am assuming there is an erroneous </div> tag somewhere in my code yet I cannot for the life of me find it.
My php code is a function that is delcare as such:
<div class="mainScheduleWrapper">
<?php daySchedule(); ?>
</div>
My php code is as such:
function daySchedule() {
global $conn;
$dayScheduleQuery = 'SET DATEFIRST 1
SELECT [DAY].[DAY] AS [DAY], CLASS.CLASSTIME AS CLASSTIME, CLASSLEVEL.CLASSLEVEL AS CLASSLEVEL, CLASS.MAXSTUDENT AS MAXSTUDENT, INSTRUCTOR.FIRSTNAME AS INSTRUCTOR, STUDENT.FIRSTNAME AS STUDENTFIRST, STUDENT.SURNAME AS STUDENTLAST, STUDENT.DOB AS STUDENTDOB
FROM STUDENT JOIN BOOKING ON STUDENT.ID = BOOKING.STUDENTID JOIN CLASS ON CLASS.ID = BOOKING.CLASSID JOIN CLASSLEVEL ON CLASS.CLASSLEVELID = CLASSLEVEL.ID JOIN [DAY] ON CLASS.CLASSDAY = [DAY].ID JOIN INSTRUCTOR ON CLASS.INSTRUCTORID = INSTRUCTOR.ID
WHERE [DAY].ID = (DATEPART(dw, GETUTCDATE() AT TIME ZONE \'AUS Eastern Standard Time\'))
ORDER BY CLASS.CLASSTIME ASC, INSTRUCTOR.FIRSTNAME ASC, CLASSLEVEL.CLASSLEVEL ASC';
// COUNTERS
$t = 0;
$i = 0;
//VARIABLES FOR DAY SCHEDULE
$classDay = NULL;
$classTime = NULL;
$classInstructor = NULL;
$closeClass = false;
$closeAll = false;
$queryConnector = $conn->query($dayScheduleQuery);
foreach ($queryConnector as $schedule) {
// CLASS DAY HEADER
if ($classDay != $schedule['DAY']) {
echo '<div class="grid-1">';
echo '<h1>' . $schedule['DAY'] . '</h1>';
echo '</div><!-- Day closed! -->';
$classDay = $schedule['DAY'];
}
// CLASS TIME HEADER
if ($classTime != $schedule['CLASSTIME']) {
if($classTime != $schedule['CLASSTIME'] && $t > 0) {
$closeAll = true;
goto closeAll;
}
echo '<div class="grid-12-noGutter scheduleContainer">'; //NON-CLOSED
echo '<h1>' . 'T = ' . $t . '</h1>';
echo '<div class="grid-middle-center col scheduleTimeTab">';
// FIX 3 DIGIT MILITARY TIME
if (strlen($schedule['CLASSTIME']) < 4) {
$classScheduleTime = '0' . $schedule['CLASSTIME'];
} else {
$classScheduleTime = $schedule['CLASSTIME'];
}
echo '<p>' . date('g:i A', strtotime($classScheduleTime)) . '</p>';
echo '</div>'; //CLOSE TIME TAB
echo '<div class="innerSchedule">'; // NON-CLOSED
$classTime = $schedule['CLASSTIME'];
$t += 100;
}
// INSTRUCTOR HEADER
if ($classInstructor != $schedule['INSTRUCTOR']) {
if ($classInstructor != $schedule['INSTRUCTOR'] && $i > 0) {
$closeClass = true;
goto closeClassWrapper;
}
echo '<div class="classWrapper">';
echo '<h1>' . 'I =' . $i . 'T = ' . $t . '</h1>';
echo '<div class="grid-3-middle classHeader">';
echo '<div class="col classHeaderCell' . classLevelColour($schedule['CLASSLEVEL']) . '">' . $schedule['CLASSLEVEL'] . '</div>';
echo '<div class="col classHeaderCell">' . $schedule['INSTRUCTOR'] . '</div>';
echo '<div class="col classHeaderCell">Max' . ' ' . $schedule['MAXSTUDENT'] . '</div>';
echo '</div>';
echo '<div class="grid-4-middle" id="studentHeaders">';
echo '<div class="col"><h6>Student Name</h6></div>';
echo '<div class="col"><h6>Student Birthday</h6></div>';
echo '<div class="col"><h6>Class Level</h6></div>';
echo '<div class="col"><h6>Attendance</h6></div>';
echo '</div>';
$classInstructor = $schedule['INSTRUCTOR'];
$i += 100;
}
echo '<div class="grid-4 studentRow">';
echo '<div class="col">';
echo '<span class="studentCell">' . $schedule['STUDENTFIRST'] . ' ' . $schedule['STUDENTLAST'] . '</span>';
echo '</div>';
echo '<div class="col">';
echo '<span class="studentCell">' . $schedule['STUDENTDOB'] . '</span>';
echo '</div>';
echo '<div class="col">';
echo '<span class="studentCell">' . $schedule['CLASSLEVEL'] . '</span>';
echo '</div>';
echo '<div class="col">';
echo '<span class="studentCell">--</span>';
echo '</div>';
echo '</div>';
// GOTO TAGS
closeClassWrapper: {
if ($closeClass === true) {
echo '</div>';
$closeClass = false;
$i = 0;
}
}
closeAll: {
if ($closeAll === true) {
echo '</div>';
echo '</div>';
echo '</div>';
$closeAll = false;
$t = 0;
$i = 0;
}
}
}
}
Any help would be greatly appreciated - even if it's to tell me I'm going about it the completely wrong way.
Kindest Regards
Michael Z
I wouldn't say you're going about it the completely wrong way, but a few red flags jumped out at me in your code.
The use of goto jumping is bad practice. It butchers your program flow and forces you to segregate tasks that shouldn't be kept apart. You marked the sections of code "// NON CLOSED" when there was a </div> missing, is there any purpose for that? How do you know the goto sections are reliable?
When you echo something like <div class="col">, without escaping the double-quotes (as in \" for every " character), it can be problematic. Your code can get mangled or misinterpreted, both on the PHP end or on the HTML end.
Like others have said, the use of PHP may be overkill here. Besides just sending the JSON, the rest could be handled with JavaScript.
I have an issue that seems to be quiet easy but I just would like to ask how you would solve it:
In a MySQL-table there is the following structure:
provider artist
a 1
a 2
a 3
b 4
Now it is necessary to echo a list in HTML like:
provider a
1
2
3
provider b
4
I stuck at the point where I would like to group the results and echo them out with for-each and while loop.
The main idea is quiet simple like:
<?php $query = mysqli->query("SELECT * FROM `table` GROUP by provider");
foreach GROUP {?>
echo some styling HTML-code for each group of headline;
<?php while ($data= $query->fetch_assoc()){?>
echo some styling HTML-code for each list-item;
<?php};?>
Thanks in advance.
UPDATE:
Thanks for answering.
The solution fro RiggsFolly seems to work fine. There is just a small problem with the HTML. There is a surrounding div-tag that wont be closed when adding the HTML code in that line:
echo 'provider '. $data->provider;
The problem is that the while loop needs to be in the div. The closing div-tag is missing for every
if ( $current_provider != $data->provider ) {
Here is the original HTML-code:
<?php
$service = $db->query("SELECT * FROM `system` ORDER BY provider, artist");
$current_provider = NULL;
while ($data = $service->fetch_object()) {
if ( $current_provider != $data->provider ) {// new provider?>
<div class="service">
<p class="lower">
<?php echo $data->provider;?>
</p>
<?php
$current_provider = $data->provider;
}?>
<a href='?artist=<?php echo $data->artist;?>'><?php echo "/".$data->artist;?</a><br/>
<?php };?>
</div><!--service -->
The list-items will be shown nicely. But when looking into the Source code you can see that the closing div-tag is missing. Thanks
Kind regards.
It would seem simpler to not use a GROUP BY especially as it will not provide you with the data that you want. So instead just select them all and sort them by provider and maybe artist as a sub sort like so
<?php
$result = $mysqli->query("SELECT * FROM `table` ORDER BY provider, artist");
$current_provider = NULL;
while ($data = $result->fetch_object()){
if ( $current_provider != $data->provider ) {
// new provider
echo 'provider '. $data->provider;
$current_provider = $data->provider;
}
echo $data->artist;
}
?>
AFTER UPDATE:
<?php
$service = $db->query("SELECT * FROM `system` ORDER BY provider, artist");
$current_provider = NULL;
while ($data = $service->fetch_object()) {
if ( $current_provider != $data->provider ) {
if ( $current_provider !== NULL ) {
echo '</div>';
}
echo '<div class="service">';
echo '<p class="lower">' . $data->provider . '</p>';
$current_provider = $data->provider;
}
echo '<a href="?artist=' . $data->artist '">' .
$data->artist . '</a><br/>';
}
echo '</div>';
How about that.
<?php $query = mysqli->query("SELECT * FROM `table`");
$current_group = array();
while ($data= $query->fetch_assoc()){
if(in_array($data['provider'],$current_group)){
echo "<h1>New Group" . $data['provider'] ."</h1>";
$current_group[] = $data['provider']
}
echo $data['artist'] . "<br/>";
}
I'm running a while loop which is taking rows from mySQL and echo'ing them out. Pretty standard. However, there needs to be different HTML markup for the first item, next two items, then it continues as normal into the while loop.
Currently, my while loop looking something like this:
while( ( $row = mysql_fetch_object( $result ) ) !== false )
{
// Places ad based of predefined variable frequency
if ($ad == $adFrequency){
echo '<div class="one-advertisement-article clearfix">';
echo '<div class="grid_9 suffix_2"><img src="http://placehold.it/263x75/000000/ffffff"></div>';
echo '<div class="grid_1"><a class="navigate-right-icon ss-icon" href="#">navigateright</a></div>';
echo '</div>';
$ad = 0;
}
echo '<div class="one-news-article clearfix">';
if( $row->imagelibid )
{
$imageid = intval( $row->imagelibid );
$image_result = mysql_query( "SELECT * FROM imagelib WHERE id = {$imageid}", $db );
$image_row = mysql_fetch_object( $image_result );
$image_url = "http://www.#.com/slir/w280/imagelib/" . $image_row->id . "_" . $image_row->filename;
echo '<div class="grid_4"><img src="'.$image_url.'"></div>';
}
else {
echo '<div class="grid_4"><div class="news-placeholder"><span class="ss-icon">ellipsischat</span></div></div>';
}
echo '<div class="grid_7">';
echo '<h2>'.$row->title.'</h2>';
$published_date = date('D, d M Y', strtotime($row->datein));
echo '<p class="published-date">'.$published_date.'</p>';
echo '</div>';
echo '<div class="grid_1">';
echo '<div class="news-item-vertical-sep"> </div>';
echo '<p></p>';
echo '</div>';
echo '</div>';
$ad++;
}
This works fine, but I need to take the first three news items and use this:
echo ' <div class="one-news-featured-article clearfix">';
echo ' <div class="grid_12">';
if( $row->imagelibid )
{
$imageid = intval( $row->imagelibid );
$image_result = mysql_query( "SELECT * FROM imagelib WHERE id = {$imageid}", $db );
$image_row = mysql_fetch_object( $image_result );
$image_url = "http://www.#.com/slir/w280/imagelib/" . $image_row->id . "_" . $image_row->filename;
echo '<div class="large-featured-image-container"><img src="'.$image_url.'">/div>';
}
echo ' <div>';
echo ' <h2>'.$row->title.'</h2>';
echo ' </div>';
echo ' </div>';
echo ' </div>';
echo ' <div class="grid_6">';
Any help? Essentially, it needs to apply the second code to the first three items in the query, then follow through with the code included in the current while loop - like an offset I guess.
Thanks,
R
This is quite simple. I hope I understood your question correctly:
$i = 0;
while ( ( $row = mysql_fetch_object( $result ) ) !== false ) {
if ($i < 3) {
// First code
} else {
// Second code
}
$i += 1;
}
Firstly, you should avoid using any mysql_ functions as they are all deprecated and will be removed from future versions of PHP. I'd recommend using PDO instead. See this tutorial to get started.
Then, it'll simply be a case of doing something like this:
foreach($db->query($query) as $index => $row) {
if ($index < 3) {
// first 3 items
} else {
// other items
}
}
You can do it easaly with an simple counter and an if statement:
$count = 0;
while(fetching) {
if($count < 3) {
// items 1, 2 and 3
} else {
// do normal
}
$count++;
}