DataTables CRUD Operations with PHP and MySQL

DataTables is a JavaScript library that helps build data tables and instantly add advanced features to HTML tables. In the web application, the DataTables jQuery plugin is the best option to display data in table view with search and pagination features. DataTables server-side processing allows to fetch data from the database and display live data in tabular format. Advanced features such as search, filter, sorting, and pagination can be attached to the data table without extra effort.

CRUD operations are the most used functionality in the data table. The DataTables can be enhanced with CRUD feature to display and manage data in HTML tables. In this tutorial, we will show you how to integrate DataTables CRUD operations with Ajax using PHP and MySQL. You can manage data in DataTables with live add/edit/delete features using jQuery, Ajax, and PHP.

In the example script, we will display dynamic data from the database and add CRUD functionality in DataTables with PHP.

  • Fetch and list data from the MySQL database using DataTables Server-side Processing.
  • Add a new column (Action) and insert hyperlinks (Edit and Delete) to each row in DataTables.
  • Add, edit, and delete table data with popup without page refresh/reload using jQuery and Ajax.

Before getting started to integrate the CRUD feature in DataTables with PHP, take a look at the file structure.

datatables_crud_with_php/
├── config.php
├── dbConnect.php
├── index.html
├── fetchData.php
├── ssp.class.php
├── eventHandler.php
├── DataTables/
│   ├── datatables.min.css
│   └── datatables.min.js
├── js/
│   ├── jquery.min.js
│   ├── bootstrap.min.js
│   ├── sweetalert2.all.min.js
└── css/
    ├── bootstrap.min.css
    └── style.css

Create Database Table

A table is required in the database in which the data will be managed. The following SQL creates a members table with some basic fields in the MySQL database.

