Handling Dynamic Data Fields using Database Vertical Table Design in PHP Tutorial

In this tutorial, we will tackle Handing Dynamic Data Fileds using Database Vertical Table Design. This idea is very useful for such web applications that handling multiple data. This will prevent multiple columns in your database table. Also, this will help you to store new data fields without making changes in your database table structure.

This tutorial can also help you learn some techniques or ideas for developing a web application. The simple web application that we will make for this tutorial contains a dynamic modal, dynamic confirmation modal, and flash message. The said features can lessen/prevent redundancy when writing your codes.

Getting Started

In this tutorial, we will be using XAMPP as our local web server tp run our PHP Scripts and for our MySQL Database Server.

Also, download and install the following:

Compile all the download libraries in a directory inside your XAMPP's 'htdocs' directory. Then, open your XAMPP's Control Panel and start the Apache and MySQL.

Creating Our Database

Open your PHPMyAdmin i.e. http://localhost/phpmyadmin and create a new database naming dummy_db. Then, navigate to the SQL Tab and copy/paste the mysql script below.

  1.         CREATE TABLE `data_meta` (
  2.           `meta_label` text NOT NULL,
  3.           `meta_field_name` text NOT NULL,
  4.           `type` text NOT NULL
  5.         ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  6.  
  7.         INSERT INTO `data_meta` (`meta_label`, `meta_field_name`, `type`) VALUES
  8.         ('Contact #', 'contact_number', 'Numeric'),
  9.         ('Address', 'address', 'Long Text'),
  10.         ('Sample Details', 'sample_detail1', 'Long Text');
  11.  
  12.         CREATE TABLE `student_list` (
  13.           `id` int(30) NOT NULL,
  14.           `student_code` varchar(50) NOT NULL,
  15.           `firstname` text NOT NULL,
  16.           `middlename` text DEFAULT NULL,
  17.           `lastname` text NOT NULL,
  18.           `date_created` datetime NOT NULL DEFAULT current_timestamp(),
  19.           `date_updated` datetime DEFAULT NULL ON UPDATE current_timestamp()
  20.         ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  21.  
  22.         INSERT INTO `student_list` (`id`, `student_code`, `firstname`, `middlename`, `lastname`, `date_created`, `date_updated`) VALUES
  23.         (1, '6231415', 'John', 'D', 'Smith', '2021-10-09 13:43:38', '2021-10-09 13:46:35');
  24.         CREATE TABLE `student_meta` (
  25.           `student_id` int(30) NOT NULL,
  26.           `meta_field` text NOT NULL,
  27.           `meta_value` text NOT NULL
  28.         ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  29.         INSERT INTO `student_meta` (`student_id`, `meta_field`, `meta_value`) VALUES
  30.         (1, 'contact_number', '09123456798'),
  31.         (1, 'address', 'Sample Address'),
  32.         (1, 'sample_detail1', 'Sample Data only');
  33.  
  34.         ALTER TABLE `student_list`
  35.           ADD PRIMARY KEY (`id`);
  36.  
  37.         ALTER TABLE `student_meta`
  38.           ADD KEY `student_id` (`student_id`);
  39.  
  40.         ALTER TABLE `student_list`
  41.           MODIFY `id` int(30) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
  42.  
  43.         ALTER TABLE `student_meta`
  44.           ADD CONSTRAINT `student_meta_ibfk_1` FOREIGN KEY (`student_id`) REFERENCES `student_list` (`id`) ON DELETE CASCADE;

Creating Our Database Connection

Open a your text editor software such as (sublime, notepad++, or vs code). Create a new PHP file naming connection.php. Then, copy/paste the script below.

  1.         <?php
  2.         $host = "localhost";
  3.         $username = "root";
  4.         $password = "";
  5.         $db_tbl = "dummy_db";
  6.  
  7.         $conn=new mysqli($host,$username,$password,$db_tbl);
  8.         if(!$conn){
  9.             die("Database Connection Failed.". $conn->error);
  10.         }

Creating the custom Javascript File

The code below is the script which contains the javascript/jquery functions for our dynamic modal and confirmation modal. Save this file as script.js. In my case, this file is located inside the js folder where all the javascript file of the libraries are compiled.

  1.         window.uni_modal = function($title = '', $url = '', $size = "") {
  2.             $.ajax({
  3.                 url: $url,
  4.                 error: err => {
  5.                     console.log()
  6.                     alert("An error occured")
  7.                 },
  8.                 success: function(resp) {
  9.                     if (resp) {
  10.                         $('#uni_modal .modal-title').html($title)
  11.                         $('#uni_modal .modal-body').html(resp)
  12.                         $('#uni_modal .modal-dialog').removeClass('large')
  13.                         $('#uni_modal .modal-dialog').removeClass('mid-large')
  14.                         $('#uni_modal .modal-dialog').removeClass('modal-md')
  15.                         if ($size == '') {
  16.                             $('#uni_modal .modal-dialog').addClass('modal-md')
  17.                         } else {
  18.                             $('#uni_modal .modal-dialog').addClass($size)
  19.                         }
  20.                         $('#uni_modal').modal({
  21.                             backdrop: 'static',
  22.                             keyboard: true,
  23.                             focus: true
  24.                         })
  25.                         $('#uni_modal').modal('show')
  26.                     }
  27.                 }
  28.             })
  29.         }
  30.         window._conf = function($msg = '', $func = '', $params = []) {
  31.             $('#confirm_modal #confirm').attr('onclick', $func + "(" + $params.join(',') + ")")
  32.             $('#confirm_modal .modal-body').html($msg)
  33.             $('#confirm_modal').modal('show')
  34.         }

Creating the Interfaces

The PHP File scripts below are the codes for the pages in our simple web application. Save the files according the filename above each scripts.

index.php

This is the file for our web application template. This contains the html scripts for our web application document.

  1.         <?php
  2.         session_start();
  3.         require_once('connection.php');
  4.         $page = isset($_GET['page']) ? $_GET['page'] : 'student';
  5.         ?>
  6.         <!DOCTYPE html>
  7.         <html lang="en">
  8.         <head>
  9.             <meta charset="UTF-8">
  10.             <meta http-equiv="X-UA-Compatible" content="IE=edge">
  11.             <meta name="viewport" content="width=device-width, initial-scale=1.0">
  12.             <title>Dynamic Data</title>
  13.             <link rel="stylesheet" href="./css/bootstrap.min.css">
  14.             <script src="./js/jquery-3.6.0.min.js"></script>
  15.             <script src="./js/popper.min.js"></script>
  16.             <script src="./js/bootstrap.min.js"></script>
  17.             <script src="./js/script.js"></script>
  18.             <style>
  19.                 .modal-dialog.large {
  20.                     width: 80% !important;
  21.                     max-width: unset;
  22.                 }
  23.                 .modal-dialog.mid-large {
  24.                     width: 50% !important;
  25.                     max-width: unset;
  26.                 }
  27.                 @media (max-width:720px){
  28.                    
  29.                     .modal-dialog.large {
  30.                         width: 100% !important;
  31.                         max-width: unset;
  32.                     }
  33.                     .modal-dialog.mid-large {
  34.                         width: 100% !important;
  35.                         max-width: unset;
  36.                     }  
  37.                
  38.                 }
  39.             </style>
  40.         </head>
  41.         <body class="bg-light">
  42.             <main>
  43.             <nav class="navbar navbar-expand-lg navbar-dark bg-primary bg-gradient" id="topNavBar">
  44.                 <div class="container">
  45.                     <a class="navbar-brand" href="./">
  46.                        Sourcecodester
  47.                     </a>
  48.                     <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
  49.                     <span class="navbar-toggler-icon"></span>
  50.                     </button>
  51.                     <div class="collapse navbar-collapse" id="navbarNav">
  52.                         <ul class="navbar-nav">
  53.                             <li class="nav-item">
  54.                                 <a class="nav-link <?php echo ($page == 'student')? 'active' : '' ?>" aria-current="page" href="./"><i class="fa fa-user-friends"></i> Student List</a>
  55.                             </li>
  56.                             <li class="nav-item">
  57.                                 <a class="nav-link <?php echo ($page == 'settings')? 'active' : '' ?>" aria-current="page" href="./?page=settings"><i class="fa fa-cogs"></i> Settings</a>
  58.                             </li>
  59.                         </ul>
  60.                     </div>
  61.                 </div>
  62.             </nav>
  63.             <div class="container py-5 mb-4">
  64.                 <h3>Dynamic Data using Vertical Database Table Design</h3>
  65.                 <hr>
  66.                 <?php
  67.                     if(isset($_SESSION['flashdata'])):
  68.                 ?>
  69.                 <div class="alert alert-<?php echo $_SESSION['flashdata']['type'] ?>">
  70.                 <div class="w-100 d-flex">
  71.                     <p class="col-auto flex-grow-1 m-0"><?php echo $_SESSION['flashdata']['msg'] ?></p>
  72.                     <div class="col-auto">
  73.                         <button class="btn-close" onclick="$(this).closest('.alert').remove()"></button>
  74.                     </div>
  75.                 </div>
  76.                 </div>
  77.                 <?php
  78.                     unset($_SESSION['flashdata']);
  79.                     endif;
  80.                 ?>
  81.                 <?php include($page.'.php') ?>
  82.             </div>
  83.             </main>
  84.             <!-- Universal Modal -->
  85.             <div class="modal fade" id="uni_modal" role='dialog' data-bs-backdrop="static" data-bs-keyboard="true">
  86.                 <div class="modal-dialog modal-md modal-dialog-centered" role="document">
  87.                     <div class="modal-content">
  88.                         <div class="modal-header py-2">
  89.                             <h5 class="modal-title"></h5>
  90.                         </div>
  91.                         <div class="modal-body pb-0 mb-0">
  92.                         </div>
  93.                     </div>
  94.                 </div>
  95.             </div>
  96.             <!-- Universal Modal End -->
  97.  
  98.             <!-- Confirmation Modal End -->
  99.             <div class="modal fade" id="confirm_modal" role='dialog'>
  100.                 <div class="modal-dialog modal-md modal-dialog-centered" role="document">
  101.                 <div class="modal-content rounded-0">
  102.                     <div class="modal-header py-2">
  103.                     <h5 class="modal-title">Confirmation</h5>
  104.                 </div>
  105.                 <div class="modal-body">
  106.                     <div id="delete_content"></div>
  107.                 </div>
  108.                 <div class="modal-footer py-1">
  109.                     <button type="button" class="btn btn-primary btn-sm rounded-0" id='confirm' onclick="">Continue</button>
  110.                     <button type="button" class="btn btn-secondary btn-sm rounded-0" data-bs-dismiss="modal">Close</button>
  111.                 </div>
  112.                 </div>
  113.                 </div>
  114.             </div>
  115.             <!-- Confirmation Modal End -->
  116.  
  117.         </body>
  118.         </html>
student.php

This file contains the PHP and HTML scripts of the students list page.

  1.         <div class="col-md-12" id="">
  2.             <div class="w-100 my-2 d-flex">
  3.                 <h4 class="col-auto flex-grow-1"><b>Student List</b></h4>
  4.                 <div class="col-auto">
  5.                     <a href="./?page=manage_student" class="btn btn-sm btn-primary rounded-0">Add New</a>
  6.                 </div>
  7.             </div>
  8.             <hr>
  9.             <div class="col-12">
  10.             <table class="table table-striped table-hover">
  11.                 <thead>
  12.                     <tr class="bg-dark text-light">
  13.                         <th class="py-1 px-2">#</th>
  14.                         <th class="py-1 px-2">Date Created</th>
  15.                         <th class="py-1 px-2">Stundet Code</th>
  16.                         <th class="py-1 px-2">Student Name</th>
  17.                         <th class="py-1 px-2">Date Updated</th>
  18.                         <th class="py-1 px-2">Action</th>
  19.                     </tr>
  20.                 </thead>
  21.                 <tbody>
  22.                     <?php
  23.                     $i = 1;
  24.                     $students = $conn->query("SELECT *,CONCAT(lastname, ', ', firstname, ' ', middlename) as fullname FROM `student_list` order by fullname asc ");
  25.                     while($row= $students->fetch_assoc()):
  26.                     ?>
  27.                     <tr>
  28.                         <td class="py-1 px-2 text-center"><?php echo $i++ ?></td>
  29.                         <td class="py-1 px-2"><?php echo date("Y-m-d H:i",strtotime($row['date_created'])) ?></td>
  30.                         <td class="py-1 px-2"><?php echo $row['student_code'] ?></td>
  31.                         <td class="py-1 px-2"><?php echo ucwords($row['fullname']) ?></td>
  32.                         <td class="py-1 px-2"><?php echo ($row['date_updated'] != null || !empty($row['date_updated'])) ? date('Y-m-d H:i',strtotime($row['date_created'])) : "N/A" ?></td>
  33.                         <td class="py-1 px-2">
  34.                         <div class="dropstart">
  35.                             <button class="btn btn-primary btn-sm rounded-0 dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
  36.                                 Action
  37.                             </button>
  38.                                 <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
  39.                                     <li><a class="dropdown-item view_data" href="javascript:void(0)" data-id="<?php echo $row['id']  ?>">View</a></li>
  40.                                     <li><a class="dropdown-item" href=".?page=manage_student&id=<?php echo $row['id'] ?>">Edit</a></li>
  41.                                     <li><a class="dropdown-item delete_data" href="javascript:void(0)" data-id="<?php echo $row['id']  ?>" data-name="<?php echo $row['student_code']." - ".$row['fullname']  ?>">Delete</a></li>
  42.                                 </ul>
  43.                             </div>
  44.                         </td>
  45.                     </tr>
  46.                     <?php endwhile; ?>
  47.                     <?php if($students->num_rows <= 0): ?>
  48.                         <tr>
  49.                             <th class="py-1 px-2 text-center" colspan='6'>No Data to Display</th>
  50.                         </tr>
  51.                     <?php endif; ?>
  52.                 </tbody>
  53.             </table>
  54.             </div>
  55.         </div>
  56.         <script>
  57.             $(function(){
  58.                 // View Student Details Form Modal
  59.                 $('.view_data').click(function(){
  60.                     uni_modal('Student Details','view_data.php?id='+$(this).attr('data-id'),"large")
  61.                 })
  62.                
  63.                 // Delete Student Form Modal
  64.                 $('.delete_data').click(function(){
  65.                     _conf("Are you sure to delete <b>"+$(this).attr('data-name')+"</b>?", "delete_data",["'"+$(this).attr('data-id')+"'"]);
  66.                 })
  67.             })
  68.             function delete_data($id){
  69.                 $('#confirm_modal button').attr('disabled',true)
  70.                 $.ajax({
  71.                     url:'api.php?action=delete_student',
  72.                     method:'POST',
  73.                     data:{id:$id},
  74.                     dataType:'JSON',
  75.                     error:err=>{
  76.                         console.log(err)
  77.                         alert("An error occurred.")
  78.                         $('#confirm_modal button').attr('disabled',false)
  79.                     },
  80.                     success:function(resp){
  81.                         if(resp.status == 'success'){
  82.                             location.reload()
  83.                         }else{
  84.                             alert("An error occurred.")
  85.                             $('#confirm_modal button').attr('disabled',false)
  86.                         }
  87.                     }
  88.                 })
  89.             }
  90.         </script>
manage_student.php

This file contains the codes/script for the student form.

  1.         <?php
  2.         require_once('connection.php');
  3.         if(isset($_GET['id'])){
  4.             $qry= $conn->query("SELECT * FROM student_list where id = '{$_GET['id']}' ");
  5.             foreach($qry->fetch_array() as $k => $v){
  6.                 $$k = $v;
  7.             }
  8.             if(isset($id)){
  9.                 $qry2 = $conn->query("SELECT * from student_meta where student_id = '{$id}'");
  10.                 while($row = $qry2->fetch_assoc()){
  11.                     $meta[$row['meta_field']] = $row['meta_value'];
  12.                 }
  13.             }
  14.         }
  15.         $mdata = $conn->query("SELECT * FROM data_meta ");
  16.         while($row = $mdata->fetch_assoc()){
  17.             $fields[] = $row;
  18.         }
  19.         ?>
  20.         <div class="container-fluid">
  21.  
  22.             <form action="" id="student-form">
  23.                 <input type="hidden" name="id" value="<?php echo isset($id) ? $id : '' ?>">
  24.                 <div class="col-md-12">
  25.                     <div class="row gy-2 gx-5 row-cols-1 row-cols-sm-1 row-cols-xl-2 row-cols-md-2">
  26.                         <div class="col">
  27.                             <div class="form-group">
  28.                                 <label for="student_code" class="control-label">Student Code</label>
  29.                                 <input type="text" id="student_code" name="student_code" class="form-control form-control-sm rounded-0" value="<?php echo isset($student_code) ? $student_code : '' ?>" required>
  30.                             </div>
  31.                         </div>
  32.                         <div class="col"></div>
  33.                         <div class="col">
  34.                             <div class="form-group">
  35.                                 <label for="firstname" class="control-label">First Name</label>
  36.                                 <input type="text" id="firstname" name="firstname" class="form-control form-control-sm rounded-0" value="<?php echo isset($firstname) ? $firstname : '' ?>" required>
  37.                             </div>
  38.                         </div>
  39.                         <div class="col">
  40.                             <div class="form-group">
  41.                                 <label for="middlename" class="control-label">Middle Name</label>
  42.                                 <input type="text" id="middlename" name="middlename" class="form-control form-control-sm rounded-0" value="<?php echo isset($middlename) ? $middlename : '' ?>" placeholder="optional">
  43.                             </div>
  44.                         </div>
  45.                         <div class="col">
  46.                             <div class="form-group">
  47.                                 <label for="lastname" class="control-label">Last Name</label>
  48.                                 <input type="text" id="lastname" name="lastname" class="form-control form-control-sm rounded-0" value="<?php echo isset($lastname) ? $lastname : '' ?>" required>
  49.                             </div>
  50.                         </div>
  51.  
  52.                         <?php if(isset($fields)): ?>
  53.                         <?php foreach($fields as $field): ?>
  54.                             <div class="col">
  55.                                 <div class="form-group">
  56.                                     <label for="<?php echo $field['meta_field_name'] ?>" class="control-label"><?php echo $field['meta_label'] ?></label>
  57.                                     <?php if($field['type'] == 'Text'): ?>
  58.                                         <input type="text" id="<?php echo $field['meta_field_name'] ?>" name="<?php echo $field['meta_field_name'] ?>" class="form-control form-control-sm rounded-0" value="<?php echo isset($meta[$field['meta_field_name']]) ? $meta[$field['meta_field_name']] : '' ?>" required>
  59.                                     <?php elseif($field['type'] == 'Numeric'): ?>
  60.                                         <input type="number" id="<?php echo $field['meta_field_name'] ?>" name="<?php echo $field['meta_field_name'] ?>" class="form-control form-control-sm rounded-0" value="<?php echo isset($meta[$field['meta_field_name']]) ? $meta[$field['meta_field_name']] : '' ?>" required>
  61.                                     <?php else: ?>
  62.                                         <textarea rows="3" id="<?php echo $field['meta_field_name'] ?>" name="<?php echo $field['meta_field_name'] ?>" style="resize:none" class="form-control form-control-sm rounded-0"><?php echo isset($meta[$field['meta_field_name']]) ? $meta[$field['meta_field_name']] : '' ?></textarea>
  63.                                     <?php endif; ?>
  64.                                 </div>
  65.                             </div>
  66.                         <?php endforeach; ?>
  67.                         <?php endif; ?>
  68.                     </div>
  69.                 </div>
  70.                 <div class="col-12 py-2">
  71.                     <div class="w-100 d-flex justify-content-center">
  72.                             <button class="btn btn-sm btn-primary rounded-0 me-2">Save</button>
  73.                             <a href="./?page=student" class="btn btn-sm btn-dark rounded-0">Back</a>
  74.                     </div>
  75.                 </div>
  76.             </form>
  77.  
  78.         </div>
  79.         <script>
  80.             $(function(){
  81.                 $('#student-form').submit(function(e){
  82.                     e.preventDefault()
  83.                     var _this = $(this)
  84.                     _this.find('button').attr('disabled',true)
  85.                     $('.pop_msg').remove()
  86.                     $.ajax({
  87.                         url:'api.php?action=save_student',
  88.                         method:'POST',
  89.                         data:_this.serialize(),
  90.                         dataType:'json',
  91.                         error:err=>{
  92.                             console.log(err)
  93.                             alert('an error occured')
  94.                             _this.find('button').attr('disabled',false)
  95.                         },
  96.                         success:function(resp){
  97.                             if(resp.status == 'success'){
  98.                                 location.replace('./')
  99.                             }else if(resp.status == 'failed' && !!resp.msg){
  100.                                 var el = $('<div>')
  101.                                     el.addClass('pop_msg alert alert-danger')
  102.                                     .css('display','none')
  103.                                     .text(resp.msg)
  104.                                     _this.prepend(el)
  105.                                     el.show('slow')
  106.                             }else{
  107.                                 console.log(resp)
  108.                                 alert('an error occured')
  109.                             }
  110.                             _this.find('button').attr('disabled',false)
  111.                         }
  112.                     })
  113.                 })
  114.             })
  115.         </script>
view_data.php

This file contains the script of the student data modal.

  1.         <?php
  2.         require_once('connection.php');
  3.         if(isset($_GET['id'])){
  4.         $qry= $conn->query("SELECT *,CONCAT(lastname, ', ', firstname, ' ', middlename) as fullname FROM student_list where id = '{$_GET['id']}' ");
  5.             foreach($qry->fetch_array() as $k => $v){
  6.                 $$k = $v;
  7.             }
  8.             if(isset($id)){
  9.                 $qry2 = $conn->query("SELECT * from student_meta where student_id = '{$id}'");
  10.                 while($row = $qry2->fetch_assoc()){
  11.                     $meta[$row['meta_field']] = $row['meta_value'];
  12.                 }
  13.             }
  14.         }
  15.         $mdata = $conn->query("SELECT * FROM data_meta ");
  16.         while($row = $mdata->fetch_assoc()){
  17.             $fields[] = $row;
  18.         }
  19.         ?>
  20.  
  21.         <div class="container-fuid">
  22.             <div class="col-12">
  23.                 <div class="row gy-2 gx-5 row-cols-1 row-cols-sm-1 row-cols-xl-2 row-cols-md-2">
  24.                     <div class="col">
  25.                         <div class="text-muted">Student Code:</div>
  26.                         <div class="lh-1 fs-6"><?php echo $student_code ?></div>
  27.                     </div>
  28.                     <div class="col">
  29.                         <div class="text-muted">Student Name:</div>
  30.                         <div class="lh-1 fs-6"><?php echo ucwords($fullname) ?></div>
  31.                     </div>
  32.                     <div class="col">
  33.                         <div class="text-muted">Student Code:</div>
  34.                         <div class="lh-1 fs-6"><?php echo $student_code ?></div>
  35.                     </div>
  36.                     <?php if(isset($fields)): ?>
  37.                     <?php foreach($fields as $field): ?>
  38.                     <div class="col">
  39.                         <div class="text-muted"><?php echo $field['meta_label'] ?>:</div>
  40.                         <p class="lh-1 fs-6"><?php echo isset($meta[$field['meta_field_name']]) ? $meta[$field['meta_field_name']] : '' ?></p>
  41.                     </div>
  42.                     <?php endforeach; ?>
  43.                     <?php endif; ?>
  44.                 </div>
  45.             </div>
  46.         </div>
  47.  
  48.         <div class="row justify-content-end mx-0 my-2">
  49.             <div class="col-auto">
  50.                 <button class="btn btn-sm btn-dark rounded-0" data-bs-dismiss="modal">Close</button>
  51.             </div>
  52.         </div>
settings.php

This file contains the list of dynamic data fields in our database table.

  1.         <div class="col-lg-12">
  2.             <div class="w-100 my-2 d-flex">
  3.                 <h4 class="col-auto flex-grow-1"><b>Dynamic Data Fields</b></h4>
  4.                 <div class="col-auto">
  5.                     <a href="javascript:void(0)" id="add_new" class="btn btn-sm btn-primary rounded-0">Add New</a>
  6.                 </div>
  7.             </div>
  8.             <table class="table table-striped table-hover">
  9.                 <thead>
  10.                     <tr class="bg-dark text-light">
  11.                         <th class="py-1 px-2">#</th>
  12.                         <th class="py-1 px-2">Field Label</th>
  13.                         <th class="py-1 px-2">Field Name</th>
  14.                         <th class="py-1 px-2">Type</th>
  15.                         <th class="py-1 px-2">Action</th>
  16.                     </tr>
  17.                 </thead>
  18.                 <tbody>
  19.                     <?php
  20.                     $i = 1;
  21.                     $students = $conn->query("SELECT * FROM `data_meta` ");
  22.                     while($row= $students->fetch_assoc()):
  23.                     ?>
  24.                     <tr>
  25.                         <td class="py-1 px-2 text-center"><?php echo $i++ ?></td>
  26.                         <td class="py-1 px-2"><?php echo $row['meta_label'] ?></td>
  27.                         <td class="py-1 px-2"><?php echo $row['meta_field_name'] ?></td>
  28.                         <td class="py-1 px-2"><?php echo $row['type'] ?></td>
  29.                         <td class="py-1 px-2">
  30.                         <div class="dropdown">
  31.                             <button class="btn btn-primary btn-sm rounded-0 dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
  32.                                 Action
  33.                             </button>
  34.                                 <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
  35.                                     <li><a class="dropdown-item edit_data" href="javascript:void(0)" data-meta_field_name="<?php echo $row['meta_field_name']  ?>">Edit</a></li>
  36.                                     <li><a class="dropdown-item delete_data" href="javascript:void(0)" data-meta_field_name="<?php echo $row['meta_field_name']  ?>">Delete</a></li>
  37.                                 </ul>
  38.                             </div>
  39.                         </td>
  40.                     </tr>
  41.                     <?php endwhile; ?>
  42.                     <?php if($students->num_rows <= 0): ?>
  43.                         <tr>
  44.                             <th class="py-1 px-2 text-center" colspan='5'>No Data to Display</th>
  45.                         </tr>
  46.                     <?php endif; ?>
  47.                 </tbody>
  48.             </table>
  49.         </div>
  50.         <script>
  51.             $(function(){
  52.                 // Add New Data Form Modal
  53.                 $('#add_new').click(function(){
  54.                     uni_modal("Add New Data Field", "manage_field.php");
  55.                 })
  56.                 // Edit Data Form Modal
  57.                 $('.edit_data').click(function(){
  58.                     uni_modal("Edit Data Field", "manage_field.php?meta_field_name="+$(this).attr('data-meta_field_name'));
  59.                 })
  60.                 // Delete Data Form Modal
  61.                 $('.delete_data').click(function(){
  62.                     _conf("Are you sure to delete <b>"+$(this).attr('data-meta_field_name')+"</b>?", "delete_data",["'"+$(this).attr('data-meta_field_name')+"'"]);
  63.                 })
  64.             })
  65.             function delete_data($meta_field_name){
  66.                 $('#confirm_modal button').attr('disabled',true)
  67.                 $.ajax({
  68.                     url:'api.php?action=delete_field',
  69.                     method:'POST',
  70.                     data:{meta_field_name:$meta_field_name},
  71.                     dataType:'JSON',
  72.                     error:err=>{
  73.                         consolre.log(err)
  74.                         alert("An error occurred.")
  75.                         $('#confirm_modal button').attr('disabled',false)
  76.                     },
  77.                     success:function(resp){
  78.                         if(resp.status == 'success'){
  79.                             location.reload()
  80.                         }else{
  81.                             alert("An error occurred.")
  82.                             $('#confirm_modal button').attr('disabled',false)
  83.                         }
  84.                     }
  85.                 })
  86.             }
  87.         </script>
manage_field.php

This file is the script for the dynamic data field form modal.

  1.         <?php
  2.         require_once('connection.php');
  3.         if(isset($_GET['meta_field_name'])){
  4.             $qry= $conn->query("SELECT * FROM data_meta where meta_field_name = '{$_GET['meta_field_name']}' ");
  5.             foreach($qry->fetch_array() as $k => $v){
  6.                 $$k = $v;
  7.             }
  8.         }
  9.         ?>
  10.         <div class="container-fluid">
  11.             <form action="" id="field-form">
  12.                 <input type="hidden" name="o_field_name" value="<?php echo isset($meta_field_name)? $meta_field_name : "" ?>">
  13.                 <div class="form-group">
  14.                     <label for="meta_label" class="control-label">Label</label>
  15.                     <input type="text" id="meta_label" name="meta_label" class="form-control form-control-sm rounded-0" value="<?php echo isset($meta_label) ? $meta_label : '' ?>" required>
  16.                 </div>
  17.                 <div class="form-group">
  18.                     <label for="meta_field_name" class="control-label">Field Name</label>
  19.                     <input type="text" id="meta_field_name" name="meta_field_name" class="form-control form-control-sm rounded-0" pattern="[a-z0-9A-Z_]+" value="<?php echo isset($meta_field_name) ? $meta_field_name : '' ?>" required>
  20.                     <small class="text-info">(Accepted Characters: A-Z, a-z, '_' )</small>
  21.                 </div>
  22.                 <div class="form-group">
  23.                     <label for="type" class="control-label">Field Type</label>
  24.                     <select name="type" id="type" class="form-select form-select-sm rounded">
  25.                         <option <?php echo isset($type) && $type == 'Text' ? 'selected' : '' ?>>Text</option>
  26.                         <option <?php echo isset($type) && $type == 'Long Text' ? 'selected' : '' ?>>Long Text</option>
  27.                         <option <?php echo isset($type) && $type == 'Numeric' ? 'selected' : '' ?>>Numeric</option>
  28.                     </select>
  29.                 </div>
  30.             </form>
  31.         </div>
  32.         <div class="row justify-content-end mx-0 my-2">
  33.             <div class="col-auto">
  34.                 <button class="btn btn-sm btn-primary rounded-0 me-2" form="field-form">Save</button>
  35.                 <button class="btn btn-sm btn-dark rounded-0" data-bs-dismiss="modal">Close</button>
  36.             </div>
  37.         </div>
  38.         <script>
  39.             $(function(){
  40.                 $('#field-form').submit(function(e){
  41.                     e.preventDefault()
  42.                     var _this = $(this)
  43.                     _this.find('button').attr('disabled',true)
  44.                     $('.pop_msg').remove()
  45.                     $.ajax({
  46.                         url:'api.php?action=save_field',
  47.                         method:'POST',
  48.                         data:_this.serialize(),
  49.                         dataType:'json',
  50.                         error:err=>{
  51.                             console.log(err)
  52.                             alert('an error occured')
  53.                             _this.find('button').attr('disabled',false)
  54.                         },
  55.                         success:function(resp){
  56.                             if(resp.status == 'success'){
  57.                                 location.reload()
  58.                             }else if(resp.status == 'failed' && !!resp.msg){
  59.                                 var el = $('<div>')
  60.                                     el.addClass('pop_msg alert alert-danger')
  61.                                     .css('display','none')
  62.                                     .text(resp.msg)
  63.                                     _this.prepend(el)
  64.                                     el.show('slow')
  65.                             }else{
  66.                                 console.log(resp)
  67.                                 alert('an error occured')
  68.                             }
  69.                             _this.find('button').attr('disabled',false)
  70.                         }
  71.                     })
  72.                 })
  73.             })
  74.         </script>

Creating our PHP API

The script below is the file that contains our PHP API which queries (Insert, Update, and Delete) data in our database. Save this PHP File as api.php.

  1.         <?php
  2.         session_start();
  3.         require_once('connection.php');
  4.         $action = isset($_GET['action']) ? $_GET['action'] : '';
  5.         if($_SERVER['REQUEST_METHOD'] == 'POST'){
  6.             // Extracting Post data to varialbles
  7.             extract($_POST);
  8.         }
  9.         if(empty($action)){
  10.             $resp['status'] ='failed';
  11.             $resp['msg'] = 'Unknown Action';
  12.         }
  13.         elseif($action == 'save_field'){
  14.             $data = "";
  15.             $check = $conn->query("SELECT * FROM `data_meta` where meta_field_name = '{$meta_field_name}' ".(!empty($o_field_name)? " and meta_field_name != '{$o_field_name}'" : '' ))->num_rows;
  16.             if($check > 0){
  17.                 $resp['status'] ='failed';
  18.                 $resp['msg'] ='Field Name Already Exists.';
  19.             }else{
  20.                 if(empty($o_field_name)){
  21.                     $sql = "INSERT INTO `data_meta` (meta_label,meta_field_name,`type`) VALUES ('{$meta_label}','{$meta_field_name}','{$type}')";
  22.                 }else{
  23.                     $sql = "UPDATE `data_meta` set `meta_label` = '{$meta_label}', `meta_field_name` = '{$meta_field_name}', `type` = '{$type}' where `meta_field_name` = '{$o_field_name}'";
  24.                     $sql2 = "UPDATE `student_meta` set `meta_field` = '{$meta_field_name}' where `meta_field` = '{$o_field_name}'";
  25.                 }
  26.                 $save = $conn->query($sql);
  27.                 if(isset($sql2))
  28.                     $conn->query($sql2);
  29.                 if($save){
  30.                     $resp['status'] = 'success';
  31.                     $_SESSION['flashdata']['type'] = 'success';
  32.                     $_SESSION['flashdata']['msg'] = 'Field Successfuly Saved';
  33.                 }else{
  34.                     $resp['status'] = 'failed';
  35.                     $resp['msg'] = 'Failed to saved data. Error: '.$conn->error;
  36.                 }
  37.             }
  38.         }
  39.         elseif($action == 'delete_field'){
  40.             $delete = $conn->query("DELETE FROM `data_meta` where meta_field_name = '{$meta_field_name}'");
  41.             if($delete){
  42.                 $resp['status'] = 'success';
  43.                 $_SESSION['flashdata']['type'] = 'success';
  44.                 $_SESSION['flashdata']['msg'] = 'Data Field successfully deleted.';
  45.             }else{
  46.                 $resp['status'] = 'failed';
  47.                 $resp['msg'] = 'Error: '.$conn->error;
  48.             }
  49.         }
  50.         elseif($action == 'save_student'){
  51.             // static data
  52.             $static = array('id','student_code','firstname','lastname','middlename');
  53.             $data = "";
  54.            
  55.             $check = $conn->query("SELECT * FROM `student_list` where student_code = '{$student_code}' ".(!empty($id)? " and id != '{$id}'" : '' ))->num_rows;
  56.             if($check > 0){
  57.                 $resp['status'] ='failed';
  58.                 $resp['msg'] ='Student Code Already Exists.';
  59.             }else{
  60.             // dynamically set data to insert or update
  61.                 foreach($_POST as $k =>$v){
  62.                     if(!in_array($k,$static) || $k =='id')
  63.                     continue;
  64.                     $v= $conn->real_escape_string($v);
  65.                     if(!empty($data)) $data .=", ";
  66.                     $data .= " `$k` = '{$v}' ";
  67.                 }
  68.                 if(empty($id)){
  69.                     $sql = "INSERT INTO `student_list` set {$data}";
  70.                 }else{
  71.                     $sql = "UPDATE `student_list` set {$data} where id = '{$id}'";
  72.                 }
  73.                 $save = $conn->query($sql);
  74.                 if($save){
  75.                     $student_id = empty($id) ? $conn->insert_id : $id;
  76.                     $data = "";
  77.                     $resp['status'] ='success';
  78.                     $_SESSION['flashdata']['type'] = 'success';
  79.                     $_SESSION['flashdata']['msg'] = 'Student Data Successfuly Saved';
  80.  
  81.                     // setting the dynamic data for insertion
  82.                     foreach($_POST as $k =>$v){
  83.                         if(in_array($k,$static))
  84.                         continue;
  85.                         $v= $conn->real_escape_string($v);
  86.                         if(!empty($data)) $data .=", ";
  87.                         $data .= " ('{$student_id}','{$k}', '{$v}' )";
  88.                     }
  89.                     if(!empty($data)){
  90.                         // Deleting the old dynamic data
  91.                         $conn->query("DELETE FROM student_meta where student_id = '{$student_id}'");
  92.                         // Inserting Updated dynamic Data
  93.                         $conn->query("INSERT INTO student_meta (`student_id`,`meta_field`,`meta_value`) VALUES {$data} ");
  94.                     }
  95.                    
  96.                 }else{
  97.                     $resp['status'] = 'failed';
  98.                     $resp['msg'] = 'Failed to saved data. Error: '.$conn->error;
  99.                 }
  100.             }
  101.         }
  102.         elseif($action == 'delete_student'){
  103.             $delete = $conn->query("DELETE FROM `student_list` where id = '{$id}'");
  104.             if($delete){
  105.                 $resp['status'] = 'success';
  106.                 $_SESSION['flashdata']['type'] = 'success';
  107.                 $_SESSION['flashdata']['msg'] = 'Data Field successfully deleted.';
  108.             }else{
  109.                 $resp['status'] = 'failed';
  110.                 $resp['msg'] = 'Error: '.$conn->error;
  111.             }
  112.         }
  113.         echo json_encode($resp);

DEMO VIDEO

There you go! You can now test the simple web application we created and see if we've met our goals for this tutorial. If you have encountered any errors, kindly review the scripts I provided above. You can also download the working source code I created for this tutorial.

I hope this PHP, jQuery, Ajax, and MySQL Database Tutorial will help you enhance your programming capabilities and you'll find this useful for your future PHP Projects.

Explore more on this website for more Programming Tutorials and Free Source Codes.

Happy Coding :)

Add new comment