PHP CRUD Using Modals

How to Create a PHP CRUD Application with Modal Popups in PHP and MySQL Database

How to Create a PHP CRUD Application with Modal Popups in PHP and MySQL Database


In this PHP tutorial we will go step by step on How To Create a simple CRUD (Create, Read, Update, Delete) web application using PHP and JavaScript.
We Will Create Modal interface for adding and editing product data.
The PHP code handles database operations, including creating, updating, and deleting product records.
JavaScript is employed to control modal windows, which are used to facilitate user data input for both adding and editing products, as well as to confirm product deletions.

What We Will Use To Build This Project ? :
- PHP Programming Language.
- JavaScript Programming Language.
- HTML & CSS.
- Font-Awesome.
- VSCode Editor.
- MySQL Database.
- PhpMyAdmin.







Project Source Code:


------------ Create A Class "db_connect" To Connect Our Project With Database

This file establishes a PDO database connection, defining the server, username, password, and database name, while configuring error handling for exceptions.


<?php

$servername = "localhost";
$username = "root";
$password = "";
$dbname = "products_manager";

try{
$conn = new PDO("mysql: host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e){
echo "connection failed: " . $e->getMessage();
die();
}

?>




------------ On The CRUD Page ------------

This file retrieves and displays data from the "product_table" in the database in a table, supports product searching, offers options to add, edit, and delete products through modals, and employs JavaScript to manage modal popups and data capture for editing and deleting.

<?php

// Start the session
session_start();
// Include the database connection file
require_once "db_connect.php";
// Query to select all records from the product_table
$sql = "SELECT * FROM `product_table`";

// Check if a search term is provided via POST request
if(isset($_POST['search']))
{
// Retrieve the search term
$searchTerm = $_POST['search-term'];
// Update the query to filter records based on the search term
$sql = "SELECT * FROM `product_table` WHERE name LIKE '%" . $searchTerm . "%'";
}

// Prepare and execute the SQL query
$stmt = $conn->prepare($sql);
$stmt->execute();
// Fetch all the results as an associative array
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);

?>


<!DOCTYPE html>
<html>
<head>

<title>CRUD Modal</title>
<link rel="stylesheet" href="style.css">

</head>
<body>

<div class="main-content">

<div class="content">

<?php


// Check if error message is set in the session
if(isset($_SESSION['error']))
{
// Display error message with a specific CSS class for styling
echo'<div class="alert error"><p>'.$_SESSION['error']."</p><span class='close-alert'
id='closeAlert'>
&times;</span></div>";
}
// Check if success message is set in the session
elseif(isset($_SESSION['success']))
{
// Display success message with a specific CSS class for styling
echo'<div class="alert success"><p>'.$_SESSION['success']."</p><span class='close-alert'
id='closeAlert'>
&times;</span></div>";
}
// Unset error and success messages from the session to avoid displaying them again
unset($_SESSION['error']);
unset($_SESSION['success']);

?>

<div class="product-section">

<div class="product-header">
<h2>Products</h2>
<div class="search-bar">
<form action="#" method="post" class="form-search">
<input type="text" name="search-term" placeholder="Search...">
<button type="submit" name="search">Search</button>
</form>
</div>
<button class="add-btn">Add Product</button>
</div>

<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Category</th>
<th>Description</th>
<th>Price</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php

$i = 0;
foreach($results as $row)
{
echo"<tr>";
echo"<td>".$row['id']."</td>";
echo"<td>".$row['name']."</td>";
echo"<td>".$row['category']."</td>";
echo"<td>".$row['description']."</td>";
echo"<td>$".$row['price']."</td>";
echo"<td>";
echo"<button class='edit-btn' data-row-index=".$i.">Edit</button>";
echo"<button class='remove-btn' data-row-index=".$i.">Remove</button>";
echo"</td>";
echo"</tr>";

$i += 1;
}

?>






</tbody>
</table>

<!-- Start add / edit modal -->

