Mnemonic Application Design

I would like to make modification to my application can you read the following and say “OK” once you finish reading:

Application Overview

The application is designed to manage memory systems, projects, items, pegs, and images. The PHP scripts handle various operations such as adding items to a project, deleting items, updating items, uploading item images, and retrieving details about items, projects, pegs, and memory systems.

The index.php script is the main page of the application. It starts a session and checks if the user is logged in. If not, it redirects the user to the login page. The page then displays a list of projects and items, and allows the user to add new projects, select items, and update item details.

The main.js script contains the JavaScript code that interacts with the PHP backend. It fetches the projects and items from the server, handles the selection of projects and items, and updates the item details. It also handles the uploading of item images, updating of item and project descriptions, and deletion of items.

Here’s a brief overview of the main functionalities:

  1. Project Selection: The script fetches the list of projects from the server and populates the project dropdown. When a project is selected, it fetches the corresponding items and pegs.
  2. Item Selection: When an item is selected, it fetches the corresponding item details.
  3. Adding a Project: When the “Add Project” button is clicked, it prompts the user to enter the project name and description, and sends a request to the server to add the new project.
  4. Updating Item Details: When the “Update” button is clicked, it sends a request to the server to update the item details.
  5. Uploading Item Images: When the item image link is clicked, it opens the file upload dialog. When a file is selected, it sends a request to the server to upload the image.
  6. Deleting Items: When the “Delete” button is clicked, it sends a request to the server to delete the selected item.
  7. Updating Project Description: When the “Update Project Description” button is clicked, it prompts the user to enter the new project description, and sends a request to the server to update the project description.
  8. Memory Systems: The script fetches the list of memory systems from the server and populates the memory system dropdown. When a memory system is selected, it fetches the corresponding pegs.

This code is a good example of how to build a web application using PHP and JavaScript that interacts with a server to fetch and update data.

MySQL table definitions:


--
-- Table structure for table `M_Images`
--

