Affichage des articles dont le libellé est js. Afficher tous les articles
Affichage des articles dont le libellé est js. Afficher tous les articles

PHP - Comment System with PHP and MySQL

How to Create a Comment System Using PHP and MySQL Database

How to Create a Comment System Using PHP and MySQL Database


In this PHP project tutorial, we will see how to create a basic comment system using PHP, HTML, CSS, JavaScript, and a MySQL database. 
The system connects to a MySQL database to store and retrieve comments.
Users can submit comments and replies to specific comments, and there is an option to cancel replies.





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





Project Source Code:


- Create a Class "db_connect" To Connect Our Form With Database

This file establishes a database connection using PDO (PHP Data Objects) and sets up error handling for the connection.


<?php

$servername = "localhost";
$username = "root";
$password = "";
$dbname = "php-comments";

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 Comments Page: Creating the HTML Structure

This file contains an HTML form for submitting comments, retrieves and displays comments from a database, allows users to reply to comments, and integrates JavaScript for toggling the display of the reply form.


<!DOCTYPE html>
<html>
<head>
<title>Comment System</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>

<div class="container">

<form action="operation.php" method="post">
<label for="name"> Name: </label>
<input type="text" name="name" id="name" required>

<label for="comment"> Comment: </label>
<textarea name="comment" id="comment" rows="5" required></textarea>

<input type="submit" name="submit" value="Post Comment">
</form>

<div class="comments">
<h2>Comments</h2>
<div class="comment-container">
<?php
include 'operation.php';
display_comments($comments);
?>
<!-- test -->
<!-- <ul>
<li class="comment">
<div class="comment-info">
<span class="comment-name">Username</span>
</div>

<div class="comment-text">comment text here</div>
<button class="reply-button">Reply</button>

</li>
</ul> -->

</div>

<form id="reply-form" method="post" action="operation.php">

<input type="hidden" name="parent-id" id="parent-id">
<label for="name">Name:</label>
<input type="text" name="name" id="reply-name">
<input type="hidden" name="reply-to-name" id="reply-to">
<label for="reply-comment-text">Comment:</label>
<textarea name="reply-comment-text" id="reply-comment-text" rows="5" required></textarea>
<button type="submit" name="submit-reply">Submit</button>
<button name="cancel" id="cancel-button">Cancel</button>

</form>


</div>
</div>

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

</body>
</html>



- The Operation File: Handling Form Submissions with PHP

This file manages comment and reply submissions by processing form data, inserting it into the database, and then redirecting to the comments page. 
It also retrieves comments from the database, organizes them hierarchically, and prepares them for display on the web page.


<?php

// Require the database connection file
require_once 'db-connect.php';

