How to display dynamic data in Bootstrap tabs using PHP and MySQL

In this topic, we will discuss how to display dynamic content in Bootstrap tabs in PHP after fetching data from MySQL database. Tabs are used to display related information in a single page. For example, if you want to display employee details, salary details and leave details of an employee, you can show them in three tabs. Each tab will have a different set of information. By clicking on each tab user can view the details in the tab.

Tabs in PHP and MySQL

In the above screen, there are two tabs, one for the Course and other for the Exam. User can click on each tab and view the details.

We will create an application to display student courses and exam details in tabs. It will display a list of candidates in a html table and for each candidate you can view the courses and exams in two different tabs.

display MySQL table data in tabsFolders and Files

create tabs in PHP

We have created a folder called 'tabs' under 'xampp/htdocs' as I am using XAMPP.

Folder 'cfg' - Keep dbconnect.php to connect to the MySQL database.
Folder 'css' - Keep custom stylesheet in this folder
index.php - it displays list of candidates
course_exam.php - This is the program that displays candidate's course and exam data in the tabs.

Create the tables in MySQL database

Let us create few tables in MySQL database. These tables are for Candidates, Courses, Exams and Courses-Exams assigned to each candidate.

Table1: candidates

This table stores the details of all candidates:

Display data in tabs in php

Table has 4 columns.

  1. candidate_id - primary key and auto incremented
  2. name - Name of the candidate
  3. email_id - email_id of the candidate
  4. registration_dt - date of registration

Table2: courses

This table stores all courses.

Display data in tabs in php example

Table has 2 columns.

  1. course_id - course_id is the primary key and it is auto incremented
  2. course_name - Course Name

Table3: exams

This table stores exam details.

create bootstrap dynamic Tabs in PHP and MySQL

Table has 3 columns.

  1. exam_id - exam_id is the primary key and auto incremented
  2. exam_name - Name of Exam
  3. passing_score - Passing score of the exam

Table4: candidate_courses

This table stores the courses assigned to candidates.

bootstrap tabs example with php code

Table has 5 columns.

  1. id - it is the primary key and auto incremented
  2. candidate_id - candidate_id from candidates table
  3. course_id - course_id from courses table
  4. assigned_dt - date on which course was assigned to a candidate
  5. completion_dt - course completion date

Table5: candidate_exams

This table stores the all exams candidate took.

dynamic tabs in php

Table has 6 columns.

  1. id - primary key and auto incremented
  2. candidate_id - candidate_id from candidates table
  3. exam_id - exam_id from exams table
  4. exam_dt - Date of exam
  5. nof_questions - Number of questions in this exam
  6. correct_answers - Number of questions correctly answered by the candidate

MySQL create tables scripts with insert statements(for test data) are given below. You can also download the source code (see download section later).


