0

Currently I have this,

enter image description here

This my code

 <table class="table table-hover">
  <thead>
    <tr>
      <th scope="col">Monday</th>
      <th scope="col">Tuesday</th>
      <th scope="col">Wednesday</th>
      <th scope="col">Thursday</th>
      <th scope="col">Friday</th>
      <th scope="col">Saturday</th>
      <th scope="col">Sunday</th>
    </tr>
  </thead>
  <tbody>

<?php     
      if(isset($_GET['class_id'])) {
        $class_id = $_GET['class_id'];

            } else {
              $class_id = '1'; //default class id => Yoga
            }

       $mQuery = "SELECT * FROM timetable where class_id = '".$class_id."'"; //code to select from database

        $result = $pdo-> query($mQuery); 

        while($row = $result->fetch(PDO::FETCH_ASSOC)):

            $timeslot = $row['timeslot'];
            // pass delimiter and string to explode function
            $timeslot_ar = explode(',', $timeslot);


      ?>        

    //code to display result in table
    <tr class="table-active">
        <?php if(date('l', strtotime($row['date'])) == 'Monday') { ?>
           <td><?= date('d M', strtotime($row['date'])); ?><br/><?= implode("<br/>", $timeslot_ar); ?></td>

           <?php }else { ?>
           <td></td>
        <?php } ?>

        <?php if(date('l', strtotime($row['date'])) == 'Tuesday') { ?>
           <td><?= date('d M', strtotime($row['date'])); ?><br/><?= implode("<br/>", $timeslot_ar); ?></td>
           <?php }else { ?>
           <td></td>
        <?php } ?>

        <?php if(date('l', strtotime($row['date'])) == 'Wednesday') { ?>
           <td><?= date('d M', strtotime($row['date'])); ?><br/><?= implode("<br/>", $timeslot_ar); ?></td>
           <?php }else { ?>
           <td></td>
        <?php } ?>

        <?php if(date('l', strtotime($row['date'])) == 'Thursday') { ?>
           <td><?= date('d M', strtotime($row['date'])); ?><br/><?= implode("<br/>", $timeslot_ar); ?></td>
           <?php }else { ?>
           <td></td>
        <?php } ?>

        <?php if(date('l', strtotime($row['date'])) == 'Friday') { ?>
           <td><?= date('d M', strtotime($row['date'])); ?><br/><?= implode("<br/>", $timeslot_ar); ?></td>
           <?php }else { ?>
           <td></td>
        <?php } ?>

        <?php if(date('l', strtotime($row['date'])) == 'Saturday') { ?>
           <td><?= date('d M', strtotime($row['date'])); ?><br/><?= implode("<br/>", $timeslot_ar); ?></td>
           <?php }else { ?>
           <td></td>
        <?php } ?>

        <?php if(date('l', strtotime($row['date'])) == 'Sunday') { ?>
           <td><?= date('d M', strtotime($row['date'])); ?><br/><?= implode("<br/>", $timeslot_ar); ?></td>
           <?php }else { ?>
           <td></td>
        <?php } ?>
    </tr>
<?php endwhile; ?> 
  </tbody>
</table> 

I've been trying to get my result to display in a single row for all the days and then make a new row when a day of the same name already exists. I've been trying to figure out the login behind this and after countless of stack overflow answers and youtube tutorials I got to this point. I still can't manage to get them in a single row, if anyone would be kind enough to explain the method behind this, I would really appreciate it.

5
  • 1
    If you want them in a single row, then you need to run while loop in <td> not in <tr>. Commented Jan 27, 2020 at 13:29
  • 1
    Can't help wondering if this code could be more concisely expressed. Commented Jan 27, 2020 at 13:30
  • 1
    Warning: Your code is vulnerable to SQL Injection attacks. You should use parameterised queries and prepared statements to help prevent attackers from compromising your database by using malicious input values. bobby-tables.com gives an explanation of the risks, as well as some examples of how to write your queries safely using PHP / mysqli. Never insert unsanitised data directly into your SQL. The way your code is written now, someone could easily steal, incorrectly change, or even delete your data. Commented Jan 27, 2020 at 13:34
  • you must write td in while but you write tr in while and php print the tr Commented Jan 27, 2020 at 14:21
  • You urgently need to read up on for loops to cut down on the ridiculous amount of duplication in this code. An array of days would make this code collapse by a factor of seven. Commented Jan 27, 2020 at 19:18