// Check if the request method is POST
if($_SERVER['REQUEST_METHOD'] === 'POST'){

// Check if the submit button was clicked
if(isset($_POST['submit'])){

// Check if the name and comment fields are not empty
if(!empty($_POST['name']) && !empty($_POST['comment']))
{
// Get the name and comment values from the form
$name = $_POST['name'];
$comment = $_POST['comment'];
$parent_id = null;

// Prepare an SQL statement to insert the new comment into the database
$stmt = $conn->prepare('INSERT INTO `comments`(`name`, `comment_text`, `parent_id`)
VALUES (:name,:comment,:parent_id)');

// Execute the SQL statement, passing in the name, comment, and parent_id values
$stmt->execute(array(':name'=>$name, ':comment'=>$comment, ':parent_id'=>$parent_id));

// Redirect the user to the comments page after the comment has been added
header('Location: comments.php');
exit;

}
}


if(isset($_POST['submit-reply'])){

$name = filter_input(INPUT_POST,'name',FILTER_SANITIZE_STRING);
$comment_text = filter_input(INPUT_POST,'reply-comment-text',FILTER_SANITIZE_STRING);
$replyTo = filter_input(INPUT_POST,'reply-to-name',FILTER_SANITIZE_STRING);
$comment_text = $replyTo . " " . $comment_text;
$parent_id = $_POST['parent-id'];

// Check if the name and comment fields are not empty
if(!empty($_POST['name']) && !empty($_POST['reply-comment-text']))
{
// Prepare an SQL statement to insert the new comment into the database
$stmt = $conn->prepare('INSERT INTO `comments`(`name`, `comment_text`, `parent_id`)
VALUES (:name,:comment,:parent_id)');

// Execute the SQL statement, passing in the name, comment, and parent_id values
$stmt->execute(array(':name'=>$name, ':comment'=>$comment_text, ':parent_id'=>$parent_id));

// Redirect the user to the comments page after the comment has been added
header('Location: comments.php');
exit;
}

}

}


// Fetch comments
// Select all comments from the database
$stmt = $conn->query('SELECT * FROM `comments`');

// Initialize an empty array to store the comments
$comments = array();

// Loop through each row of the result set and create a comment array
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){

// Create an array to represent the comment
$comment=array(
'id' => $row['id'],
'name' => $row['name'],
'comment' => $row['comment_text'],
'parent_id' => $row['parent_id'],
'replies' => array()
);

// Find parent comment and add this comment as its reply
if($row['parent_id'] !== null)
{
foreach($comments as &$parent){
if($parent['id'] == $row['parent_id']){
$parent['replies'][] = $comment;
}
}
// Remove reference to the last element of $comments
unset($parent);

}else{
// If the comment does not have a parent, add it to the comments array
$comments[] = $comment;
}
}


/**
* This function displays comments in a hierarchical structure.
* @param array $comments An array of comments to display.
* @param int|null $parent_id The ID of the parent comment. If null, display top-level comments.
*/
function display_comments($comments, $parent_id=null){

echo'<ul>';
foreach($comments as $comment){
if($comment['parent_id'] == $parent_id){
// Start displaying the comment
echo'<li class="comment">';
echo'<div class="comment-info">';
echo'<span class="comment-name" data-username="'.$comment['name'].'">'.$comment['name'].'</span>';
echo'</div>';
echo'<div class="comment-text">'.$comment['comment'].'</div>';

// Add reply button
if($parent_id == null){
// Display the reply button for top-level comments
echo'<button class="reply-button"
data-username-text="'.$comment['name'].'"
data-parent-id="'.$comment['id'].'">Reply</button>';
}
else{
// Display the reply button for nested comments
echo'<button class="reply-button"
data-username-text="'.$comment['name'].'"
data-parent-id="'.$comment['parent_id'].'">Reply</button>';
}

// Recursively display replies to the current comment
if(!empty($comment['replies'])){
display_comments($comment['replies'], $comment['id']);
}

// End displaying the comment
echo'</li>';

}
}

echo'</ul>';

}

                                                     

- The testjs.js File: Adding JavaScript for Reply Functionality

this JavaScript file attaches click event listeners to reply buttons, enabling users to reply to comments. When a user selects "Reply," it reveals the reply form, sets the parent comment's ID, and pre-fills the user's name. Additionally, it offers a "Cancel" button for hiding the reply form.


// Get all the reply buttons and assign them to replyButtons variable
const replyButtons = document.querySelectorAll('.reply-button');

// Loop through each reply button and add a click event listener to it
replyButtons.forEach(button => {
button.addEventListener('click', event=>{
// Get the parent ID of the clicked reply button
const parent_id = event.target.getAttribute('data-parent-id');
// Get the username of the user whose comment is being replied to
const name = event.target.getAttribute('data-username-text');
// Set the name input value to '@' + the username
const replyTo = '@'+name;
// Get the reply form and the parent ID field
const replyForm = document.getElementById("reply-form");
const parentField = document.querySelector("#parent-id");
const replyToField = document.querySelector("#reply-to");
replyToField.value = replyTo;
parentField.value = parent_id;

// Show the reply form and scroll to the bottom of the form
replyForm.style.display = "block";
scrollToBottom();

console.log(replyTo);
});
});


// scroll to the bottom to see the reply form
function scrollToBottom(){
const replyForm = document.getElementById("reply-form");
replyForm.scrollIntoView({behavior:"smooth"});
}


// Get the cancel button and the reply form
const cancelButton = document.querySelector("#cancel-button");
const replyForm = document.getElementById("reply-form");

// Add a click event listener to the cancel button
cancelButton.addEventListener('click', event=>{
event.preventDefault();
// Hide the reply form
replyForm.style.display = "none";

});



                                          


////// OUTPUT : 
Comment System with PHP and MySQL

JavaScript - Expense and Income Tracker with JavaScript

How to Build an Expense and Income Tracker with JavaScript


Expense and Income Tracker with JavaScript


In this Javascript tutorial, we will see how to create a web application that allows users to enter their expenses and incomes, view a list of these transactions, and calculate the total net income (income - expenses).



Project Source Code:

HTML and CSS Page


<!DOCTYPE html>
<html>
<head>
<title>Expense and Income Tracker</title>
<link rel="stylesheet" type="text/css" href="style.css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"
rel="stylesheet">
</head>
<body>

<div class="container">
<h1><i class="fas fa-chart-line"></i>Expense-Income Tracker</h1>
<form id="expense-form">
<label>
<i class="fas fa-file-alt"></i>Description:
<input type="text" id="description" placeholder="Enter Expense/Income Description">
</label>
<label>
<i class="fas fa-dollar-sign"></i>Amount:
<input type="number" id="amount" placeholder="Enter Expense/Income Amount">
</label>
<label>
<i class="fas fa-tags"></i>Type:
<select id="type">
<option value="expense">Expense</option>
<option value="income">Income</option>
</select>
</label>
<button type="button" id="btn-add"><i class="fas fa-plus-circle"></i>Add</button>
</form>
<div id="show-values">
<div class="box-expense">
<h2><i class="fas fa-arrow-circle-down"></i>Expense</h2>
<button class="btn" id="btn-clear-expense" style="display: none;">
<i class="fas fa-trash"></i>Clear All
</button>
<ul id="expense-list">
</ul>
</div>

<div class="box-income">
<h2><i class="fas fa-arrow-circle-up"></i>Income</h2>
<button class="btn" id="btn-clear-income" style="display: none;">
<i class="fas fa-trash"></i>Clear All
</button>
<ul id="income-list">
</ul>
</div>

<div class="box-calculate">
<h2><i class="fas fa-calculator"></i>Total Net
</h2> <span id="total"></span>
</div>
</div>

</div>



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



</body>
</html>



JavaScript Code


// Declare variables to store references to HTML elements
let expenseList = document.getElementById("expense-list");
let incomeList = document.getElementById("income-list");
let total = document.getElementById("total");
let expenseForm = document.getElementById("expense-form");
let description = document.getElementById("description");
let amount = document.getElementById("amount");
let type = document.getElementById("type");
let btnAdd = document.getElementById("btn-add");
let btnClearIncomes = document.getElementById("btn-clear-income");
let btnClearExpenses = document.getElementById("btn-clear-expense");

// Initialize arrays and variables for expenses and incomes
let expenses = [];
let incomes = [];
let totalExpenses = 0;
let totalIncomes = 0;

// Add event listener to the button add when clicked
btnAdd.addEventListener("click", function(){

// Create an object to represent the expense / income
let dataValues = { description:description.value,
amount: parseFloat(amount.value),
type:type.value
};

// If the expense / income has a description and amount, add it to the appropriate array
if(dataValues.description && dataValues.amount){

if(dataValues.type === "expense"){
expenses.push(dataValues);
totalExpenses += dataValues.amount;
}
else
{
incomes.push(dataValues);
totalIncomes += dataValues.amount;
}

// Clear the description and amount input fields, then update the lists and total
description.value = "";
amount.value = "";
updateLists();
updateTotal();
}

});


// Function to update the HTML lists of expenses and incomes
function updateLists(){
// Clear the lists
expenseList.innerHTML = "";
incomeList.innerHTML = "";


/* Loop through the expenses and incomes arrays and add each one to its
respective list as an HTML <li> element */
expenses.forEach(function(expense){
let li = document.createElement("li");
li.innerHTML = expense.description + ": $" + expense.amount;
expenseList.appendChild(li);
});

incomes.forEach(function(income){
let li = document.createElement("li");
li.innerHTML = income.description + ": $" + income.amount;
incomeList.appendChild(li);
});
}

// Function to update the total income and expenses and display the result
function updateTotal()
{
total.innerHTML = "";
let netIncome = totalIncomes - totalExpenses;

/* Display the net income with a minus sign if it's negative,
otherwise display it as a positive value */
if(netIncome < 0){
total.innerHTML = "-$" + -netIncome;
}
else{
total.innerHTML = "$" + netIncome;
}


// Hide the clear buttons if there are no expenses or incomes, otherwise show them
if(expenseList.children.length == 0 ){
btnClearExpenses.style.display = "none";
}else{
btnClearExpenses.style.display = "block";
}

if(incomeList.children.length == 0 ){
btnClearIncomes.style.display = "none";
}else{
btnClearIncomes.style.display = "block";
}


}



// Add event listeners to the clear buttons for expenses and incomes
btnClearExpenses.addEventListener("click", function(){

expenses = [];
totalExpenses = 0;
updateLists();
updateTotal();

});

btnClearIncomes.addEventListener("click", function(){

incomes = [];
totalIncomes = 0;
updateLists();
updateTotal();

});





Code Explanation:

This JavaScript code enables users to manage expenses and incomes by allowing them to input financial transactions, view lists of these transactions, and calculate the net income.

This JavaScript code performs the following actions:

1 - Variable Declarations: The code declares variables to store references to HTML elements such as expense and income lists, total, form inputs, and buttons. 
It also initializes arrays and variables for tracking expenses and incomes along with their totals.

2 - Add Event Listener: An event listener is added to the "Add" button (btnAdd) for managing the addition of expenses and incomes. 
When clicked, it generates a transaction object containing a description, amount, and type, and appends it to the appropriate array (either expenses or incomes). 
It subsequently updates the lists displaying these transactions and computes the total net income.

3 - Update Lists Function: A function (updateLists()) that updates the HTML lists for expenses and incomes. It clears the existing lists and then iterates through the expenses and incomes arrays, creating list items (HTML <li> elements) for each transaction.

4 - Update Total Function: The "updateTotal()" function calculates the net income by subtracting total expenses from total income, updating the "Total Net" display with the value (formatted as positive or negative), and controlling the visibility of "Clear" buttons based on transaction presence.

5 - Clear Buttons Event Listeners: The "Clear" buttons for expenses and incomes (btnClearExpenses and btnClearIncomes) have event listeners that, upon clicking, clear the corresponding arrays, reset the totals for expenses and incomes, and update the HTML lists and total net income.



OUTPUT:

Build an Expense and Income Tracker with JavaScript

JavaScript Expenses And Incomes Tracker App Source Code

if you want to download the project files click on the button below


download the source code








JavaScript Quiz App Source Code

How To Make a Quiz App With JavaScript Using Visual Studio Code

JavaScript Quiz App Source Code


In this JavaScript Tutorial we will see How to Make a Simple Quiz App Using a Paragraph, RadioButtons and a Button In JavaScript and Visual Studio Code .



Project Source Code:


<!DOCTYPE HTML>

<head>
<style>
#q-div{background-color: lightgray; border: 1px solid darkgray; width:25%;
padding: 25px; margin-bottom: 35px;}