CREATE TABLE `courses` (
  `course_id` int(11) NOT NULL,
  `course_name` varchar(200) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `courses` (`course_id`, `course_name`) VALUES
(1, 'Java'),
(2, 'PHP For Beginners'),
(3, 'HTML and CSS'),
(4, 'Learn CodeIgniter');

CREATE TABLE `exams` (
  `exam_id` int(11) NOT NULL,
  `exam_name` varchar(200) NOT NULL,
  `passing_score` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `exams` (`exam_id`, `exam_name`, `passing_score`) VALUES
(1, 'Java Test', 70),
(2, 'PHP Test', 85),
(3, 'HTML and CSS', 80),
(4, 'CodeIgniter Test', 80);

CREATE TABLE `candidates` (
  `candidate_id` int(11) NOT NULL,
  `name` varchar(100) NOT NULL,
  `email_id` varchar(200) NOT NULL,
  `registration_dt` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `candidates` (`candidate_id`, `name`, `email_id`, `registration_dt`) VALUES
(1, 'John Cullen', 's123@yahoo1.com', '2021-05-20'),
(2, 'Lawrence K', 'sl@gmail1.com', '2021-10-09'),
(3, 'Anant Kumar', 'ak@yahoo1.com', '2021-12-10'),
(4, 'Daniel Kurt', 'daniel@test.com', '2021-11-26');

CREATE TABLE `candidate_courses` (
  `id` int(11) NOT NULL,
  `candidate_id` int(11) NOT NULL,
  `course_id` int(11) NOT NULL,
  `assigned_dt` date NOT NULL,
  `completion_dt` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `candidate_courses` (`id`, `candidate_id`, `course_id`, `assigned_dt`, `completion_dt`) VALUES
(1, 1, 2, '2021-05-26', '2021-06-09'),
(2, 1, 3, '2021-06-08', '0000-00-00'),
(3, 1, 5, '2021-05-27', '2021-09-23'),
(4, 2, 2, '2021-10-21', '2021-11-17'),
(5, 2, 4, '2021-10-31', '0000-00-00'),
(6, 2, 5, '2021-11-10', '2021-11-23'),
(7, 3, 1, '2021-12-23', '2022-01-19'),
(8, 3, 2, '2021-12-17', '2022-01-20'),
(9, 4, 1, '2021-11-30', '2021-12-23'),
(10, 4, 2, '2021-12-08', '2022-01-20'),
(11, 3, 3, '2021-12-08', '2021-12-31');

CREATE TABLE `candidate_exams` (
  `id` int(11) NOT NULL,
  `candidate_id` int(11) NOT NULL,
  `exam_id` int(11) NOT NULL,
  `exam_dt` date NOT NULL,
  `nof_questions` int(11) NOT NULL,
  `correct_answers` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `candidate_exams` (`id`, `candidate_id`, `exam_id`, `exam_dt`, `nof_questions`, `correct_answers`) VALUES
(1, 1, 2, '2022-01-10', 40, 32),
(2, 1, 3, '2022-01-11', 50, 45),
(3, 3, 2, '2022-01-10', 70, 62),
(4, 3, 3, '2022-01-11', 60, 40),
(5, 2, 4, '2022-02-23', 60, 56),
(6, 2, 2, '2022-02-22', 60, 56),
(7, 4, 2, '2022-01-27', 50, 40),
(8, 4, 1, '2022-02-09', 100, 90);

ALTER TABLE `candidates`
  ADD PRIMARY KEY (`candidate_id`);

ALTER TABLE `candidate_courses`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `candidate_exams`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `courses`
  ADD PRIMARY KEY (`course_id`);

ALTER TABLE `exams`
  ADD PRIMARY KEY (`exam_id`);

ALTER TABLE `candidates`
  MODIFY `candidate_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;

ALTER TABLE `candidate_courses`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=12;

ALTER TABLE `candidate_exams`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9;

ALTER TABLE `courses`
  MODIFY `course_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;

ALTER TABLE `exams`
  MODIFY `exam_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;

Connect to MySQL database (dbconnect.php)

To connect to MySQL database from PHP, use the below scripts:

dbconnect.php


<?php
  $server="localhost";
  $userid="root";
  $pwd="";
  $dbname="test";
  $conn = mysqli_connect($server, $userid, $pwd, $dbname);
//Check connection
if (!$conn) 
  	die("Connection Error: " . mysqli_connect_error());

We are using mysqli_connect() function with the below parameters.

  1. server - localhost
  2. userid - root user
  3. password - no password for the user root
  4. database name - test in our case.

We will just include dbconnect.php to avoid writing in every program. You can read the topic How to connect to MySQL database in PHP using MySQLi and PDO.

Write a program to display list of candidates (index.php)

create Tabs in PHP

Let us assume there is a list of candidates who registered themselves for certain courses and exams. So, we will first display a list of such candidates in an html table by selecting all rows from 'candidates' table. It is a simple page in HTML and PHP that selects all data from candidates table and fetch in a loop and display in a html table. Below is the code for it.

index.php


<?php
include "cfg/dbconnect.php";
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <title>Tab Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<div class="row">
      <div class="col-md-12">
          <h2>List of Candidates</h2>
          <div class="table-responsive">
          <table class="table table-bordered table-hover">
            <thead>
                <tr><th>Candidate Id</th><th>Name</th><th>Email Id</th><th>Registration Date (yyyy-mm-dd)</th><th>Course and Exam</th>
                </tr>
            </thead>
            <?php
            $candidate_sql ="select * from candidates order by candidate_id";
            $candidate_rs = mysqli_query($conn,$candidate_sql);
            if (mysqli_num_rows($candidate_rs) >0) 
            foreach ($candidate_rs as $arr)
              {  ?>                  
               <tr>
                  <td><?php echo $arr['candidate_id']; ?></td>
                  <td><?php echo $arr['name']; ?></td>
                  <td><?php echo $arr['email_id']; ?></td>
                  <td><?php echo $arr['registration_dt'];?></td>
                  <td><a href="course_exam.php?candidate_id=<?php echo $arr['candidate_id']?>&name=<?php echo $arr['name']?>">View Details</a></td>
                </tr>
              <?php }
              else
                  echo '<td colspan = "5"> No Candidates Found</td><tr>'; ?>
          </table>
          </div>          
        </div>
      </div>
    </div>
</body>
</html>

For each candidate, there is a link to view details of exam and courses for the candidate. courses_exam.php program is called for this with parameters as candidate id and name. If you click on view details of any candidates then new page opens with details of courses and exams in separate tabs for the that candidate.

Develop a program to display data in Tabs (course_exam.php)

This is the program that displays course details and exam details of a candidate in separate tabs. You can click on a tab and view the details. Here we will use Bootstrap tabs.

course_exam.php


<!DOCTYPE html>
<html lang="en">
<head>
  <title>Tab Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> 
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
  <link rel="stylesheet" href="css/style.css">
</head>
<body>
<?php
include "cfg/dbconnect.php";
$candidate_id = $name = "";
if (isset($_REQUEST['candidate_id']))
$candidate_id =$_REQUEST['candidate_id'];

if (isset($_REQUEST['name']))
$name = $_REQUEST['name'];
?>
<div class="container">
  <h2>Courses and Exam details of the candidate: <?php echo $name;?></h2>
  <br>
  <!-- Nav tabs -->
  <ul class="nav nav-tabs">
    <li class="nav-item">
      <a class="nav-link active" data-toggle="tab" href="#course"><h3>Course Details</h3></a>
    </li>
    <li class="nav-item">
      <a class="nav-link" data-toggle="tab" href="#exam"><h3>Exam Details</h3></a>
    </li>
  </ul>

  <!-- Tab panes -->
  <div class="tab-content">
    <!-- Course Tab -->
    <div id="course" class="container tab-pane active">
      <table id="table1" name="table1" class="table table-bordered table-hover" style="font-size:13px;">
          <thead>
              <tr><th>Course Name</th><th>Assigned Date</th><th>Completion Date  (yyyy-mm-dd)</th></tr></thead>
          <?php
          $courses_sql ="select a.course_name, b.assigned_dt,b.completion_dt from courses a,candidate_courses b where a.course_id = b.course_id and b.candidate_id = '$candidate_id' order by assigned_dt";
          $courses_rs = mysqli_query($conn,$courses_sql);
          if (mysqli_num_rows($courses_rs) > 0) 
          foreach ($courses_rs as $arr)
            { ?>                  
             <tr>
              <td><?php echo $arr['course_name']; ?></td>
              <td><?php echo $arr['assigned_dt']; ?></td>
              <td><?php echo $arr['completion_dt'];?></td>
            </tr>
          <?php
            }
          else
              echo '<td colspan = "4"> No Courses Found</td><tr>';
            ?>
        </table> 
    </div>
    <!-- Exam Tab -->
    <div id="exam" class="container tab-pane fade">
      <table id="table1" name="table1" class="table table-bordered table-hover" style="font-size:13px;">
          <thead>
              <tr><th>Exam Id</th><th>Exam Name</th><th>Date of Exam  (yyyy-mm-dd)</th><th>Total No of Questions</th><th>Correct Answer</th><th>Score (%)</th></tr></thead>
          <?php
          $exam_sql ="select a.exam_id,a.exam_name, b.exam_dt,b.nof_questions,b.correct_answers from exams a,candidate_exams b where a.exam_id=b.exam_id and b.candidate_id='$candidate_id' order by exam_dt";
          $exam_rs = mysqli_query($conn,$exam_sql);
          if (mysqli_num_rows($exam_rs)>0) 
            foreach ($exam_rs as $arr)
            {  
              $score_per = round($arr['correct_answers']/$arr['nof_questions'],2)*100; ?>
            <tr><td><?php echo $arr['exam_id'];?></td>
              <td><?php echo $arr['exam_name']; ?></td>
              <td><?php echo $arr['exam_dt']; ?></td>
              <td><?php echo $arr['nof_questions']; ?></td>
              <td><?php echo $arr['correct_answers']; ?></td>
              <td><?php echo $score_per;?></td>
              </tr>
          <?php } else
              echo '<td colspan = "4"> No Exam Found</td><tr>';
              ?>
      </table> 
    </div>
    <div class="col-md-12 text-center"><a href="index.php" class="btn btn-primary">Close</a></div>
  </div>
</div>

</body>
</html>

A nav-tab is defined with two nav items. Each item has reference to a unique id (href="#course" and href="#exam"). Then there are two <div>s with tab panes defined with id = "course" and id = "exam".

You can see these two <div>s are defined under tab-content div (line 36). Once this structure is defined, just display the data under two different tabs. Course data is displayed under div with id = "course" and exam data is displayed under div with id = "exam".

Use the below stylesheet - style.css used:

style.css


body{
  font-size: 18px;
}
h2{
  margin-top: 20px;
}
.tab-content {
  background-color: #eef8f0;
  padding : 5px 15px;
  border-top-left-radius: 0;
  border-top-right-radius: 12px;
  border-bottom-left-radius: 12px;
  border-bottom-right-radius: 12px;
}
.nav-tabs>li {
    background: #fff;
}
.nav-tabs .nav-item.show .nav-link, .nav-tabs .nav-link.active {
    color: #000;
    background-color: #eef8f0;
  }
table,th,td {
  margin:auto;
  border-collapse: collapse;
  border:1px solid #000;
  font-size: 18px;
  }
thead {
  background-color: #265159;
  color:#fff;
}

make tabs and data dynamic in phpTest the Application

Check in XAMPP control panel if Apache and MySQL services are running. Run localhost/tabs in the browser. Candidate list page will be displayed. it will show the screen as below:

Dynamic Bootstrap Tabs using PHP and MYSQL

If you click on view details for any candidate, data will be displayed in two tabs. You can view data in each tab by clicking in the tab heading as below:

Load Dynamic Content in Tabs

create tabs with the data from database

Hope, you could develop and test it successfully.

download source code for Tabs in PHP and MySQLDownload Source Code

Download the source code by clicking on the download button below:

create tabs containing different content in HTMLConclusion

In this topic, I have showed how you can use Bootstrap tabs and display dynamic content from database. However, one can use better styles to design and display data so that overall tabs look really nice. There is always scope to improve it. I hope I could explain it properly for your easy understanding.