3 Answers 3

1

Put the <tr></tr> outside of the while() loop:

<tr class="table-active">
<?php     
  // other code

    while($row = $result->fetch(PDO::FETCH_ASSOC)):
        //code for table cells
?>
</tr>
Sign up to request clarification or add additional context in comments.

1 Comment

only if there are exactly 7 days worth of results.
1

I'm going to assume the timetable is output in date order in the query. You should probably include an ORDER BY clause to make sure of that. I also assume that the results may cover more than one week. Lastly I'm going to assume that every single day is represented by a row in the results. If it's not the case, then please show a sample of results which demonstrates the reality (as you will need some extra logic to deal with missing days).

Using those assumptions, it looks like you only need to start a new row when the current day is Monday, and end it when it's Sunday. So...move the row creation inside the if for Mondays, and the ending inside the if for Sundays, e.g.:

<?php if(date('l', strtotime($row['date'])) == 'Monday') { ?>
   <tr class="table-active">
...
<?php if(date('l', strtotime($row['date'])) == 'Sunday') { ?>
  </tr>
...

Also, it looks like you actually output the exact same <td> for each day, and you don't want to output blank tds if it's not the mentioned day (because that will add extra cells you don't need in the row), so the whole loop could be simplified as follows:

while($row = $result->fetch(PDO::FETCH_ASSOC)):
    $timeslot = $row['timeslot'];
    // pass delimiter and string to explode function
    $timeslot_ar = explode(',', $timeslot);
?>        

    //code to display result in table
    <?php if(date('l', strtotime($row['date'])) == 'Monday') { ?>
      <tr class="table-active">
    <?php } ?>

       <td><?= date('d M', strtotime($row['date'])); ?><br/><?= implode("<br/>", $timeslot_ar); ?></td>

    <?php if(date('l', strtotime($row['date'])) == 'Sunday') { ?>
      </tr>
    <?php } ?>
<?php endwhile; ?> 

You can also replace the implode/explode with a simple string replacement function...I'll leave that as an exercise for the reader.

2 Comments

Thank you but this method didn't work either. The columns ended up getting mixed up into one column (Monday) instead of being classified to their respective table headers
I'm guessing that one of my assumptions was wrong then. Can you show (a relevant sample of) the source data, as I requested in case something was not as I had had to assume? I'm guessing some of the days are missing, perhaps. If you want accurate solutions, you need to fully explain the source data.
0

Managed to fix my issue by scraping off the table and using custom div containers.

Code snippet:

<div class="card" style="width: 9rem;display:inline-block">
  <ul class="list-group list-group-flush">
      <center><li class="list-group-item"><b>Monday</b></li></center>
 <?php             
    $sql = "SELECT * FROM timetable where class_id='$class_id' and day='Monday'";
    $stm = $pdo->query($sql);
    $slots = $stm->fetchAll();
    foreach ($slots as $row) {
        $timeslot = $row['timeslot'];
        // pass delimiter and string to explode function
        $timeslot_ar = explode(',', $timeslot);
        echo '<center>'.date('d M', strtotime($row['date'])).'</center>'.'<li class="list-group-item">'.implode("<br/>", $timeslot_ar). '</li>';
    }
    echo "<br/>";   
?>
  </ul>
</div>

Final product

enter image description here

2 Comments

Fix your injection holes! $stmt = $pdo->prepare("SELECT * FROM timetable where class_id=:class_id and day=:day") (no ; required) and then $stmt->execute([ 'class_id' => $class_id, 'day' => 'Monday') This isn't hard and saves you from a whole world of hurt you do not want to visit upon yourself.
<center> is obsolete: developer.mozilla.org/en-US/docs/Web/HTML/Element/center. Use CSS instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.