input{margin-bottom: 14px}
button{background-color: black; color: yellow}

</style>
</head>

<body>

<div id="container">
<div id="content">
<div id="q-div">
<p id="q-content"> Question Here ?</p>
</div>
<input onclick="getSelectedRbutton(this)" type="radio" name="ops"
class="rb" id="op1" value="A">
<label class="lbl" for="op1">Option 1</label><br>

<input onclick="getSelectedRbutton(this)" type="radio" name="ops"
class="rb" id="op2" value="B">
<label class="lbl" for="op2">Option 2</label><br>

<input onclick="getSelectedRbutton(this)" type="radio" name="ops"
class="rb" id="op3" value="C">
<label class="lbl" for="op3">Option 3</label><br>

<input onclick="getSelectedRbutton(this)" type="radio" name="ops"
class="rb" id="op4" value="D">
<label class="lbl" for="op4">Option 4</label><br><br>

<button onclick="play()" id="btn">Next Question</button>

</div>

</div>


<script>
const questions = ["15 + 15 = ?","100 / 10 = ?","200 X 4 = ?",
"250 - 150 = ?","27 / 9 = ?"]
// the last item in the options list row is the correct answer
/* the four other are the options we gonna show the user and
one of them is the correct one */
const options = [["1","30","3","4","30"],["10","30","25","1000","10"],
["100","30","8000","800","800"],["100","300","500","450","100"],
["10","5","3","4","3"]]
// get the radio buttons
rbuttons = document.getElementsByName("ops");
// get the labels
lbls = document.getElementsByClassName("lbl");
// index to go through the questions
// correct to count the correct answers
index = 0, correct = 0;
q_div = document.getElementById("q-div");
question = document.getElementById("q-content");
btn = document.getElementById("btn");