CREATE TABLE `members` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `first_name` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
  `last_name` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
  `email` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `gender` enum('Male','Female') COLLATE utf8_unicode_ci NOT NULL,
  `country` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  `created` datetime NOT NULL DEFAULT current_timestamp(),
  `modified` datetime NOT NULL DEFAULT current_timestamp(),
  `status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '1=Active | 0=Inactive',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Configuration (config.php)

In the config.php file, some configuration variables are defined.

<?php 

// Database credentials
define('DB_HOST''MySQL_Database_Host');
define('DB_USER''Database_Username');
define('DB_PASS''Database_Password');
define('DB_NAME''Database_Name');

?>

Database Connection (dbConnect.php)

The dbConnect.php file is used to connect and select the database.

<?php 

// Include config file
include_once 'config.php';

// Connect to the database 
$conn = new mysqli(DB_HOSTDB_USERDB_PASSDB_NAME); 
if(
$conn->connect_error){ 
    die(
"Failed to connect with MySQL: " $conn->connect_error); 
}

?>

Attach DataTables to HTML Table with CRUD Links (index.html)

On page load, the DataTables class is initialized, and dynamic data is fetched from the server side and listed in an HTML table with Add/Edit/Delete buttons.

jQuery Library:
Include the jQuery library that is required to initiate Ajax and build modal popup.

<script src="js/jquery.min.js"></script>

Bootstrap Library:
Include the Bootstrap CSS and JS library files, which will be used to integrate the popup dialog.

<link rel="stylesheet" href="css/bootstrap.min.css">
<script src="js/bootstrap.min.js"></script>

SweetAlert Plugin:
We will use the SweetAlert2 plugin to display alert notification messages on the dialog box.

<script src="js/sweetalert2.all.min.js"></script>

DataTables Library:
Include the DataTables CSS and JS library files.

<link rel="stylesheet" type="text/css" href="DataTables/datatables.min.css"/>
<script type="text/javascript" src="DataTables/datatables.min.js"></script>

HTML Table with Add/Edit/Delete Links:
Create an HTML table structure and specify the column names in <thead> and <tfoot>.

  • Define a selector ID (#dataList) in <table> to attach DataTables.
  • Specify an additional column named “Action” where the Edit and Delete links/buttons will be added.
<!-- Add button -->
<div class="top-panel">
    <a href="javascript:void(0);" class="btn btn-primary" onclick="addData()">Add New User</a>
</div>

<!-- Data list table -->
<table id="dataList" class="display" style="width:100%">
    <thead>
        <tr>
            <th>First name</th>
            <th>Last name</th>
            <th>Email</th>
            <th>Gender</th>
            <th>Country</th>
            <th>Created</th>
            <th>Status</th>
            <th>Action</th>
        </tr>
    </thead>
    <tfoot>
        <tr>
            <th>First name</th>
            <th>Last name</th>
            <th>Email</th>
            <th>Gender</th>
            <th>Country</th>
            <th>Created</th>
            <th>Status</th>
            <th>Action</th>
        </tr>
    </tfoot>
</table>

Add/Edit Modal:
Define HTML to create a modal popup for add and edit operations.

  • For this example, we will create a form to input members’ data (First Name, Last Name, Email, Gender, Country, and Status).
  • On clicking the Add/Edit button, this modal will appear with the form fields.
  • The user can add, edit, and update data through the modal popup form.
  • We will use this same modal form for add and edit operations.
<div class="modal fade" id="userDataModal" tabindex="-1" aria-labelledby="userAddEditModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h1 class="modal-title fs-5" id="userModalLabel">Add New User</h1>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <form name="userDataFrm" id="userDataFrm">
            <div class="modal-body">
                <div class="frm-status"></div>
                <div class="mb-3">
                    <label for="userFirstName" class="form-label">First Name</label>
                    <input type="text" class="form-control" id="userFirstName" placeholder="Enter firstname">
                </div>
                <div class="mb-3">
                    <label for="userLastName" class="form-label">Last Name</label>
                    <input type="text" class="form-control" id="userLastName" placeholder="Enter lastname">
                </div>
                <div class="mb-3">
                    <label for="userEmail" class="form-label">Email address</label>
                    <input type="email" class="form-control" id="userEmail" placeholder="Enter email">
                </div>
                <div class="form-radio">
                    <label>Gender:</label>
                    <input type="radio" name="userGender" id="userGender_1" value="Male" checked> Male 
                    &nbsp;&nbsp; 
                    <input type="radio" name="userGender" id="userGender_2" value="Female"> Female
                </div>
                <div class="mb-3">
                    <label for="userCountry" class="form-label">Country</label>
                    <input type="text" class="form-control" id="userCountry" placeholder="Enter country">
                </div>
                <div class="form-radio">
                    <label>Status:</label>
                    <input type="radio" name="userStatus" id="userStatus_1" value="1" checked> Active &nbsp;&nbsp;
                    <input type="radio" name="userStatus" id="userStatus_2" value="0"> Inactive
                </div>
            </div>
            <div class="modal-footer">
                <input type="hidden" id="userID" value="0">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary" onclick="submitUserData()">Submit</button>
            </div>
            </form>
        </div>
    </div>
</div>

JavaScript: Attach DataTables Plugin to HTML Table
Initialize the DataTables API class using the DataTable() method and configure the table object.

  • To enable server-side processing,
    • Set the processing option to true.
    • Set the serverSide option to true.
  • Specify the server-side script URL (fetchData.php) in the ajax option.
  • Since the custom links are placed in the “Action” column, disable sorting for this column (index count is 7).
    • Use columnDefs option to disable sorting of a specific column.
    • Set orderable to false.
    • Specify column index count from left in targets.

Hold the DataTables object in a variable (table) and use the draw() method to render the table data.

// Initialize DataTables API object and configure table
var table = $('#dataList').DataTable({
    "processing": true,
    "serverSide": true,
    "ajax": "fetchData.php",
    "columnDefs": [
        { "orderable": false, "targets": 7 }
    ]
});

$(document).ready(function(){
    // Draw the table
    table.draw();
});

JavaScript: DataTables Add Request
The addData() function displays a modal popup with form fields.

function addData(){
    $('.frm-status').html('');
    $('#userModalLabel').html('Add New User');

    $('#userGender_1').prop('checked', true);
    $('#userGender_2').prop('checked', false);
    $('#userStatus_1').prop('checked', true);
    $('#userStatus_2').prop('checked', false);
    $('#userFirstName').val('');
    $('#userLastName').val('');
    $('#userEmail').val('');
    $('#userCountry').val('');
    $('#userID').val(0);
    $('#userDataModal').modal('show');
}

JavaScript: DataTables Edit Request
The editData() function displays a modal popup with prefilled form.

function editData(user_data){
    $('.frm-status').html('');
    $('#userModalLabel').html('Edit User #'+user_data.id);

    if(user_data.gender == 'Female'){
        $('#userGender_1').prop('checked', false);
        $('#userGender_2').prop('checked', true);
    }else{
        $('#userGender_2').prop('checked', false);
        $('#userGender_1').prop('checked', true);
    }

    if(user_data.status == 1){ 
        $('#userStatus_2').prop('checked', false);
        $('#userStatus_1').prop('checked', true);
    }else{
        $('#userStatus_1').prop('checked', false);
        $('#userStatus_2').prop('checked', true);
    }

    $('#userFirstName').val(user_data.first_name);
    $('#userLastName').val(user_data.last_name);
    $('#userEmail').val(user_data.email);
    $('#userCountry').val(user_data.country);
    $('#userID').val(user_data.id);
    $('#userDataModal').modal('show');
}

JavaScript: Submit Add/Edit Form Data via Ajax Request
The submitUserData() function is used to submit input data of the modal form.

  • The form data is submitted to the server-side script (eventHandler.php) via Ajax request.
  • Based on the response, the DataTables is reloaded with the updated data.
function submitUserData(){
    $('.frm-status').html('');
    let input_data_arr = [
        document.getElementById('userFirstName').value,
        document.getElementById('userLastName').value,
        document.getElementById('userEmail').value,
        document.querySelector('input[name="userGender"]:checked').value,
        document.getElementById('userCountry').value,
        document.querySelector('input[name="userStatus"]:checked').value,
        document.getElementById('userID').value,
    ];

    fetch("eventHandler.php", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ request_type:'addEditUser', user_data: input_data_arr}),
    })
    .then(response => response.json())
    .then(data => {
        if (data.status == 1) {
            Swal.fire({
                title: data.msg,
                icon: 'success',
            }).then((result) => {
                // Redraw the table
	        table.draw();

                $('#userDataModal').modal('hide');
                $("#userDataFrm")[0].reset();
            });
        } else {
            $('.frm-status').html('<div class="alert alert-danger" role="alert">'+data.error+'</div>');
        }
    })
    .catch(console.error);
}

JavaScript: DataTables Delete Request
The deleteData() function is used to POST delete request to the server-side script (eventHandler.php) via Ajax.

  • The SweetAlert plugin is used to display the confirmation dialog.
  • Based on the response, the DataTables is reloaded with the updated data.
function deleteData(user_id){
    Swal.fire({
        title: 'Are you sure to Delete?',
        text:'You won\'t be able to revert this!',
        icon: 'warning',
        showCancelButton: true,
        confirmButtonColor: '#3085d6',
        cancelButtonColor: '#d33',
        confirmButtonText: 'Yes, delete it!'
      }).then((result) => {
        if (result.isConfirmed) {
          // Delete event
          fetch("eventHandler.php", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ request_type:'deleteUser', user_id: user_id}),
          })
          .then(response => response.json())
          .then(data => {
            if (data.status == 1) {
                Swal.fire({
                    title: data.msg,
                    icon: 'success',
                }).then((result) => {
                    table.draw();
                });
            } else {
              Swal.fire(data.error, '', 'error');
            }
          })
          .catch(console.error);
        } else {
          Swal.close();
        }
    });
}

Server-side Script to Fetch DataTables Data (fetchData.php)

The fetchData.php file performs server-side processing with custom links (edit and delete).

  • To make the SQL query-building process more accessible, we will use the SSP class (ssp.class.php).
  • The simple() function of the SSP class helps to fetch the member’s data from the database based on the mentioned columns using PHP and MySQL.
  • The formatter parameter is used to modify the default format of the data returns for the column.
  • We will define anchor tags (<a>) to add hyperlinks to the column of each row with dynamic ID (primary key ID of the DB data).
    • The editData() functionality is added to the onclick attribute of the Edit anchor. It will trigger the JavaScript method for the edit form popup.
    • The deleteData() functionality is added to the onclick attribute of the Delete anchor. It will trigger the JavaScript method for the delete confirmation dialog.
<?php 
// Include config file
include_once 'config.php';

// Database connection info
$dbDetails = array(
    
'host' => DB_HOST,
    
'user' => DB_USER,
    
'pass' => DB_PASS,
    
'db'   => DB_NAME
);

// DB table to use
$table 'members';

// Table's primary key
$primaryKey 'id';

// Array of database columns which should be read and sent back to DataTables.
// The `db` parameter represents the column name in the database. 
// The `dt` parameter represents the DataTables column identifier.
$columns = array(
    array( 
'db' => 'first_name''dt' => ),
    array( 
'db' => 'last_name',  'dt' => ),
    array( 
'db' => 'email',      'dt' => ),
    array( 
'db' => 'gender',     'dt' => ),
    array( 
'db' => 'country',    'dt' => ),
    array(
        
'db'        => 'created',
        
'dt'        => 5,
        
'formatter' => function( $d$row ) {
            return 
date'jS M Y'strtotime($d));
        }
    ),
    array(
        
'db'        => 'status',
        
'dt'        => 6,
        
'formatter' => function( $d$row ) {
            return (
$d == 1)?'Active':'Inactive';
        }
    ),
    array(
        
'db'        => 'id',
        
'dt'        => 7,
        
'formatter' => function( $d$row ) {
            return 
'
                <a href="javascript:void(0);" class="btn btn-warning" onclick="editData('
.htmlspecialchars(json_encode($row), ENT_QUOTES'UTF-8').')">Edit</a>&nbsp;
                <a href="javascript:void(0);" class="btn btn-danger" onclick="deleteData('
.$d.')">Delete</a>
            '
;
        }
    )
);

// Include SQL query processing class
require 'ssp.class.php';

// Output data as json format
echo json_encode(
    
SSP::simple$_GET$dbDetails$table$primaryKey$columns )
);

SSP Library

The SSP class handles the database-related operations. It contains some helper functions to build SQL queries for DataTables server-side processing with custom links or buttons. You can see the code of the SSP library here.

Note that: This library and all the required files are included in the source code, you don’t need to download them separately.

CRUD Operations with PHP (eventHandler.php)

The eventHandler.php script handles the add, edit, and delete operations with PHP and MySQL.

addEditUser Request:
Validate the input field’s value before data processing.

  • Check whether the index ID is available in the POST data.
  • If an ID exists, update the record based on the index ID in the database.
  • Otherwise, insert data in the database.

deleteUser:
Delete data from the database based on the ID.

<?php      
// Include database configuration file 
require_once 'dbConnect.php';

// Retrieve JSON from POST body
$jsonStr file_get_contents('php://input');
$jsonObj json_decode($jsonStr);

if(
$jsonObj->request_type == 'addEditUser'){
    
$user_data $jsonObj->user_data;
    
$first_name = !empty($user_data[0])?$user_data[0]:'';
    
$last_name = !empty($user_data[1])?$user_data[1]:'';
    
$email = !empty($user_data[2])?$user_data[2]:'';
    
$gender = !empty($user_data[3])?$user_data[3]:'';
    
$country = !empty($user_data[4])?$user_data[4]:'';
    
$status = !empty($user_data[5])?$user_data[5]:0;
    
$id = !empty($user_data[6])?$user_data[6]:0;

    
$err '';
    if(empty(
$first_name)){
        
$err .= 'Please enter your First Name.<br/>';
    }
    if(empty(
$last_name)){
        
$err .= 'Please enter your Last Name.<br/>';
    }
    if(empty(
$email) || !filter_var($emailFILTER_VALIDATE_EMAIL)){
        
$err .= 'Please enter a valid Email Address.<br/>';
    }
    
    if(!empty(
$user_data) && empty($err)){
        if(!empty(
$id)){
            
// Update user data into the database
            
$sqlQ "UPDATE members SET first_name=?,last_name=?,email=?,gender=?,country=?,status=?,modified=NOW() WHERE id=?";
            
$stmt $conn->prepare($sqlQ);
            
$stmt->bind_param("sssssii"$first_name$last_name$email$gender$country$status$id);
            
$update $stmt->execute();

            if(
$update){
                
$output = [
                    
'status' => 1,
                    
'msg' => 'Member updated successfully!'
                
];
                echo 
json_encode($output);
            }else{
                echo 
json_encode(['error' => 'Member Update request failed!']);
            }
        }else{
            
// Insert event data into the database
            
$sqlQ "INSERT INTO members (first_name,last_name,email,gender,country,status) VALUES (?,?,?,?,?,?)";
            
$stmt $conn->prepare($sqlQ);
            
$stmt->bind_param("sssssi"$first_name$last_name$email$gender$country$status);
            
$insert $stmt->execute();

            if(
$insert){
                
$output = [
                    
'status' => 1,
                    
'msg' => 'Member added successfully!'
                
];
                echo 
json_encode($output);
            }else{
                echo 
json_encode(['error' => 'Member Add request failed!']);
            }
        }
    }else{
        echo 
json_encode(['error' => trim($err'<br/>')]);
    }
}elseif(
$jsonObj->request_type == 'deleteUser'){
    
$id $jsonObj->user_id;

    
$sql "DELETE FROM members WHERE id=$id";
    
$delete $conn->query($sql);
    if(
$delete){
        
$output = [
            
'status' => 1,
            
'msg' => 'Member deleted successfully!'
        
];
        echo 
json_encode($output);
    }else{
        echo 
json_encode(['error' => 'Member Delete request failed!']);
    }
}

Data Table Inline Editing using jQuery, Ajax, PHP and MySQL

Conclusion

DataTables is very useful to build a data list in tabular format and add advanced features to make it user-friendly. You can use this example script to integrate CRUD functionality with DataTables using PHP and MySQL. Here we have used a modal popup to integrate add/edit form UI and delete confirmation window. Since Ajax is used to handle the add, edit, and delete requests, the user can do CRUD operations on a single page without page refresh/reload.

Do you want to get implementation help, or enhance the functionality of this script? Click here to Submit Service Request

Leave a reply

keyboard_double_arrow_up