I am trying to write a simple delete function for a comment system that i am working on. the comments are stored in a database where each comment has a cid that is incremented automatically. i have noticed that the user can only delete the first comment he/she has written but when a the user writes two comments and presses delete on the second one, the comment can not be deleted, can someone help fix this. here is my code. thank you for your help.
this is my meatballs.php file where i have the comments loaded.
<div class = "page" id = "comments">
<p class = "style">Comments</p>
<button class="btn" id="load-comments">See Previous Comments</button><br>
<br>
<?php
if(isset($_SESSION['u_id'])){
echo " <input type = 'hidden' id = 'uid' value = '".$_SESSION['u_uid']."'>
<input type = 'hidden' id = 'date' value = '".date('Y-m-d H:i:s')."'>
<textarea id = 'message'></textarea><br>
<button class = 'btn' type = 'submit' id = 'meatballsSubmit'>Comment</button>";
}
else{
echo "<p>Please log in to comment</p>";}
?>
</div><br>
<script>
$(document).ready(function(){
$("#load-comments").click(function(){
document.getElementById('#comments').innerHTML=
$("#comments").load("getComments.php");
});
});
</script>
as for getCommetns.php file which retrieves the comments from the database.
<?php
include 'includes/dbh.inc.php';
session_start();
$sql = "SELECT * FROM meatballscomments";
$result = mysqli_query($conn, $sql);
while($row = $result->fetch_assoc()){
echo "<div class = 'comment-box'>";
echo '<span class = "user">'.$row['user_uid'].'</span><br><br>';
echo "<p>".htmlspecialchars($row['message'])."</p>";
echo '<span class = "datef">'.$row['date'].'</span>';
if(isset($_SESSION['u_id']) && $_SESSION['u_uid'] == $row['user_uid']){
echo "<br>";
echo "<input type = 'hidden' id = 'cid' value = '".$row['cid']."'>";
echo "<button class = 'btn' type = 'submit' id = 'meatballsDelete'>Delete</button>";
}
echo "</div><hr>";
}
?>
<script>
$(document).ready(function(){
$("#meatballsDelete").click(function(){
var cid = $("#cid").val();
$.ajax({
url: "deleteComment.php",
type: "POST",
async: false,
data: {
"cid": cid
}});
alert("Your comment has been deleted");
});
});
</script>
the deleteComment.php file that i have is very short and here it is.
<?php
include 'includes/dbh.inc.php';
$cid = $_POST['cid'];
$sql = "DELETE FROM meatballscomments WHERE cid = '$cid'";
$result = mysqli_query($conn, $sql);
You're assigning the same id on multiple html elements & using val() on the result of the jQuery selector which returns the first element with the id of cid. From jQuery:
Each id value must be used only once within a document. If more than
one element has been assigned the same ID, queries that use that ID
will only select the first matched element in the DOM.
Therefore there's no guarantee that it automatically grabs the right element for you, when you're using the same id multiple times.
The quickest fix would be to change #meatballsDelete to .meatballsDelete, and add the meatballsDelete class to your button, that way clicking will register on both buttons. Also add the $row['cid'] value as attribute to the button and then grab that with $(this).attr("myAttribute") in the function in click, which will always guarantee that the id is returned which belongs to the button.
Like #u_mulder says in the comments, you're also using an id to register the click, which will also bind to the first element with that id.
A reasonably easy way to modify your code to resolve this issue would be to get rid of the hidden cid input and add the cid value as a data value to your button. You also need to change the button to have a class meatballsDelete rather than an id, since id values must be unique. So change this:
echo "<input type = 'hidden' id = 'cid' value = '".$row['cid']."'>";
echo "<button class = 'btn' type = 'submit' id = 'meatballsDelete'>Delete</button>";
To
echo "<button class = 'btn meatballsDelete' type = 'submit' data-cid = '{$row['cid']}'>Delete</button>";
and then modify your javascript to add the click handler to items of class meatballsDelete (instead of id) and retrieve the cid value from the data-cid attribute:
$(document).ready(function(){
$(".meatballsDelete").click(function(){
var cid = $(this).data('cid');
$.ajax({
url: "deleteComment.php",
type: "POST",
async: false,
data: {
"cid": cid
}});
alert("Your comment has been deleted");
});
});
if(isset($_SESSION['u_id']) && $_SESSION['u_uid'] == $row['user_uid']){
echo "<br>";
echo "<p id='demo'></p>";
$commentId = $row['cid'];
echo "<input type = 'hidden' id = 'cid' value = '".$row['cid']."'>";
echo "<button class = 'btn' type = 'submit' onclick= 'deleteFunction($commentId, 1)'>Delete</button>";
}
and the script i used
<script>
function deleteFunction(cid, page){
//document.getElementById("demo").innerHTML = cid + " ----"+ page;
$.ajax({
url: "deleteComment.php",
type: "POST",
async: false,
data: {
"cid": cid,
"page": page}
});
alert("Your comment has been deleted!");
}
</script>
Related
I am building a basic commenting system for a website: Comments can be made and users can reply on every comment. I am using ajax for submitting and retrieving/displaying the comments and replies. I have successfully coded the comments part, but need assistance on the replies part.
Every comment stored in the database has a unique id (comment_id) associated with it. And I use that id to associate replies to each respective comment.
The form for the comments, which is in index.php:
<div id="showComments"></div> <!--div where comments are inserted by AJAX-->
<div style="text-align:center;">
<form action="" method="post" id="commentForm">
<textarea name="comment" id="comment" rows="1"></textarea><BR>
<button type="submit" name="new_comment" onClick="submitComment()">Comment</button>
</form>
<div id="message"></div> <!--div where a status (comment submitted successfully or failed) is inserted by AJAX-->
</div>
The JavaScript for submitting the comment and displaying the comments, also in index.php.
<script>
$(document).ready(function() {
showComments();
});
function submitComment(){
var commentText = document.getElementById('comment').value;
var commentString = 'comment=' + commentText;
event.preventDefault();
$.ajax({
url: "insert_com.php",
method: "POST",
data: commentString,
dataType: "JSON",
success: function(response) {
if (!response.error) {
$("#commentForm")[0].reset();
$("#message").html(response.message);
showComments();
} else if (response.error) {
$("#message").html(response.message);
}
}
});
}
function showComments() {
$.ajax({
url: "get_com.php",
method: "POST",
success: function(response) {
$("#showComments").html(response);
}
});
}
</script>
The file insert_com.php, which submits the comment to the database, to where AJAX posts in the submitComment() function:
<?php
if(!empty($_POST["comment"])){
$new_com_date = date('Y-m-d H:i:s');
$insertComment = "INSERT INTO comments (text, date) VALUES ('".$_POST["comment"]."', '".$new_com_date."')";
mysqli_query($connect, $insertComment) or die("database error: ". mysqli_error($connect));
$message = '<label>Comment posted Successfully.</label>';
$status = array(
'error' => 0,
'message' => $message
);
} else {
$message = '<label>Error: Comment not posted.</label>';
$status = array(
'error' => 1,
'message' => $message
);
}
echo json_encode($status);
?>
And the file get_com.php, which retrieves and displays the comments but also retrieves the replies and contains the form for submitting the replies
<?php
require 'php/connect.php';
$comment = mysqli_query($connect, "SELECT * FROM `comments` ORDER BY `date` DESC");
$string ="";
foreach($comment as $item) {
$date = new dateTime($item['date']);
$date = date_format($date, 'M j, Y | H:i:s');
$comment = $item['text'];
$comment_id = $item['id'];
$string .= '<div style="text-align:center;">'
.'<div id="'.$comment_id.'" style="text-align:center;">'
.'<span><b>'.$comment.'</b></span> '
.'<span><b>'.$date.'</b></span> '
.'<span><b>'.$comment_id.'</b></span>'
.'</div>';
$reply = mysqli_query($connect, "SELECT * FROM `replies` WHERE `comment_id`='$comment_id' ORDER BY `date` DESC");
foreach($reply as $com) {
$reply_date = new dateTime($com['date']);
$reply_date = date_format($reply_date, 'M j, Y | H:i:s');
$reply_com = $com['text'];
$com_id = $com['comment_id'];
$string.= '<div>'
.'<span>'.$reply_com.'</span> '
.'<span class="time">'.$reply_date.'</span> '
.'<span><b>'.$com_id.'</b></span>'
.'</div>';
}
$string .=
'<div>'
.'<form action="" method="post" id="replyForm">'
.'<textarea name="new-reply" id="new-reply" rows="1"></textarea>'
.'<input type="hidden" id="com_id" name="com_id" value="'.$comment_id.'"/>'
.'<button type="submit" id="form-reply" name="new_reply" onClick="submitReply()">Reply</button> '
.'<span><b>'.$comment_id.'</b></span>'
.'</form>'
.'<span id="replymessage"></span>'
.'</div>'
.'</div>'
.'<hr style="width:300px;">';
}
echo $string;
?>
Now, here is where the problem comes in. I want to use AJAX to submit a reply to a particular comment with an id $comment_id. I want to get this id from the hidden input contained in the reply form (The form with id replyForm.
I wrote the following JavaScript to retrieve the id belonging to a particular comment:
<script>
function submitReply(){
var replyText = document.getElementById('new-reply').value; console.log(replyText);
var commId = document.getElementById('com_id').value; console.log(commId);
event.preventDefault();
...
</script>
As you can see, I log the form text (the reply) and the comment id to the console to see whether I am capturing the correct data, but it always returns the id of the last comment submitted. (i.e the reply form works for the last comment. The JavaScript logs the correct text and comment id for a reply on the last comment, but for all other replies it returns the text of the reply on the last comment and the id of the last comment.
I know it's quite a lot of code, so if anyone more experience could assist me it would certainly be appreciated.
You have more than one element with id="com_id". id should be unique. What you can do is when you are generating the DOM in get_com.php, instead of
'<input type="hidden" id="com_id" name="com_id" value="'.$comment_id.'"/>'
'<button type="submit" id="form-reply" name="new_reply" onClick="submitReply()">Reply</button> '
You can call submitReply() with the right ID, like so:
'<button type="submit" id="form-reply" name="new_reply" onClick="submitReply('.$comment_id.')">Reply</button> '
Then, the comment ID would be the argument of your submitReply method and you wouldn't need to read it from the input field.
<script>
function submitReply(commId){
var replyText = document.getElementById('new-reply').value;
console.log(replyText);
console.log(commId);
event.preventDefault();
...
</script>
Your <textarea> has the same issue as well.
I suggest to assign a unique ID to your <textarea> as well, something like "reply-'.$comment_id.'". Then, when submitReply(comment_id) gets called, you know which comment ID is the call for, so you can construct the unique ID for the exact same textarea, and get the value of the desired element.
<script>
function submitReply(commId){
var replyText = document.getElementById('reply-' + commId).value;
console.log(replyText);
console.log(commId);
event.preventDefault();
...
</script>
I'm trying to get data from a database and update the records one by one,
I had made a table I created a text input field and button which will build dynamically with the records, the text input field will have the previous record, then I should change that and submit it. the problem is when I try to edit and submit which I changed, it gives the first text input value for all the button
this is my Javascript code:
$("body").delegate("a","click",function(event){
//$("#category_editing").click(function(){
event.preventDefault();
var cat_name = $("#new_cat_name").val();
//var cat_name = $(this).attr('new_cat_name');
var cat_id = $(this).attr('cat_id');
console.log('starting ajax');
alert(cat_name);
$.ajax({
url : "update_cat.php",
method: "POST",
data : {cat_id:cat_id,cat_name:cat_name},
success : function(data){
alert(data);
}
});
});
and this is my php and html code:
$category_query = "SELECT * FROM `CATEGORIES`";
$run_query = mysqli_query($connect,$category_query);
echo "
<div class='nav nav-pills nav-stacked'>
<li class='active'><a href='#'
>Categories</a></li>";
if(mysqli_num_rows($run_query)>0){
while
($row = mysqli_fetch_array($run_query))
{
$CATEGORY_ID = $row['CATEGORY_ID'];
$CATEGORY_NAME = $row['CATEGORY_NAME'];
$CATEGORY_DESC = $row['CATEGORY_DESC'];
$CATEGORY_IMAGE_PATH = $row['CATEGORY_IMAGE_PATH'];
echo "
<li><a class='category_editing' cat_id='$CATEGORY_ID'><input type='text' class='form-control' id='new_cat_name' value='$CATEGORY_NAME'><a href='#' class='category_editing btn btn-warning' cat_id='$CATEGORY_ID' cat_name='$CATEGORY_NAME'>Submit</a></a></li>";
}
}
//}
?>
That's the problem:
var cat_name = $("#new_cat_name").val();
You should access the changed input by the id of the anchor tag or something like this. You have to select a specific input. You could render it this way:
cat_id='$CATEGORY_ID'><input type='text' class='form-control' id='input_$CATEGORY_ID'
And try to access the input by concatenation of the string 'input' and the id of the anchor text in the handler context.
I'm trying to create a comment system on my website where the user can comment & see it appear on the page without reloading the page, kind of like how you post a comment on facebook and see it appear right away. I'm having trouble with this however as my implementation shows the comment the user inputs, but then erases the previous comments that were already on the page (as any comments section, I'd want the user to comment and simply add on to the previous comments). Also, when the user comments, the page reloads, and displays the comment in the text box, rather than below the text box where the comments are supposed to be displayed. I've attached the code. Index.php runs the ajax script to perform the asynchronous commenting, and uses the form to get the user input which is dealt with in insert.php. It also prints out the comments stored in a database.
index.php
<script>
$(function() {
$('#submitButton').click(function(event) {
event.preventDefault();
$.ajax({
type: "GET",
url: "insert.php",
data : { field1_name : $('#userInput').val() },
beforeSend: function(){
}
, complete: function(){
}
, success: function(html){
$("#comment_part").html(html);
window.location.reload();
}
});
});
});
</script>
<form id="comment_form" action="insert.php" method="GET">
Comments:
<input type="text" class="text_cmt" name="field1_name" id="userInput"/>
<input type="submit" name="submit" value="submit" id = "submitButton"/>
<input type='hidden' name='parent_id' id='parent_id' value='0'/>
</form>
<div id='comment_part'>
<?php
$link = mysqli_connect('localhost', 'x', '', 'comment_schema');
$query="SELECT COMMENTS FROM csAirComment";
$results = mysqli_query($link,$query);
while ($row = mysqli_fetch_assoc($results)) {
echo '<div class="comment" >';
$output= $row["COMMENTS"];
//protects against cross site scripting
echo htmlspecialchars($output ,ENT_QUOTES,'UTF-8');
echo '</div>';
}
?>
</div>
insert.php
$userInput= $_GET["field1_name"];
if(!empty($userInput)) {
$field1_name = mysqli_real_escape_string($link, $userInput);
$field1_name_array = explode(" ",$field1_name);
foreach($field1_name_array as $element){
$query = "SELECT replaceWord FROM changeWord WHERE badWord = '" . $element . "' ";
$query_link = mysqli_query($link,$query);
if(mysqli_num_rows($query_link)>0){
$row = mysqli_fetch_assoc($query_link);
$goodWord = $row['replaceWord'];
$element= $goodWord;
}
$newComment = $newComment." ".$element;
}
//Escape user inputs for security
$sql = "INSERT INTO csAirComment (COMMENTS) VALUES ('$newComment')";
$result = mysqli_query($link, $sql);
//attempt insert query execution
//header("Location:csair.php");
die();
mysqli_close($link);
}
else{
die('comment is not set or not containing valid value');
}
The insert.php takes in the user input and then inserts it into the database (by first filtering and checking for bad words). Just not sure where I'm going wrong, been stuck on it for a while. Any help would be appreciated.
There are 3 main problems in your code:
You are not returning anything from insert.php via ajax.
You don't need to replace the whole comment_part, just add the new comment to it.
Why are you reloading the page? I thought that the whole purpose of using Ajax was to have a dynamic content.
In your ajax:
$.ajax({
type: "GET",
url: "insert.php",
data : { field1_name : $('#userInput').val() },
beforeSend: function(){
}
, complete: function(){
}
, success: function(html){
//this will add the new comment to the `comment_part` div
$("#comment_part").append(html);
}
});
Within insert.php you need to return the new comment html:
$userInput= $_GET["field1_name"];
if(!empty($userInput)) {
$field1_name = mysqli_real_escape_string($link, $userInput);
$field1_name_array = explode(" ",$field1_name);
foreach($field1_name_array as $element){
$query = "SELECT replaceWord FROM changeWord WHERE badWord = '" . $element . "' ";
$query_link = mysqli_query($link,$query);
if(mysqli_num_rows($query_link)>0){
$row = mysqli_fetch_assoc($query_link);
$goodWord = $row['replaceWord'];
$element= $goodWord;
}
$newComment = $newComment." ".$element;
}
//Escape user inputs for security
$sql = "INSERT INTO csAirComment (COMMENTS) VALUES ('$newComment')";
$result = mysqli_query($link, $sql);
//attempt insert query execution
mysqli_close($link);
//here you need to build your new comment html and return it
return "<div class='comment'>...the new comment html...</div>";
}
else{
die('comment is not set or not containing valid value');
}
Please note that you currently don't have any error handling, so when you return die('comment is not set....') it will be displayed as well as a new comment.
You can return a better structured response using json_encode() but that is outside the scope of this question.
You're using jQuery.html() which is replacing everything in your element with your "html" contents. Try using jQuery.append() instead.
I am using a custom mvc framework and have added a favourite button. Once pressed this displays a 'successfully added to favourites' div, when clicked again it displays a 'successfully removed from favourites' div.
My query works fine, adding and deleting from my favourite table as it should.
What I would like to do now is change the state of the button depending on the selection. For example, if the user has the book in their favourites add btn-success class, if the user hasn't, use the btn-default class.
I'm not sure the best way to approach this. I'm new to php and js so any advice or direction is appreciated. I have tried adding toggleClass to my JS but it's not working. Do I need to perform a query/check on pageLoad?
I have included my code below for reference.
itemView.php
echo
'<td>
<button id="fav" value="'.$book->id.'" type="button" class="btn btn-default"></button>
</td>';
JS (in itemView.php)
$(document).ready(function(){
$( "#fav" ).click(function(){
book_id = $(fav).val();
$.ajax({
type: 'POST',
url: '<?php echo URL; ?>books/checkFav',
data: {book_id:book_id},
success: function () {
window.location.reload(true);
$("#fav").addClass( "btn-success" );
}//end success
});//end ajax
});
});
my checkFav function
public function checkFav($bookid,$userid)
{
$bookid=$_REQUEST['book_id'];
$userid=$_SESSION['user_id'];
$sql = "SELECT * FROM favourite WHERE book_id = :book_id AND user_id = :user_id";
$query = $this->db->prepare($sql);
$query->bindParam(':user_id', $userid);
$query->bindParam(':book_id', $bookid);
$query->execute();
$rows_found = $query->fetchColumn();
if(empty($rows_found)) {
$sql = "INSERT INTO favourite (book_id, user_id) VALUES (:book_id, :user_id)";
$query = $this->db->prepare($sql);
$query->bindParam(':user_id', $userid);
$query->bindParam(':book_id', $bookid);
$query->execute();
if ($query->rowCount() == 1) {
// successful add to favs
$_SESSION["feedback_positive"][] = FEEDBACK_ADDED_TO_FAVS;
return true;
}
} else {
$sql = "DELETE FROM favourite WHERE book_id = :book_id AND user_id = :user_id";
$query = $this->db->prepare($sql);
$query->bindParam(':user_id', $userid);
$query->bindParam(':book_id', $bookid);
$query->execute();
if ($query->rowCount() > 0) {
// successful remove from favs
$_SESSION["feedback_negative"][] = FEEDBACK_REMOVED_FROM_FAVS;
return true;
}
}
}
Use session variable in the ajax request script and using that session variable in page where button exist you can play with button css. for example:
Put this code where Button exists.
$css = "btn_default";
if($_SESSION['btnClicked'] == "success") {
$css = "btn_success";
}
Use $css variable in the button class like--
<button id="fav" value="'.$book->id.'" type="button" class="btn <?php echo $css?>"></button>
This session will manage in the ajax script where in you are adding and deleting favourite.
set session value
$_SESSION['btnClicked'] = 'success'
below the line
$_SESSION["feedback_positive"][] = FEEDBACK_ADDED_TO_FAVS;
and unset the session
unset($_SESSION['btnClicked']);
after the line.
$_SESSION["feedback_negative"][] = FEEDBACK_REMOVED_FROM_FAVS;
I'm making a simple list application and the items should be easy to edit (just clicking on them). It works fine, but I still have a problem at saving the changes to the database, for some reason it doesn't happen. I'm sure it's a code problem, but I haven't been able to find it.
List Page
<input type="hidden" id="hidden" id="hidden" value="">
<ul id="lista">
<?php
$IDllista = 1;
$selectitems = mysql_query ("SELECT * FROM items WHERE IDllista=".$IDllista." ORDER BY posicio ASC") or die (mysql_error());
while ($row = mysql_fetch_array($selectitems))
{
echo'<li class="item" id="';
echo $row['IDitem'];
echo '"><span class="edit" id="span-';
echo $row['IDitem'];
echo '" data="';
echo $row['Text'];
echo '">';
echo $row['Text'];
echo'</span></li>';
}
?>
</ul>
JavaScript
//Call the edit function
$(".edit").live("click", function () {
// Get the id name
var iditem = $(this).parent().attr("id");
var element = this;
var id = element.id;
//New text box with id and name according to position
var textboxs = '<input type="text" name="text' + id + '" id="text' + id + '" class="textbox" >'
//Place textbox in page to enter value
$('#'+id).html('').html(textboxs);
//Set value of hidden field
$('#hidden').val(id);
//Focus the newly created textbox
$('#text'+id).focus();
});
// Even to save the data - When user clicks out side of textbox
$('.edit').focusout(function () {
//Get the value of hidden field (Currently editing field)
var field = $('#hidden').val();
//get the value on text box (New value entred by user)
var value = $('#text'+field).val();
//Update if the value in not empty
if(value != '') {
//Post to a php file - To update at backend
//Set the data attribue with new value
$(this).html(value).attr('data', value);
$.ajax({
type: 'POST',
data: {id: iditem},
url: 'editartext.php'
});
}
// If user exits without making any changes
$(".edit").each(function () {
//set the default value
$(this).text($(this).attr('data'));
});
});
Edit Page
<?php
include_once "../connect.php";
$IDitem = $_POST['id'];
$noutext = "hola";
$actualitza = mysql_query ("UPDATE items SET Text = ".$noutext." WHERE IDitem = ".$IDitem." ");
?>
Quote problem i think. You can use query with single quote like;
"mysql_query("UPDATE items SET Text ='$noutext' WHERE IDitem ='$IDitem'");