// create a unction to get the selected radio button value
function getSelectedRbutton(rbtn)
{

console.log(rbtn.value);
// check if the user has selected the correct answer
if(rbtn.value == options[index][4]){
correct++;
}
index++;
rButtonsState("d");

}

// create a function to enable and disable radio buttons
function rButtonsState(st)
{
if(st == "d") // d for disable
{
rbuttons.forEach(element => {
element.disabled = true;
});
}
else
{// enable
rbuttons.forEach(element => {
element.disabled = false;
});
}
}
// create the main function to play
function play()
{
// display the question
question.innerHTML = questions[index];
// get the options
op = options[index];
if(btn.innerHTML == "Restart")
{
q_div.style.backgroundColor = "lightgray";
q_div.style.borderColor = "darkgray";
btn.innerHTML = "Next";
}

if(index == questions.length)
{
// if half or more of the answers are correct
if(correct >= questions.length/2)
{
q_div.style.backgroundColor = "lightgreen";
q_div.style.borderColor = "green";
question.innerHTML = correct + " Answers Are Correct";
}
else{
q_div.style.backgroundColor = "lightcoral";
q_div.style.borderColor = "red";
question.innerHTML = correct + " Answers Are Correct";
}

btn.innerHTML = "Restart";
index = 0;
correct = 0;

}
else
{
// enable radiobuttons
rButtonsState("e");
// display the options in labels and radiobuttons
for(var i = 0; i < lbls.length; i++)
{
rbuttons[i].value = op[i];
lbls[i].innerHTML = op[i];
rbuttons[i].checked = false;
}
// if it's the last question
if(index == questions.length - 1 )
{
btn.innerHTML = "Finish and See the Result";
}
}
}
play();

</script>

</body>

</html>                                              



////// OUTPUT : 











download the source code