CREATE TABLE `M_Images` (
  `ImageID` int(11) NOT NULL,
  `ImageType` int(11) DEFAULT NULL,
  `ImageDescription` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `ImageURL` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
 
--
-- Table structure for table `M_ImageTypes`
--

CREATE TABLE `M_ImageTypes` (
  `ImageTypeID` int(11) NOT NULL,
  `ImageTypeName` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Dumping data for table `M_ImageTypes`
--

INSERT INTO `M_ImageTypes` (`ImageTypeID`, `ImageTypeName`) VALUES
(1, 'Peg Image'),
(2, 'Descriptive Image');

-- --------------------------------------------------------

--
-- Table structure for table `M_Items`
--

CREATE TABLE `M_Items` (
  `ItemID` int(11) NOT NULL,
  `ProjectID` int(11) NOT NULL,
  `PegID` int(11) DEFAULT NULL,
  `Name` varchar(500) COLLATE utf8_unicode_ci NOT NULL,
  `ItemDescription` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `ItemImageID` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
 

--
-- Table structure for table `M_MemorySystems`
--

CREATE TABLE `M_MemorySystems` (
  `SystemID` int(11) NOT NULL,
  `name` varchar(100) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Dumping data for table `M_MemorySystems`
--

INSERT INTO `M_MemorySystems` (`SystemID`, `name`) VALUES
(1, 'Mnemonic Number System'),
(2, '4 Room Apartment Systems');

-- --------------------------------------------------------

--
-- Table structure for table `M_Pegs`
--

CREATE TABLE `M_Pegs` (
  `PegID` int(11) NOT NULL,
  `MemorySystemID` int(11) NOT NULL,
  `PegName` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `PegDescription` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `PegOrder` int(11) DEFAULT NULL,
  `PegImageID` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

 
--
-- Table structure for table `M_Projects`
--

CREATE TABLE `M_Projects` (
  `ProjectID` int(11) NOT NULL,
  `ProjectName` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `ProjectDescription` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
 

addItemToProject.php Scripts

<?php

//addItemToProject.php

include('config.php');
header('Content-Type: application/json');
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');

$itemName = $_GET['itemName'] ?? null;
$itemDescription = $_GET['itemDescription'] ?? null;
$projectId = $_GET['projectId'] ?? null;
$pegId = $_GET['pegId'] ?? null;

if ($itemName && $itemDescription && $projectId && $pegId) {
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=' . $dbname, $username, $password);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        $stmt = $pdo->prepare("INSERT INTO M_Items (ProjectID, PegID, Name, ItemDescription, ItemImageID) VALUES (:projectId, :pegId, :itemName, :itemDescription, 51)");
        $stmt->bindParam(':projectId', $projectId);
        $stmt->bindParam(':pegId', $pegId);
        $stmt->bindParam(':itemName', $itemName);
        $stmt->bindParam(':itemDescription', $itemDescription);
        $stmt->execute();

        echo json_encode(['success' => true]);
    } catch (PDOException $e) {
        echo json_encode(['success' => false, 'message' => $e->getMessage()]);
    }
} else {
    echo json_encode(['success' => false, 'message' => 'Missing required parameters']);
}
?>

addProject.php

<?php
include('config.php');
header('Content-Type: application/json');



$projectName = $_GET['projectName'] ?? null;
$projectDescription = $_GET['projectDescription'] ?? null;

if ($projectName !== null) {
    // Remove any special characters for safety
    $projectName = filter_var($projectName, FILTER_SANITIZE_STRING);
    $projectDescription = filter_var($projectDescription, FILTER_SANITIZE_STRING);
    
    // Check if the project name is not empty and does not exceed 100 characters
    if (empty($projectName) || strlen($projectName) > 250) {
        echo json_encode(['success' => false, 'message' => 'Invalid project name']);
        exit;
    }
    // Check if the project description does not exceed 100 characters
    if ($projectDescription !== null && strlen($projectDescription) > 250) {
        echo json_encode(['success' => false, 'message' => 'Invalid project description']);
        exit;
    }
    
    echo "---->> " . $projectName;

    try {
        $pdo = new PDO('mysql:host=localhost;dbname=' . $dbname, $username, $password);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        $stmt = $pdo->prepare("INSERT INTO M_Projects (ProjectName, ProjectDescription) VALUES (:projectName, :projectDescription)");
        $stmt->bindParam(':projectName', $projectName);
        $stmt->bindParam(':projectDescription', $projectDescription);
        $stmt->execute();

        $projectId = $pdo->lastInsertId();

        echo json_encode(['success' => true, 'projectId' => $projectId]);
    } catch (PDOException $e) {
        echo json_encode(['success' => false, 'message' => $e->getMessage()]);
    }
} else {
    echo json_encode(['success' => false, 'message' => 'No project name provided']);
}
?>

deleteItem.php

<?php
include('config.php');
header('Content-Type: application/json');

$itemId = $_GET['itemId'] ?? null;

if ($itemId) {
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=' . $dbname, $username, $password);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        $stmt = $pdo->prepare("DELETE FROM M_Items WHERE ItemId = :itemId");
        $stmt->bindParam(':itemId', $itemId);
        $stmt->execute();

        echo json_encode(['success' => true]);
    } catch (PDOException $e) {
        echo json_encode(['success' => false, 'message' => $e->getMessage()]);
    }
} else {
    echo json_encode(['success' => false, 'message' => 'No item id provided']);
}
?>

getItemDetails.php

<?php
include('config.php'); 
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Content-Type: application/json');

try {
    $pdo = new PDO('mysql:host=localhost;dbname=' . $dbname, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $itemID = $_GET['itemID'];

    $query = "SELECT M_Items.ItemID, 
                     M_Items.Name, 
                     M_Items.ItemDescription, 
                     M_Items.ItemImageID as ItemImageID, 
                     M_Images.ImageUrl as ItemImageUrl, 
                     M_Images.ImageDescription as ItemImageDescription, 
                     M_Pegs.PegID, 
                     M_Pegs.PegOrder,
                     M_Pegs.PegImageID as PegImageID, 
                     M_Images2.ImageUrl as PegImageUrl, 
                     M_Images2.ImageDescription as PegImageDescription 
              FROM M_Items 
              INNER JOIN M_Images ON M_Items.ItemImageID = M_Images.ImageID 
              INNER JOIN M_Pegs ON M_Items.PegID = M_Pegs.PegID 
              INNER JOIN M_Images as M_Images2 ON M_Pegs.PegImageID = M_Images2.ImageID 
              WHERE M_Items.ItemID = :itemID";

 

    $statement = $pdo->prepare($query);
    $statement->bindValue(':itemID', $itemID);
    $statement->execute();


//  echo "-->>" . $query;
// echo "<br /><br />";


    $itemDetails = $statement->fetch(PDO::FETCH_ASSOC);

    echo json_encode($itemDetails);
   
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}
?>

getItems.php

<?php
include('config.php'); 
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Content-Type: application/json');

try {
    $pdo = new PDO('mysql:host=localhost;dbname=' . $dbname, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);


    $projectID = $_GET['projectID'];

    $query = "SELECT M_Items.ItemID, M_Items.Name, M_Items.ItemDescription, M_Items.ItemImageID as ItemImageID, 
                     M_Images.ImageUrl as ItemImageUrl, M_Images.ImageDescription as ItemImageDescription, 
                     M_Pegs.PegID, M_Pegs.PegOrder, M_Pegs.PegImageID as PegImageID, 
                     M_Images2.ImageUrl as PegImageUrl, M_Images2.ImageDescription as PegImageDescription 
              FROM M_Items 
              LEFT JOIN M_Images ON M_Items.ItemImageID = M_Images.ImageID 
              LEFT JOIN M_Pegs ON M_Items.PegID = M_Pegs.PegID 
              LEFT JOIN M_Images as M_Images2 ON M_Pegs.PegImageID = M_Images2.ImageID 
              WHERE M_Items.ProjectID = :projectID";

    $statement = $pdo->prepare($query);
    $statement->bindValue(':projectID', $projectID);
    $statement->execute();

    $items = $statement->fetchAll(PDO::FETCH_ASSOC);

    echo json_encode($items);
   
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

?>

getPegDetails.php

<?php
include('config.php'); 

header('Content-Type: application/json');

try {
    $pdo = new PDO('mysql:host=localhost;dbname=' . $dbname, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $itemID = $_GET['itemID'];

    $query = "SELECT M_Items.ItemID, M_Items.ItemDescription, M_Items.ItemImageID as ItemImageID, 
                     M_Images.ImageUrl as ItemImageUrl, M_Images.ImageDescription as ItemImageDescription, 
                     M_Pegs.PegID, M_Pegs.PegImageID as PegImageID, 
                     M_Images2.ImageUrl as PegImageUrl, M_Images2.ImageDescription as PegImageDescription 
              FROM M_Items 
              LEFT JOIN M_Images ON M_Items.ItemImageID = M_Images.ImageID 
              LEFT JOIN M_Pegs ON M_Items.PegID = M_Pegs.PegID 
              LEFT JOIN M_Images as M_Images2 ON M_Pegs.PegImageID = M_Images2.ImageID 
              WHERE M_Items.ItemID = :itemID";

    $statement = $pdo->prepare($query);
    $statement->bindValue(':itemID', $itemID);
    $statement->execute();

    $itemDetails = $statement->fetch(PDO::FETCH_ASSOC);

    echo json_encode($itemDetails);
   
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}
?>

getPegs.php

<?php
include('config.php');
header('Content-Type: application/json');

try {
    $pdo = new PDO('mysql:host=localhost;dbname=' . $dbname, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $pdo->prepare("
        SELECT 
            M_Pegs.PegID,
            M_Pegs.PegName, 
            M_Pegs.PegOrder, 
            M_Pegs.PegDescription, 
            M_Images.ImageDescription AS PegImageDescription,
            M_Images.ImageURL AS PegImageUrl
        FROM 
            M_Pegs
        LEFT JOIN 
            M_Images ON M_Pegs.PegImageID = M_Images.ImageID
    ");
    
    $stmt->execute();

    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);

    echo json_encode($result);
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}
?>

getProjects.php

<?php
include('config.php');
header('Content-Type: application/json');
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');

try {
    $pdo = new PDO('mysql:host=localhost;dbname=' . $dbname, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $pdo->prepare("SELECT * FROM M_Projects");
    $stmt->execute();

    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);

    echo json_encode($result);
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}
?>

updateItem.php

<?php
include('config.php'); 
header('Content-Type: application/json');

try {
    $pdo = new PDO('mysql:host=localhost;dbname=' . $dbname, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $itemID =  $_POST['itemID'];
    $newName = $_POST['newName'];
    $newDescription = $_POST['newDescription'];

    $query = "UPDATE M_Items SET Name = :newName, ItemDescription = :newDescription WHERE ItemID = :itemID";
    
    $statement = $pdo->prepare($query);
    
  //  echo $query;
    
    $statement->bindValue(':itemID', $itemID);
    $statement->bindValue(':newName', $newName);
    $statement->bindValue(':newDescription', $newDescription);
    $statement->execute();

    $response = array("success" => true);
    echo json_encode($response);

} catch (PDOException $e) {
    $response = array("success" => false, "error" => $e->getMessage());
    echo json_encode($response);
}
?>

updateProjectDescription.php

<?php
include('config.php');
header('Content-Type: application/json');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Content-Type: application/json');

$projectId = $_GET['projectId'] ?? null;
$newDescription = $_GET['newDescription'] ?? null;

if ($projectId && $newDescription) {
    try {
        $pdo = new PDO('mysql:host=localhost;dbname=' . $dbname, $username, $password);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        $stmt = $pdo->prepare("UPDATE M_Projects SET ProjectDescription = :newDescription WHERE ProjectID = :projectId");
        $stmt->bindParam(':newDescription', $newDescription);
        $stmt->bindParam(':projectId', $projectId);
        $stmt->execute();

        echo json_encode(['success' => true]);
    } catch (PDOException $e) {
        echo json_encode(['success' => false, 'message' => $e->getMessage()]);
    }
} else {
    echo json_encode(['success' => false, 'message' => 'No project id or new description provided']);
}
?>

uploadItemImage.php

<?php
// uploadItemImage.php

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // Enable exceptions for mysqli

include('config.php');
header('Content-Type: application/json');
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');

// Database connection
$conn = new mysqli($server, $username, $password, $dbname);

// Check connection
if ($conn->connect_error) {
    die(json_encode(['error' => "Connection failed: " . $conn->connect_error]));
}

if(isset($_POST['itemId'])){
    $itemId = $_POST['itemId'];
} else {
    die(json_encode(['error' => "Item ID not provided"]));
}

if(isset($_POST['submit'])) {
    $target_dir = "./pics/";
    $target_file = $target_dir . basename($_FILES["image"]["name"]);
    $uploadOk = 1;
    $imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));

    // Check if image file is a actual image or fake image
    $check = getimagesize($_FILES["image"]["tmp_name"]);
    if($check !== false) {
        $uploadOk = 1;
    } else {
        die(json_encode(['error' => "File is not an image"]));
    }

    // Check file size
    if ($_FILES["image"]["size"] > 6500000) {
        die(json_encode(['error' => "Sorry, your file is too large"]));
    }

    // Allow certain file formats
    if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg" && $imageFileType != "gif" ) {
        die(json_encode(['error' => "Sorry, only JPG, JPEG, PNG & GIF files are allowed"]));
    }

    // Check if $uploadOk is set to 0 by an error
    if ($uploadOk == 0) {
        echo json_encode(array("success" => false, "message" => "Sorry, your file was not uploaded."));
    // if everything is ok, try to upload file
    } else {
        if (move_uploaded_file($_FILES["image"]["tmp_name"], $target_file)) {

            // Check if image already exists in M_Images table
            $sql = "SELECT ImageID FROM M_Images WHERE ImageURL = ?";
            $stmt = $conn->prepare($sql);
            $stmt->bind_param("s", $target_file);
            $stmt->execute();
            $result = $stmt->get_result();
            $row = $result->fetch_assoc();

            if($row) {
                // Image already exists, get the ImageID
                $last_id = $row['ImageID'];
                
            } else {
                
                    try {
                        // Insert into M_Images table
                        $sql = "INSERT INTO M_Images (ImageType, ImageDescription, ImageURL) VALUES (2, 'for item id $itemId', '" . $target_file . "')";
                        $stmt= $conn->prepare($sql); 
                        $stmt->execute();
                    } catch (mysqli_sql_exception $e) {
                        echo json_encode(['error' => "Error: " . $e->getMessage()]);
                        exit;
                    }
                        // Get the last inserted ImageID
                        $last_id = $conn->insert_id;
            }

            // Update M_Items table
            $sql = "UPDATE M_Items SET ItemImageID = ? WHERE ItemID = ?";
            $stmt = $conn->prepare($sql);
            $stmt->bind_param("ii", $last_id, $itemId); 
            $stmt->execute();

            echo json_encode(array("success" => true, "message" => "The file ". basename( $_FILES["image"]["name"]). " has been uploaded.", "imageUrl" => $target_file));

        } else {
            echo json_encode(array("success" => false, "message" => "Sorry, there was an error uploading your file."));
        }
    }
} else {
    die(json_encode(['error' => "POST submit not set"]));
}

$conn->close();
?>

getMemorySystems.php

<?php
include('config.php');
header('Content-Type: application/json');

try {
    $pdo = new PDO('mysql:host=localhost;dbname=' . $dbname, $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $pdo->prepare("
        SELECT SystemID, name FROM M_MemorySystems
    ");
    
    $stmt->execute();

    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);

    echo json_encode($result);
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}
?>

index.php Script

<?php 
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
// Start the session
session_start();
 
if(!$_SESSION['valid']){
    ?> 
    <script> 
      window.location = "./login.php"; 
    </script>
    
    <?php
    exit("you must log in to see this page.");
}

?>
<!DOCTYPE html>
<html>
<head>
    <title>Mnemonic System</title> 
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
    <style>
        .peg-image {
            max-width: 200px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1 class="text-center mt-1">Mnemonic System</h1>

        <div class="row">
            <div class="col-md-6">
                <div class="input-group mb-3">
                    <label class="input-group-text" for="project">Select a project:</label>
                    <select class="form-select" id="project">
                        <option value="">Select project</option>
                    </select>
                    <button class="btn btn-success" id="addProject">+</button>
                <button class="btn btn-warning" id="updateProjectDescription">&#9998;</button>

                </div>

        <div class="mb-3 d-flex align-items-center">
            <label for="item" class="input-group-text" >Select an Item:</label>
            <select class="form-select me-2" id="item" style="flex-grow: 1;">
                <option value="">Select Item</option>
            </select>
            <button id="deleteItemButton" class="btn btn-danger">-</button>
        </div>


<div id="itemDetails">
    <div style="display: flex; align-items: center;">
    <b><div id="idAndPeg"> </div></b>&nbsp;&nbsp; <input type="text" id="itemName"  size="60" placeholder="Enter new name"  />
    </div>
    <div style="display: flex; align-items: center;">
        <textarea id="newDescription" placeholder="Enter new description" rows="2" class="form-control me-3"></textarea>
    <button id="updateItem" class="btn btn-primary">Update</button>
    </div>
    
    <a href="#" id="itemImageLink">
        <img id="itemImage" class="img-fluid" />
    </a>
    <input type="file" id="itemImageUpload" style="display: none;" />
    <img id="pegImage" class="img-fluid" />
</div>


            </div>

            <div class="col-md-6">
                <select id="memorySystem"></select>
                <div id="pegImages">
                    <h6>Peg Images</h6>
                        <!-- Options will be dynamically populated here -->
                    </select>
                </div>
            </div>
        </div>
    </div>
    

    <script src="main.js"></script>    

</body>
</html>


main.js


    
        // Fetch the projects and populate the dropdown
        fetch('getProjects.php')
            .then(response => response.json())
            .then(data => {
                data.forEach(project => {
                    const option = document.createElement('option');
                    option.value = project.ProjectID;
                    option.textContent = `${project.ProjectName} - ${project.ProjectDescription}`;
                    document.querySelector('#project').appendChild(option);
                });
            });

        function getItems(projectId) {
                let cacheBuster = new Date().getTime();  // Get the current time
              fetch(`getItems.php?projectID=${projectId}&cb=${cacheBuster}`)  
//            fetch(`getItems.php?projectID=${projectId}`)
                .then(response => response.json())
                .then(data => {
                    const itemSelect = document.querySelector('#item');
                    itemSelect.innerHTML = '<option value="">Select Item</option>';

                    data.forEach(item => {
                        const option = document.createElement('option');
                        option.value = item.ItemID;
                        option.textContent = item.PegOrder + ' ' + item.Name  + ' (' + item.PegImageDescription + ') - ' +item.ItemDescription;
                        itemSelect.appendChild(option);
                    });

                    // Automatically select the first item and display its details
                    itemSelect.selectedIndex = 1;
                    getItemDetails(itemSelect.value);
                })
                .catch(error => console.error('Error:', error));
        }

function getItemDetails(itemId) {
    let cacheBuster = new Date().getTime();  // Get the current time
    fetch(`getItemDetails.php?itemID=${itemId}&cb=${cacheBuster}`)
        .then(response => response.json())
        .then(data => { 
            
                    document.querySelector('#idAndPeg').textContent = data.PegOrder + " : " + data.PegImageDescription + ' ';
                    document.querySelector('#itemName').value = data.Name;
document.querySelector('#newDescription').value = data.ItemDescription;

            document.querySelector('#itemImage').src = data.ItemImageUrl + "?v=" + cacheBuster;
            document.querySelector('#itemImage').style.width = '300px';
            document.querySelector('#pegImage').src = data.PegImageUrl + "?v=" + cacheBuster;
            document.querySelector('#pegImage').style.width = '300px';
        })
        .catch(error => console.error('Error:', error));
}

        // When a project is selected, fetch the corresponding items
        document.querySelector('#project').addEventListener('change', (event) => {
            getItems(event.target.value);
            getPegs(event.target.value);
        });

        // When an item is selected, fetch the corresponding item details
        document.querySelector('#item').addEventListener('change', (event) => {
            getItemDetails(event.target.value);
        });

        // Fetch the pegs and populate the area
        function getPegs(memorySystemId) {
                let cacheBuster = new Date().getTime();  // Get the current time
    //        fetch(`getPegs.php?projectId=${projectId}&cb=${cacheBuster}`) 
    alert(memorySystemId);
            fetch(`getPegs.php?memorySystemId=${memorySystemId}&cb=${cacheBuster}`)
                .then(response => response.json())
                .then(data => {
                    const pegImagesDiv = document.querySelector('#pegImages');
                    pegImagesDiv.innerHTML = '<h2>Peg Images</h2>'; // Clear out the previous pegs

                    data.forEach(peg => {
                        const rowDiv = document.createElement('div');
                        rowDiv.className = 'row';

                        const orderDiv = document.createElement('div');
                        orderDiv.className = 'col-2';

                        // Create button
                        const btn = document.createElement('button');
                        btn.className = 'btn btn-primary'; // Bootstrap class
                        btn.textContent = "Add " + peg.PegOrder;
                        btn.onclick = function() {
                            const itemName = prompt("Enter the new item name:");
                            const itemDescription = prompt("Enter the new item description:");
                            const projectId = document.querySelector('#project').value;
                            if (itemName && itemDescription && projectId) {
                                fetch(`addItemToProject.php?itemName=${itemName}&itemDescription=${itemDescription}&projectId=${projectId}&pegId=${peg.PegID}`)
                                    .then(response => response.json())
                                    .then(data => {
                                        if (data.success) {
                                            alert("Item added successfully!");
                                            getItems(projectId);
                                        } else {
                                            alert("Failed to add item to project");
                                        }
                                    });
                            }
                        };


                        orderDiv.appendChild(btn);

                        const imgDiv = document.createElement('div');
                        imgDiv.className = 'col';

                        const img = document.createElement('img');
                        img.src = peg.PegImageUrl;
                        img.alt = peg.PegImageDescription;
                        img.classList.add('img-fluid', 'peg-image');

                        imgDiv.appendChild(img);
                        rowDiv.appendChild(orderDiv);
                        rowDiv.appendChild(imgDiv);

                        pegImagesDiv.appendChild(rowDiv);
                    });
                })
                .catch(error => console.error('Error:', error));
        }

        // On click of Add Project button, add a new project
document.querySelector('#addProject').addEventListener('click', () => {
    const projectName = prompt("Please enter the project name");
    const projectDescription = prompt("Please enter the project description");

    if (projectName && projectDescription) {
        // Add both projectName and projectDescription to your request
        fetch(`addProject.php?projectName=${projectName}&projectDescription=${projectDescription}`, { method: 'GET' })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    const option = document.createElement('option');
                    option.value = data.projectId;
                    option.textContent = `${projectName} - ${projectDescription}`; // Show both name and description
                    document.querySelector('#project').appendChild(option);
                } else {
                    alert(data.message);
                }
            })
            .catch(error => console.error('Error:', error));
    } else {
        alert("Both name and description are required.");
    }
});

        
        
        document.querySelector('#itemImageLink').addEventListener('click', (event) => {
            event.preventDefault();
            document.querySelector('#itemImageUpload').click();
        });
        
        document.querySelector('#itemImageUpload').addEventListener('change', (event) => {
            const file = event.target.files[0];
            const itemId = document.querySelector('#item').value;
            const formData = new FormData();
            formData.append('image', file);
            formData.append('itemId', itemId);
            formData.append('submit', 'true');  // Add this line here
            
            console.log(`Uploading file for item with ID: ${itemId}`);
        
            
            fetch('uploadItemImage.php', {
                method: 'POST',
                body: formData
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    const currentTime = new Date().getTime();
                    const cacheBustedUrl = data.imageUrl + "?v=" + currentTime;
                    document.querySelector('#itemImage').src = cacheBustedUrl;
                } else {
                    alert('Failed to upload image: ' + data.error);
                }
            })
            .catch(error => console.error('Error:', error));
        });

document.querySelector('#updateItem').addEventListener('click', () => {
    const itemId = document.querySelector('#item').value;
    const newItemName = document.querySelector('#itemName').value;
    const newDescription = document.querySelector('#newDescription').value;

    const formData = new FormData();
    formData.append('itemID', itemId);
    formData.append('newName', newItemName);
    formData.append('newDescription', newDescription);
    
    fetch('updateItem.php', {
        method: 'POST',
        body: formData
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            alert('Description updated successfully');

            // Find the selected option in the #item select element and update its text content
            const selectedItemOption = document.querySelector(`#item option[value="${itemId}"]`);
            if (selectedItemOption) {
                selectedItemOption.textContent = newDescription;
            }

            // Update the description in the #itemDescriptionText element
            document.querySelector('#itemDescriptionText').textContent = newDescription;
        } else {
            alert('Failed to update description: ' + data.error);
        }
    })
    .catch(error => console.error('Error:', error));
});
       
       
document.getElementById("deleteItemButton").addEventListener("click", function() {
    var itemId = document.getElementById("item").value;  // Changed from "itemListbox" to "item"
    if (itemId) {
        deleteItem(itemId);
    } else {
        alert("Please select an item to delete");
    }
});


function deleteItem(itemId) {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "deleteItem.php?itemId=" + itemId, true);
    xhr.onreadystatechange = function() {
        if (this.readyState === 4 && this.status === 200) {
            var result = JSON.parse(this.responseText);
            if (result.success) {
                alert("Item deleted successfully");
                // Refresh the item list
                var projectId = document.getElementById("project").value;
                getItems(projectId);
            } else {
                alert("Failed to delete item: " + result.message);
            }
        }
    }
    xhr.send();
}

document.querySelector('#updateProjectDescription').addEventListener('click', () => {
    const projectId = document.querySelector('#project').value;
    const currentDescription = document.querySelector(`#project option[value="${projectId}"]`).textContent.split('-')[1].trim();

    const newDescription = prompt("Please enter the new project description", currentDescription);
    if (newDescription) {
        // Assuming you have a PHP endpoint to update the project description
        fetch(`updateProjectDescription.php?projectId=${projectId}&newDescription=${newDescription}`)
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    // Find the selected option in the #project select element and update its text content
                    const selectedProjectOption = document.querySelector(`#project option[value="${projectId}"]`);
                    if (selectedProjectOption) {
                        selectedProjectOption.textContent = newDescription;
                    }
                } else {
                    alert('Failed to update description: ' + data.error);
                }
            })
            .catch(error => console.error('Error:', error));
    }
});

