I am very close to completing this project I am working on. I can add new note, fetch it, delete it, but trying to edit it is not working. I have a form, similar to the one used to add new note.
I used console.log and it gives me a result, however the form still doesn’t com up.
Please help me review the code and offer help/suggestions. It’s urgent, thank you!
notes.php
<?php
// Initialize the session
session_start();
// Check if the user is logged in
if (!isset($_SESSION["loggedin"]) || $_SESSION["loggedin"] !== true) {
header("location: login.php");
exit;
}
// Include config file
require_once "config.php";
// Handle add note request
if (isset($_POST["add_note"])) {
$title = $_POST["title"];
$description = $_POST["description"];
// Check if title and description are not empty
if (!empty($title) && !empty($description)) {
$user_id = $_SESSION["id"];
$sql = "INSERT INTO notes (user_id, title, description, date_published) VALUES (?, ?, ?, NOW())";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("iss", $user_id, $title, $description);
if ($stmt->execute()) {
// Note added successfully
header("Location: notes.php");
} else {
echo "Error adding the note.";
}
$stmt->close();
} else {
echo "Error preparing the statement.";
}
} else {
echo "Title and description are required.";
}
}
// Fetch notes for the current user
$user_id = $_SESSION["id"];
$sql = "SELECT * FROM notes WHERE user_id = ?";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("i", $user_id);
if ($stmt->execute()) {
$result = $stmt->get_result();
echo '<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Notes | Noted App</title>
<link rel="stylesheet" href="notes.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Iconscout Link For Icons -->
<link rel="stylesheet" href="https://unicons.iconscout.com/release/v4.0.8/css/line.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,500,300,700" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Nunito:400,700,300" rel="stylesheet" type="text/css">
<!--[if lt IE 9]>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<ul class="nav-links">
<li class="center"><a href="#">Dashboard</a></li>
<li class="upward"><a href="#">About</a></li>
<li class="forward"><a href="logout.php">Logout</a></li>
</ul>
<!-- Add new note popup form -->
<div class="popup-box" id="add-note-popup">
<div class="popup">
<div class="content">
<header>
<p>Add a New Note</p>
<i class="uil uil-times" id="closeAddNotePopup"></i>
</header>
<form action="" method="post">
<div class="row title">
<label for="title">Title</label>
<input type="text" spellcheck="false" id="title" name="title">
</div>
<div class="row description">
<label for="desc">Description</label>
<textarea spellcheck="false" id="desc" name="description"></textarea>
</div>
<button type="submit" name="add_note">Add Note</button>
</form>
</div>
</div>
</div>
<!-- Edit note popup form -->
<div class="popup-box" id="edit-note-popup">
<div class="popup">
<div class="content">
<header>
<p>Edit Note</p>
<i class="uil uil-times" id="closeEditNotePopup"></i>
</header>
<form action="" method="post">
<div class="row title">
<label for="title">Title</label>
<input type="text" spellcheck="false" id="title" name="title">
</div>
<div class="row description">
<label for="desc">Description</label>
<textarea spellcheck="false" id="desc" name="description"></textarea>
</div>
<button type="submit" name="update_note">Update Note</button>
</form>
</div>
</div>
</div>
<div class="wrapper">
<li class="add-box" id="addNewNoteButton">
<div class="icon"><i class="uil uil-plus"></i></div>
<p>Add new note</p>
</li>
<div class="notes-list">'; // Start the notes list
while ($row = $result->fetch_assoc()) {
// Format the date
$formattedDate = date("F j, Y", strtotime($row['date_published']));
echo '<li class="note">
<div class="details">
<p>' . $row['title'] . '</p>
<span>' . nl2br($row['description']) . '</span>
</div>
<div class="bottom-content">
<span>' . $formattedDate . '</span>
<div class="settings">
<i class="uil uil-ellipsis-h" onclick="showMenu(this)" data-note-id="' . $row['note_id'] . '"></i>
<ul class="menu">
<li class="edit-note" data-note-id="' . $row['note_id'] . '" data-title="' . $row['title'] . '" data-description="' . addslashes($row['description']) . '"><i class="uil uil-pen"></i>Edit</li>
<li class="delete-note" data-note-id="' . $row['note_id'] . '"><i class="uil uil-trash"></i>Delete</li>
</ul>
</div>
</div>
</li>';
}
echo '</div></div>';
echo '<form action="delete_note.php" method="post" id="deleteForm" enctype="application/x-www-form-urlencoded">
<input type="hidden" id="deleteNoteId" name="delete_note" value="">
</form>';
echo ' <form action="update_note.php" method="post" id="updateForm" enctype="application/x-www-form-urlencoded">
<input type="hidden" id="updateNoteId" name="note_id" value="">
<input type="hidden" id="updateNoteTitle" name="title" value="">
<input type="hidden" id="updateNoteDescription" name="description" value="">
</form>';
echo'</body>
<script src="notescript.js"></script>
</html>';
} else {
echo "Error fetching notes.";
}
$stmt->close();
}
$mysqli->close();
?>
notescript.js
document.addEventListener("DOMContentLoaded", function () {
const addNewNoteButton = document.getElementById("addNewNoteButton");
const addNotePopup = document.getElementById("add-note-popup");
const closeAddNotePopup = document.getElementById("closeAddNotePopup");
const editNoteButtons = document.querySelectorAll(".edit-note");
const deleteNoteButtons = document.querySelectorAll(".delete-note");
const popupBox = document.querySelector(".popup-box");
const closeIcon = popupBox.querySelector("header i");
const popupTitle = popupBox.querySelector("header p");
const descTag = popupBox.querySelector("textarea");
const titleTag = popupBox.querySelector("input");
const notesList = document.querySelector(".notes-list");
addNewNoteButton.addEventListener("click", () => {
popupTitle.innerText = "Add a new Note";
addNewNoteButton.innerText = "Add Note";
addNotePopup.classList.add("show");
if (window.innerWidth > 660) titleTag.focus();
});
closeIcon.addEventListener("click", () => {
titleTag.value = descTag.value = "";
popupBox.classList.remove("show");
document.querySelector("body").style.overflow = "auto";
});
window.showMenu = function (elem) {
elem.parentElement.classList.add("show");
document.addEventListener("click", e => {
if (e.target.tagName != "I" || e.target != elem) {
elem.parentElement.classList.remove("show");
}
});
}
// Edit note buttons
editNoteButtons.forEach((editButton) => {
editButton.addEventListener("click", () => {
const noteId = editButton.dataset.noteId;
const title = editButton.dataset.title;
const description = editButton.dataset.description;
console.log('edit menu has been clicked!');
// Populate the edit note popup with the note's details
const titleInput = document.getElementById("title");
const descInput = document.getElementById("desc");
titleInput.value = title;
descInput.value = description;
// Set the edit form's action to the correct URL (update_note.php)
document.getElementById("updateForm").action = "update_note.php";
// Add hidden inputs to track the note being edited
const updateNoteId = document.getElementById("updateNoteId");
const updateNoteTitle = document.getElementById("updateNoteTitle");
const updateNoteDescription = document.getElementById("updateNoteDescription");
updateNoteId.value = noteId;
updateNoteTitle.value = title;
updateNoteDescription.value = description;
// Display the edit note popup
const editNotePopup = document.getElementById("edit-note-popup");
editNotePopup.style.display = "block";
});
});
// Delete note buttons
deleteNoteButtons.forEach((deleteButton) => {
const noteId = deleteButton.dataset.noteId;
deleteButton.addEventListener("click", () => {
const confirmDel = confirm("Are you sure you want to delete this note?");
if (confirmDel) {
// Create a FormData object and append the noteId
const formData = new FormData();
formData.append("delete_note", noteId);
// Use fetch to send the FormData
fetch("delete_note.php", {
method: "POST",
body: formData,
})
.then(response => response.json())
.then(data => {
// Handle the response here, e.g., remove the deleted note from the UI
console.log(data);
if (data.success) {
// Note deleted successfully, remove it from the UI
const noteToDelete = deleteButton.closest(".note");
noteToDelete.remove();
}
})
.catch(error => {
console.error("Error:", error);
});
}
});
});
});
notes.css
/* Import Google Font - Poppins */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
body{
background: #88ABFF;
}
::selection{
color: #fff;
background: #618cf8;
}
.wrapper{
margin: 50px;
display: grid;
gap: 25px;
grid-template-columns: repeat(auto-fill, 265px);
}
.wrapper li{
height: 250px;
list-style: none;
border-radius: 5px;
padding: 15px 20px 20px;
background: #fff;
box-shadow: 0 4px 8px rgba(0,0,0,0.05);
}
.add-box, .icon, .bottom-content,
.popup, header, .settings .menu li{
display: flex;
align-items: center;
justify-content: space-between;
}
.add-box{
cursor: pointer;
flex-direction: column;
justify-content: center;
}
.add-box .icon{
height: 78px;
width: 78px;
color: #88ABFF;
font-size: 40px;
border-radius: 50%;
justify-content: center;
border: 2px dashed #88ABFF;
}
.add-box p{
color: #88ABFF;
font-weight: 500;
margin-top: 20px;
}
.note{
display: flex;
flex-direction: column;
justify-content: space-between;
}
.note .details{
max-height: 165px;
overflow-y: auto;
}
.note .details::-webkit-scrollbar,
.popup textarea::-webkit-scrollbar{
width: 0;
}
.note .details:hover::-webkit-scrollbar,
.popup textarea:hover::-webkit-scrollbar{
width: 5px;
}
.note .details:hover::-webkit-scrollbar-track,
.popup textarea:hover::-webkit-scrollbar-track{
background: #f1f1f1;
border-radius: 25px;
}
.note .details:hover::-webkit-scrollbar-thumb,
.popup textarea:hover::-webkit-scrollbar-thumb{
background: #e6e6e6;
border-radius: 25px;
}
.note p{
font-size: 22px;
font-weight: 500;
}
.note span{
display: block;
color: #575757;
font-size: 16px;
margin-top: 5px;
}
.note .bottom-content{
padding-top: 10px;
border-top: 1px solid #ccc;
}
.bottom-content span{
color: #6D6D6D;
font-size: 14px;
}
.bottom-content .settings{
position: relative;
}
.bottom-content .settings i{
color: #6D6D6D;
cursor: pointer;
font-size: 15px;
}
.settings .menu{
z-index: 1;
bottom: 0;
right: -5px;
padding: 5px 0;
background: #fff;
position: absolute;
border-radius: 4px;
transform: scale(0);
transform-origin: bottom right;
box-shadow: 0 0 6px rgba(0,0,0,0.15);
transition: transform 0.2s ease;
}
.settings.show .menu{
transform: scale(1);
}
.settings .menu li{
height: 25px;
font-size: 16px;
margin-bottom: 2px;
padding: 17px 15px;
cursor: pointer;
box-shadow: none;
border-radius: 0;
justify-content: flex-start;
}
.menu li:last-child{
margin-bottom: 0;
}
.menu li:hover{
background: #f5f5f5;
}
.menu li i{
padding-right: 8px;
}
.popup-box{
position: fixed;
top: 0;
left: 0;
z-index: 2;
height: 100%;
width: 100%;
background: rgba(0,0,0,0.4);
}
.popup-box .popup{
position: absolute;
top: 50%;
left: 50%;
z-index: 3;
width: 100%;
max-width: 400px;
justify-content: center;
transform: translate(-50%, -50%) scale(0.95);
}
.popup-box, .popup{
opacity: 0;
pointer-events: none;
transition: all 0.25s ease;
}
.popup-box.show, .popup-box.show .popup{
opacity: 1;
pointer-events: auto;
}
.popup-box.show .popup{
transform: translate(-50%, -50%) scale(1);
}
.popup .content{
border-radius: 5px;
background: #fff;
width: calc(100% - 15px);
box-shadow: 0 0 15px rgba(0,0,0,0.1);
}
.content header{
padding: 15px 25px;
border-bottom: 1px solid #ccc;
}
.content header p{
font-size: 20px;
font-weight: 500;
}
.content header i{
color: #8b8989;
cursor: pointer;
font-size: 23px;
}
.content form{
margin: 15px 25px 35px;
}
.content form .row{
margin-bottom: 20px;
}
form .row label{
font-size: 18px;
display: block;
margin-bottom: 6px;
}
form :where(input, textarea){
height: 50px;
width: 100%;
outline: none;
font-size: 17px;
padding: 0 15px;
border-radius: 4px;
border: 1px solid #999;
}
form :where(input, textarea):focus{
box-shadow: 0 2px 4px rgba(0,0,0,0.11);
}
form .row textarea{
height: 150px;
resize: none;
padding: 8px 15px;
}
form button{
width: 100%;
height: 50px;
color: #fff;
outline: none;
border: none;
cursor: pointer;
font-size: 17px;
border-radius: 4px;
background: #6A93F8;
}
@media (max-width: 660px){
.wrapper{
margin: 15px;
gap: 15px;
grid-template-columns: repeat(auto-fill, 100%);
}
.popup-box .popup{
max-width: calc(100% - 15px);
}
.bottom-content .settings i{
font-size: 17px;
}
}
.nav-links{
display: flex;
align-items: center;
background: #fff;
padding: 20px 15px;
border-radius: 12px;
box-shadow: 0 5px 10px rgba(0,0,0,0.2);
}
.nav-links li{
list-style: none;
margin: 0 12px;
}
.nav-links li a{
position: relative;
color: #333;
font-size: 20px;
font-weight: 500;
padding: 6px 0;
text-decoration: none;
}
.nav-links li a:before{
content: '';
position: absolute;
bottom: 0;
left: 0;
height: 3px;
width: 0%;
background: #34efdf;
border-radius: 12px;
transition: all 0.4s ease;
}
.nav-links li a:hover:before{
width: 100%;
}
.nav-links li.center a:before{
left: 50%;
transform: translateX(-50%);
}
.nav-links li.upward a:before{
width: 100%;
bottom: -5px;
opacity: 0;
}
.nav-links li.upward a:hover:before{
bottom: 0px;
opacity: 1;
}
.nav-links li.forward a:before{
width: 100%;
transform: scaleX(0);
transform-origin: right;
transition: transform 0.4s ease;
}
.nav-links li.forward a:hover:before{
transform: scaleX(1);
transform-origin: left;
}
.notes-list {
display: contents;
margin: 0;
padding: 0;
border: none;
}
.showMenu {
padding: 0;
border: 0;
border: 0;
}
#edit-note-popup {
display: none; /* Hide the popup by default */
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #fff;
width: 300px; /* Adjust the width as needed */
padding: 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
z-index: 999; /* Ensure the popup is on top of other elements */
}
#edit-note-popup header {
display: flex;
justify-content: space-between;
align-items: center;
}
#edit-note-popup header p {
font-size: 18px;
font-weight: bold;
margin: 0;
}
#edit-note-popup header i {
cursor: pointer;
font-size: 24px;
color: #333;
}
#edit-note-popup form {
margin-top: 10px;
}
#edit-note-popup form label {
font-size: 14px;
display: block;
margin-bottom: 5px;
}
#edit-note-popup form input[type="text"],
#edit-note-popup form textarea {
width: 100%;
padding: 10px;
margin-bottom: 15px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 14px;
}
#edit-note-popup form button {
background-color: #007BFF;
color: #fff;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
#edit-note-popup form button:hover {
background-color: #0056b3;
}
update_note.php
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
session_start();
if (!isset($_SESSION["loggedin"]) || $_SESSION["loggedin"] !== true) {
// Redirect to login page or handle unauthorized access as needed
echo json_encode(array("error" => "Unauthorized access"));
exit;
}
require_once "config.php";
// Get POST data
$data = $_POST;
if (empty($data["note_id"]) || empty($data["title"]) || empty($data["description"])) {
echo json_encode(array("error" => "Note ID, title, and description are required"));
exit;
}
$noteIdToUpdate = $data["note_id"];
$titleToUpdate = $data["title"];
$descriptionToUpdate = $data["description"];
// Prepare and execute the SQL statement to update the note
$sql = "UPDATE notes SET title = ?, description = ? WHERE note_id = ? AND user_id = ?";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("ssii", $titleToUpdate, $descriptionToUpdate, $noteIdToUpdate, $_SESSION["id"]);
if ($stmt->execute()) {
echo json_encode(array("success" => true));
} else {
echo json_encode(array("error" => "Error updating the note"));
}
$stmt->close();
} else {
echo json_encode(array("error" => "Error preparing the statement"));
}
$mysqli->close();
?>
I tried to handle the edit/update note part, expecting a pop up form anytime the edit icon or text is clicked but it doesn’t bring up anything.