<div class="modal" id="add-product-modal">
<div class="modal-content">
<span class="close">&times;</span>
<h3 id="modal-title">Add Product</h3>
<form action="functions.php" method="post">
<input type="hidden" id="product-id" name="product-id">
<input type="text" id="product-name" name="product-name" placeholder="Name" required>
<select id="product-category" name="product-category">
<option value="">Select Category</option>
<option value="Category-1">Category-1</option>
<option value="Category-2">Category-2</option>
<option value="Category-3">Category-3</option>
<option value="Category-4">Category-4</option>
</select>
<textarea id="product-description" name="product-description" placeholder="Description">
</textarea>
<input type="text" id="product-price" name="product-price" placeholder="Price">
<button type="submit" name="add" class="add-btn" id="add-edit">Add Product</button>
<button type="button" class="cancel-btn" id="cancel-btn">Cancel</button>
</form>
</div>
</div>

<!-- End add / edit modal -->

<!-- Start Delete modal -->

<div class="modal" id="delete-product-modal">
<div class="modal-content">
<span class="close">&times;</span>
<h3>Confirmation</h3>
<p>Are you sure you want to delete this product?</p>
<form action="functions.php" method="post">
<input type="hidden" id="product-id-delete" name="product-id-delete">
<div class="modal-buttons">
<button type="submit" name="remove" id="confirm-delete" class="delete-btn">
Delete
</button>

<button type="button" id="cancel-delete" class="cancel-btn">Cancel</button>
</div>
</form>
</div>
</div>

<!-- End Delete modal -->

</div>


</div>

</div>


<script>

// Get the modal element
var modal = document.getElementById("add-product-modal");

// Get the add and cancel buttons
var addButton = document.querySelector(".add-btn");
var cancelButton = document.querySelector(".cancel-btn");

// Function to handle the click event on the add button
addButton.onclick = function(){
// Clear the input fields
document.getElementById("product-id").value = "";
document.getElementById("product-name").value = "";
document.getElementById("product-price").value = "";
document.getElementById("product-description").value = "";
document.getElementById("product-category").options[0].selected = true;

// Update the modal title and button text
document.getElementById("modal-title").innerText = "Add Product";
document.getElementById("add-edit").innerText = "Add Product";
document.getElementById("add-edit").name = "add";
// Display the modal
modal.style.display = "block";
}

// Function to handle the click event on the cancel button
cancelButton.onclick = function(){
// Hide the modal
modal.style.display = "none";
}

// Get the close button
var closeBtn = document.getElementsByClassName("close")[0];

// Function to handle the click event on the close button
closeBtn.onclick = function(){
// Hide the modal
modal.style.display = "none";
}

// Get all the edit buttons
var editButtons = document.querySelectorAll(".edit-btn");

// Function to handle the click event on the edit buttons
editButtons.forEach((button)=>{

button.addEventListener('click', (event)=>{
// Get the row index of the clicked button
const rowIndex = event.target.dataset.rowIndex;
// Get the corresponding table row
const tableRow = document.querySelector(`table tbody tr:nth-child(${parseInt(rowIndex)+1})`);
// Get the values from the table cells
const id = tableRow.cells[0].textContent;
const name = tableRow.cells[1].textContent;
const category = tableRow.cells[2].textContent;
const description = tableRow.cells[3].textContent;
const price = tableRow.cells[4].textContent;
// Update the input fields with the values
document.getElementById("product-id").value = id;
document.getElementById("product-name").value = name;
document.getElementById("product-description").value = description;
document.getElementById("product-price").value = price;
// Select the corresponding option in the category dropdown
const categoryDropDown = document.getElementById("product-category");
for(let i=0; i < categoryDropDown.length; i++){
if(categoryDropDown.options[i].value === category){
categoryDropDown.options[i].selected = true;
break;
}
}

// Update the modal title and button text
document.getElementById("modal-title").innerText = "Edit Product";
document.getElementById("add-edit").innerText = "Edit Product";
document.getElementById("add-edit").name = "edit";

// Display the modal
modal.style.display = "block";
});

});


</script>

<script>

// Get all the delete buttons
const deleteButtons = document.querySelectorAll(".remove-btn");
// Get the delete modal
var deleteModal = document.getElementById("delete-product-modal");
// Get the cancel delete button
const cancelDeleteModal = document.getElementById("cancel-delete");