document.querySelector('#memorySystem').addEventListener('change', (event) => {
    getPegs(event.target.value);
});


function getMemorySystems() {
    fetch('getMemorySystems.php')
        .then(response => response.json())
        .then(data => {
            const memorySystemSelect = document.querySelector('#memorySystem');
            data.forEach(memorySystem => {
                const option = document.createElement('option');
                option.value = memorySystem.id;
                option.textContent = memorySystem.name;
                memorySystemSelect.appendChild(option);
            });
        })
        .catch(error => console.error('Error:', error));
}

// Call this function when the page loads
getMemorySystems();

 

test.php

<?php
include('config.php');
checkUserSession();

    $projectID = $_GET['project_id'];

function getRandomItems($pdo, $pid, $limit=20) {
    $query = "
        SELECT 
            M_Items.ItemID, 
            M_Items.Name, 
            M_Images.ImageURL,
            M_Items.PegID
        FROM 
            M_Items
        INNER JOIN 
            M_Images 
        ON 
            M_Items.ItemImageID = M_Images.ImageID 
        WHERE M_Items.ProjectID = " . $pid . "
        ORDER BY RAND() 
        LIMIT :limit
    ";

    $statement = $pdo->prepare($query);
    $statement->bindValue(':limit', (int) $limit, PDO::PARAM_INT);
    $statement->execute();

    $items = [];
    while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
        $items[$row['ItemID']] = [$row['Name'], $row['ImageURL'], $row['PegID']];
    }
    return $items;
}


function getRandomPegs($pdo, $pid, $limit=20) {
    $query = "
        SELECT 
            M_Pegs.PegID, 
            M_Pegs.PegName, 
            M_Images.ImageURL
        FROM 
            M_Pegs
        INNER JOIN 
            M_Images 
        ON 
            M_Pegs.PegImageID = M_Images.ImageID 
        INNER JOIN 
            M_Items 
        ON 
            M_Items.PegID = M_Pegs.PegID 
        WHERE M_Items.ProjectID = " . $pid . "
        ORDER BY RAND() 
        LIMIT :limit
    ";

  //  echo $query . "<br /><br /><br /><br />";

    $statement = $pdo->prepare($query);
    $statement->bindValue(':limit', (int) $limit, PDO::PARAM_INT);
    $statement->execute();

    $pegs = [];
    while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
        $pegs[$row['PegID']] = [$row['PegName'], $row['ImageURL']];
    }
    return $pegs;
}


$pdo = new PDO('mysql:host=localhost;dbname=' . $dbname, $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$items = getRandomItems($pdo, $projectID);
$pegs = getRandomPegs($pdo, $projectID);
?>

<!DOCTYPE html>
<html>
<head>
    <title>Memory Test</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
    $(document).ready(function() {
    var score = 0;
    var mistakes = 0;
    var selectedItem = null;
    var selectedPeg = null;

    $('.item').on('click', function() {
        if (selectedItem === this) {
            $(this).removeClass('selected');
            selectedItem = null;
        } else {
            $('.item').removeClass('selected');
            $(this).addClass('selected');
            selectedItem = this;
        }
        checkMatch();
    });

    $('.peg').on('click', function() {
        if (selectedPeg === this) {
            $(this).removeClass('selected');
            selectedPeg = null;
        } else {
            $('.peg').removeClass('selected');
            $(this).addClass('selected');
            selectedPeg = this;
        }
        checkMatch();
    });

    function checkMatch() {
        if (selectedItem && selectedPeg) {
            if ($(selectedItem).data('id') === $(selectedPeg).data('id')) {
                $(selectedItem).remove();
                $(selectedPeg).remove();
                selectedItem = null;
                selectedPeg = null;
                score++;
                $('#score').text(score);
            } else {
                mistakes++;
                $('#mistakes').text(mistakes);
            }
        }
    }
});

    </script>
        <style>
    .selected {
    background-color: #ADD8E6;
    }

    .column {
        width: 250px;
        float: left;
        padding: 10px;
        box-sizing: border-box;
    }
    .item, .peg {
        margin-bottom: 10px;
    }
    .item img, .peg img {
        max-width: 100%;
        height: auto;
    }
    </style>
</head>
<body>
    
    <h1>Score: <span id="score">0</span> | Mistakes: <span id="mistakes">0</span></h1>


    <div class="row">
        <div class="column">
            <h2>Items</h2>
            <?php foreach ($items as $id => $item) : ?>
                <div class="item" data-id="<?php echo $item[2]; ?>">
                    <h3><?php echo $item[0]; ?></h3>
                    <img src="<?php echo $item[1]; ?>" />
                </div>
            <?php endforeach; ?>
        </div>

        <div class="column">
            <h2>Pegs</h2>
            <?php foreach ($pegs as $id => $peg) : ?>
    <div class="peg" data-id="<?php echo $id; ?>">
                    <h3><?php echo $peg[0]; ?></h3>
                    <img src="<?php echo $peg[1]; ?>" />
                </div>
            <?php endforeach; ?>
        </div>
    </div>
</body>
</html>
Author: amontazar