// Add click event listeners to the delete buttons
deleteButtons.forEach((button)=>{
button.addEventListener('click', (event)=>{
// Get the row index and table row of the clicked button
const rowIndex = event.target.dataset.rowIndex;
const tableRow = document.querySelector(`table tbody tr:nth-child(${parseInt(rowIndex)+1})`);

// Get the ID from the table row cells
const id = tableRow.cells[0].textContent;

// Set the value of the delete form input
document.getElementById("product-id-delete").value = id;

// Display the delete modal
deleteModal.style.display = "block";
});

});

// Add click event listener to the cancel delete button
cancelDeleteModal.onclick = function(){
// hide the delete modal
deleteModal.style.display = "none";
}

// Get the close button for the delete modal
var closeBtn = document.getElementsByClassName("close")[1];

// Add click event listener to the close button
closeBtn.onclick = function(){
// hide the delete modal
deleteModal.style.display = "none";
}

// Close the delete modal and main modal when clicking outside of them
window.onclick = function(event){
if(event.target == deleteModal || event.target == modal ){
deleteModal.style.display = "none";
modal.style.display = "none";
}
}


</script>


<script>

// close the alert div
const closeAlert = document.getElementById('closeAlert');

if(closeAlert){
closeAlert.onclick = function(){
closeAlert.parentElement.style.display = "none";
}
}

</script>

</body>
</html>




------------ The Functions Page ------------

This file manages CRUD operations using popup modals for products, handling data retrieval from POST requests and executing SQL statements to add, edit, or delete products in the database. 
It employs sessions to convey success or error messages after each CRUD operation.


<?php

session_start();

require_once 'db_connect.php';

// ADD
if(isset($_POST['add']))
{
$name = $_POST["product-name"];
$category = $_POST["product-category"];
$description = $_POST["product-description"];
$price = $_POST["product-price"];

// Prepare the SQL statement for inserting a new product into the database
$stmt = $conn->prepare("INSERT INTO `product_table`(`name`, `category`, `description`, `price`)
VALUES (:name, :category, :description, :price)");

try
{
// Execute the SQL statement with the provided values
if($stmt->execute(array(':name'=>$name,':category'=>$category,
':description'=>$description,':price'=>$price)))
{
$_SESSION['success'] = "Product added successfully";
header('Location: crud.php');
exit();
}
else{
$_SESSION['error'] = "Failed to add the product ";
header('Location: crud.php');
exit();
}
}
catch(PDOException $ex)
{
$_SESSION['error'] = "ERROR: Failed to add the product - " . $ex->getMessage();
header('Location: crud.php');
exit();
}
}



// EDIT
if(isset($_POST['edit']))
{
$id = $_POST["product-id"];
$name = $_POST["product-name"];
$category = $_POST["product-category"];
$description = $_POST["product-description"];
$price = $_POST["product-price"];

// Prepare the SQL statement for updating a product info in the database
$stmt = $conn->prepare("UPDATE `product_table` SET `name`=:name,`category`=:category,
`description`=:description,`price`=:price WHERE `id`=:id");

try
{
// Execute the SQL statement with the provided values
if($stmt->execute(array(':name'=>$name,':category'=>$category,
':description'=>$description,':price'=>$price,':id'=>$id)))
{
$_SESSION['success'] = "Product updated successfully";
header('Location: crud.php');
exit();
}
else{
$_SESSION['error'] = "Failed to update the product ";
header('Location: crud.php');
exit();
}
}
catch(PDOException $ex)
{
$_SESSION['error'] = "ERROR: Failed to update the product - " . $ex->getMessage();
header('Location: crud.php');
exit();
}
}


// REMOVE
if(isset($_POST['remove']))
{
$id = $_POST["product-id-delete"];

// Prepare the SQL statement for deleting a product from the database
$stmt = $conn->prepare("DELETE FROM `product_table` WHERE `id`=:id");

try
{
// Execute the SQL statement with the provided values
if($stmt->execute(array(':id'=>$id)))
{
$_SESSION['success'] = "Product deleted successfully";
header('Location: crud.php');
exit();
}
else{
$_SESSION['error'] = "Failed to delete the product ";
header('Location: crud.php');
exit();
}
}
catch(PDOException $ex)
{
$_SESSION['error'] = "ERROR: Failed to delete the product - " . $ex->getMessage();
header('Location: crud.php');
exit();
}
}



?>




                                          


////// OUTPUT : 














if you want the source code click on the download button below