I have a feed page on my website (very similar to facebook) that enables me to like and comment on posts. I'm using ajax to update the posts, however, after a like, rather than each individual post reloading, the whole feed does (not the whole page itself, it just returns to the top of the feed).
I believe this is because each post is using a file named feedLikes.php that are all being reloaded rather than just that one specific post. I'm not sure how to only make that one post reload. below is my code.
From feed.php below, you can see i am searching for all the posts within the database. Each one of these posts is given a feedID like so:
$findShouts = $pdo->prepare('SELECT * FROM feed WHERE name IN (SELECT scoutingUsername FROM scout WHERE scoutedUsername =? OR scoutingUsername =?) ORDER BY timestamp DESC');
//execute query and variables
$findShouts->execute([$username, $username]);
if ($findShouts->rowCount() > 0)
{
//get the shouts for each scout
while($row = $findShouts->fetch(PDO::FETCH_ASSOC)){
$shoutID[] = $row['id'];
$shoutUsername[] = $row["username"];
$shoutName[] = $row["name"];
$shoutText[] = $row["text"];
$shoutTimestamp[] = $row["timestamp"];
}
$shoutCount = count($shoutUsername);
for($indexShout=0; $indexShout < $shoutCount; $indexShout++) {
print'
<div class=feedNewShout>
<div class=shoutInformation>
<div class=shoutName>
<p>'. $shoutName[$indexShout] .'</p>
</div>
<div class=shoutTimestamp>
<p>'. timeElapsed("$shoutTimestamp[$indexShout]", 2) .'</p>
</div>
<div class=shoutText>
<p>'. $shoutText[$indexShout] .'</p>
</div>
<input type="hidden" name="feedID" class="feedID" value="'. $shoutID[$indexShout] .'">
<div class=likesAndComments>
<div class=likesAjax data-id="'.$shoutID[$indexShout] .'">
</div>
<div class=commentsAjax data-id="'.$shoutID[$indexShout] .'">
</div>
<div class=deleteShoutAjax data-id="'.$shoutID[$indexShout] .'">
</div>
</div>
</div>
</div>';
}
unset($shoutID);
unset($shoutUsername);
unset($shoutName);
unset($shoutText);
unset($shoutTimestamp);
}
From this i use a jquery Ajax call in feedLikesAjax.js to find each individual feedID needed:
$(document).ready(function()
{
$(".likesAjax").each(function() {
var feedID = $(this).attr("data-id");
$.ajax({
url: "feedLikes.php",
cache: false,
type: "POST",
data: {feedID: feedID},
dataType: "html",
success: function(html){
$(".likesAjax[data-id='"+ feedID +"']").empty();
$(".likesAjax[data-id='"+ feedID +"']").append(html);
}
});
});
});
I use this information and pass it to feedLikes.php:
if (isset($_POST['feedID']))
{
$feedID = ($_POST['feedID']);
$findHasUserLiked = $pdo->prepare('SELECT username FROM feedLikes WHERE feedID =? and username=?');
//execute query and variables
$findHasUserLiked->execute([$feedID, $username]);
if ($findHasUserLiked->rowCount() > 0)
{
$hasUserLiked = $findHasUserLiked->fetchColumn();
echo<<<_END
<form action="feedLikes.php" id="unlikePostForm$feedID" method="post">
<button type="submit" class="unLikeButton"></button>
<input type="hidden" name="feedIDForUnlike" class="feedIDForUnlike$feedID" value="$feedID">
</form>
_END;
?>
<script type="text/javascript">
$(document).ready(function()
{
$('#unlikePostForm<?php echo $feedID ?>').on('submit', function (e) {
e.preventDefault();
var feedIDUnlike = $(".feedIDForUnlike<?php echo $feedID ?>").val();
$.ajax({
url: "feedLikesClicked.php",
cache: false,
type: "POST",
data: {feedIDUnlike: feedIDUnlike},
dataType: "html",
success: function(html){
location.reload();
}
});
});
});
</script>
<?php
}
else
{
echo<<<_END
<form action="feedLikes.php" id="likePostForm$feedID" method="post">
<button type="submit" class="likeButton"></button>
<input type="hidden" name="feedIDForLike" class="feedIDForLike$feedID" value="$feedID">
</form>
_END;
?>
<script type="text/javascript">
$(document).ready(function()
{
$('#likePostForm<?php echo $feedID ?>').on('submit', function (e) {
e.preventDefault();
var feedIDLike = $(".feedIDForLike<?php echo $feedID ?>").val();
$.ajax({
url: "feedLikesClicked.php",
cache: false,
type: "POST",
data: {feedIDLike: feedIDLike},
dataType: "html",
success: function(html){
location.reload();
}
});
});
});
</script>
<?php
}
$likesNumber = $pdo->prepare('SELECT count(*) FROM feedLikes WHERE feedID =?');
//execute query and variables
$likesNumber->execute([$feedID]);
$numberOfLikes = $likesNumber->fetchColumn();
print'
<div class=numberOfLikes data-id="'.$feedID .'">
<p>'. $numberOfLikes .'</p>
</div>';
}
?>
Like i said it all works perfectly apart from the reloading. Now i know the location.reload that is used on success is actually reloading every feedLikes.php for every post. But i'm really stuck on how to just reload the current feedLikes.php post that is needed for that specific post. I thought this would be really simple, and it maybe, but i cant find it anywhere.
Really grateful for any help. Thank you
There are lots of ways to do this. To achieve what you are actually asking you need to modify your jQuery success function to target only the div element for the post you are interested in. Either by adding a unique ID to the HTML, or using a selector based on the class and data-id attributes to identify that specific post.
Then yout PHP needs to only return the HTML which you want to modify and you have your jQuery success function insert that into the div for the relevant post.
Having said that, for what you are trying to do is there really any need to reload the post? You could have your PHP script just return the new number of likes and whether or not current user has liked the post and then update those values in your success call.
You could optimise your code a lot, the feedLikesAjax.js script is calling feedLikes.php once the page is loaded, creating a new ajax request for each post. You could combine the code from feedLikes.php into feed.php and have the server output the page with all the data immediately, and get rid of feedLikesAjax.js altogether. You could replace the likes and unlikes forms with a single button for each post and right now you are setting an event handler for each form individually, if you give them all a common class you can just use a single event handler.
EDIT
To answer your comment:
You don't need another query in your while statement. You can expand your first query using a left join to have it also include data from the feedLikes table in the returned results or you can use another subquery to your original query to add another column to your returned results. Something along the lines of this should give you a userLiked row with a value of 1 or 0 for liked/not liked. You might have to edit it a bit to get it working for you, I'm not an SQL guru by any means.
SELECT *, (SELECT COUNT(L.username) FROM feedLikes L WHERE L.feedID = F.id AND L.username = F.username) AS userLiked
FROM feed F
WHERE name IN (SELECT scoutingUsername FROM scout WHERE scoutedUsername =? OR scoutingUsername =?)
ORDER BY timestamp DESC
Related
I have a drop down on php form, I want to populate guest names in it, which has been done, now I want to load data from table on the basis of value from this drop down and without page refresh/ button submission. How do I do this? I want simple code that could achieve it in one page rather than doing it through multiple pages. The examples I have seen so far are too complicated and when I merge them in my code, they no longer work.
Here is the function which im using onchange of dropdown:
$("#guestname").change(function()
{
var id = $(this).find(":selected").val();
var dataString = 'action='+ id;
$.ajax
({
url: 'billing.php',
data: dataString,
cache: false,
success: function(r)
{
$("#display").html(r);
}
});
})
Here is my billing.php code, it loads values on the basis of first selected value, if I again select value from drop down,it doesn't show the updated record.
<?php
include('config.php');
$action = $_REQUEST['action'];
$stmt=$dbcon->prepare('SELECT discount FROM table_name WHERE name=:name
ORDER BY name');
$stmt->execute(array(':name'=>$action));
}
?>
<div class="row">
<?php
if($stmt->rowCount() > 0){
while($row=$stmt->fetch(PDO::FETCH_ASSOC))
{
extract($row);
?>
You can do it without page refresh but you gonna need another php file, let's name it query.php to get you the result.
On your current page
<select>
<option value='bob'>Bob
<option value='jane'>Jane
</select>
<div id='output'></div>
<script>
$('select').change(function(){
let name = $(this).val();
$.ajax({
url: 'query.php',
method: 'POST',
data: {username: name},
success: function(response){
$('#output').html(response);
}
});
})
In query.php
$username = $_POST['username'];
//query database to get your result
echo json_encode($result);
Kind of a newbie in using PHP/Ajax/SQL.
I am currently working in a small project where in we're asked to create a Facebook-esque website using the languages above. I am trying to create pages wherein the user can view the individual posts and the comments in each post. The user can also post comments on the same page. I also have a database to store the different details needed for the project (posts, user details, comments, etc.)
The data acquired from the page displaying the posts is passed through a GET method. There is also an ajax function for inserting the comment data into my database. The problem is, every time I try to insert the data into the database (through AJAX), the following error appears:
Notice: Undefined index: blog_title in C:\xampp\htdocs\postpage.php on line 24
I also noticed that the data I passed through the GET method disappears when I try to call the AJAX function. What can I do to solve the error?
Post data is acquired through here(line 24):
$blog_title = $_GET['blog_title'];
HTML:
<!DOCTYPE html>
<html>
<head>
<title><?=$blog_title?></title>
</head>
<body>
<div class = "details">
<h2><?=$row['title']?></h2>
<h3>Published by: <a link href = "<?=$location?>"><?=$row['author_name']?></a></h3>
<h4>Date Posted: <?=$row['date']?> at <?=$row['time']?></h4>
</div>
<br>
<p>
<?=$row['content']?>
</p><br><br>
<div class = "commentarea">
<form>
<label>Commenting as: <?=$my_username?></label><br>
<textarea rows = "10" cols = "20" id = "comment" required></textarea>
<button name = "comment" id = "post" onclick="Comment($('#comment').val(), <?=$my_username?>, <?=$blog_title?>)">Submit Comment</button>
</form>
<div>
AJAX Function:
<script src = "js/jquery.js"></script>
<script>
function Comment(comment, username, title){
//alert(search + " " + filter);
$.ajax({
method:"POST",
url:"comment.php",
data:{
"comment":comment,
"commenter_name":username,
"commented_post":title,
},
dataType = "json",
success: function(result){
alert("Comment posted.");
$("#record").html(result);
}
});
}
</script>
Thank you in advance!
In your Ajax call, you are specifying the method as POST. But in your PHP page, you are trying to get the request using $_GET['blog_title'] and that is why you are getting undefined variable error.
Instead of $_GET you should either use $_POST or $_REQUEST. That is, replace
$blog_title = $_GET['blog_title'];
with
$blog_title = $_POST['blog_title'];
or
$blog_title = $_REQUEST['blog_title'];
Read more about $_REQUEST and $_POST in the docs.
OR
you can change your ajax request as below.
$.ajax({
method:"GET", //changed method to GET
url:"comment.php",
data:{
"comment":comment,
"commenter_name":username,
"commented_post":title,
},
dataType = "json",
success: function(result){
alert("Comment posted.");
$("#record").html(result);
}
});
Like Lal answer, you first need to convert to the GET method, then you need to declare the blog_title parameter.
<script src = "js/jquery.js"></script>
<script>
function Comment(comment, username, title){
//alert(search + " " + filter);
$.ajax({
method:"GET", // Changed method to GET
url:"comment.php",
data:{
"comment":comment,
"commenter_name":username,
"commented_post":title,
"blog_title":title //You must declare the blog_title parameter here
},
dataType = "json",
success: function(result){
alert("Comment posted.");
$("#record").html(result);
}
});
}
</script>
i have a feed page which loads posts (known as 'shouts' in my code) from a database based on who the user is following ('scouting' in my code). The basic information is displayed correctly. However, in each post i would like to load a separate file using ajax which will control the likes of the post. Below is my PHP for the feed page:
$findShouts = $pdo->prepare('SELECT * FROM feed WHERE name IN (SELECT scouting FROM scout WHERE scouted =? OR scouting =?) ORDER BY timestamp DESC');
//execute query and variables
$findShouts->execute([$username, $username]);
if ($findShouts->rowCount() > 0)
{
//get the shouts for each scout
while($row = $findShouts->fetch(PDO::FETCH_ASSOC)){
$shoutID[] = $row['id'];
$shoutUsername[] = $row["username"];
$shoutName[] = $row["name"];
$shoutText[] = $row["text"];
$shoutTimestamp[] = $row["timestamp"];
}
$shoutCount = count($shoutUsername);
for($indexShout=0; $indexShout < $shoutCount; $indexShout++) {
print'
<div class=feedNewShout>
<div class=shoutInformation>
<div class=shoutName>
<p>'. $shoutName[$indexShout] .'</p>
</div>
<div class=shoutTimestamp>
<p>'. timeElapsed("$shoutTimestamp[$indexShout]", 2) .'</p>
</div>
<div class=shoutText>
<p>'. $shoutText[$indexShout] .'</p>
</div>
<input type="hidden" name="feedID" class="feedID" value="'. $shoutID[$indexShout] .'">
<div class=likesAjax>
</div>
</div>
</div>';
}
unset($shoutID);
unset($shoutUsername);
unset($shoutName);
unset($shoutText);
unset($shoutTimestamp);
}
In each post the div class=likesAjax performs an ajax call which sends the hidden $feedID to feedlikes.php.
feedLikes.js
$(document).ready(function()
{
var feedID = $(".feedID").val();
$.ajax({
url: "feedLikes.php",
cache: false,
type: "POST",
data: {feedID: feedID},
dataType: "html",
success: function(html){
$(".likesAjax").empty();
$(".likesAjax").append(html);
}
});
});
feedLikes.php
if (isset($_POST['feedID']))
{
$feedID = ($_POST['feedID']);
echo "$feedID";
}
the problem i have is that i can see the ajax goes through every post and echos the feedID, however, every time a new call is made, all the feedID's change to the same thing. I know this is because my success call in my ajax updates every likesAjax class to the same thing. So whatever the feedID is of the last post, will be displayed for all of them.
My question is, how can i load feedLikes.php so that every post is shown with its own $feedID?
Note, feedLikes.php will eventually do something with the ID, the echo is just for test purposes.
Without changing your codes' logic, in PHP you can add an attribute to each ".likesAjax" box called data-id:
<div class="likesAjax" data-id="'.$shoutID[$indexShout] .'">
Now in jQuery in your ajax success function you can update your selector to look for this attribute as well in order to update the correct ".likesAjax" element:
$(".likesAjax[data-id='"+ feedID +"']").append(html);
To put these all together you would need to loop through your .likesAjax elements. To make your code a little cleaner you should make a function with the feedID as a parameter that will be executed for every step of the loop. This will look like the following:
$(".likesAjax").each(function() {
var feedID = $(this).attr("data-id");
loadFeedLikes(feedID);
});
function loadFeedLikes(feedID) {
$.ajax({
url: "feedLikes.php",
cache: false,
type: "POST",
data: {feedID: feedID},
dataType: "html",
success: function(html){
$(".likesAjax[data-id='"+ feedID +"']").html(html);
}
});
}
If you want to make this lighter you can create a new feedLikes.php that takes all the feedLikes you have and pushes them in an array. This array should contain the content you need and the feedId. Then you would only need one ajax call and with a for loop you could loop through the results and update all the $(".likesAjax") elements at once. This way you will have only one query to your db and only one ajax call to fetch your data.
I have a page with a select list (gets successfully populated from mysql) and a text box. The text box has to be populated with a value from mysql based on the item selected in the list. But the ajax call to php is not working and i can not figure out what the issue is. I am just learning ajax and php, so a novice.. Please help. i am stuck with this for a long time.
<script>
$(document).ready(function() {
$('.selectpicker').on("change", function(){
var selected_data = $(this).find("option:selected").val();
alert(selected_data);
$.ajax ({
type: "POST",
data: { selected_data: selected_data },
url: "getoldcharity.php",
dataType: "json",
success: function(res) {
$('#charity_new').val(data.charity_new);
}
});
});
});
</script>
<form id="assign-fundraiser_form" class="form-horizontal" action="" method="post">
<div class="form-group">
<div class="col-md-3">
<select class="selectpicker form-control" id="fundraiser" name="fundraiser" required>
<option value="" selected disabled>Select a Fundraiser</option>
<?php
include('session.php');
$result1 = mysqli_query($db,"select concat(f_firstname,' ',f_lastname) fundraiser from fundraiser where f_company in (select contractor_name from contractor where company_name = '$_SESSION[login_user]') and f_status = 'Active' order by concat(f_firstname,' ',f_lastname)");
while ($rows = mysqli_fetch_array($result1))
{
echo "<option>" .$rows[fundraiser]. "</option>";
}
?>
</select>
</div>
</div>
<input type="text" name="charity" id="charity_new" />
</form>
<?php
include "session.php";
if (ISSET($_POST['.selectpicker'])) {
$ref = $_POST['.selectpicker'];
$query = $db->query("select f_charity charity_new from fundraiser limit 1");
$row = $query->fetch_assoc();
$charity_new = $row['charity_new'];
$json = array('charity_new' => $charity_new);
echo json_encode($json);
}
$db->close();
?>
There are a few problems that I've spotted from quick glance, so I've separated them below.
PHP
In your AJAX request, you are using data: { selected_data: selected_data } which means the PHP code will be expecting a POSTed key named selected_data but you're looking for .selectpicker. You seem to have mixed up a couple of things, so instead of:
$_POST['.selectpicker']
it should be:
$_POST['selected_data']
JavaScript
As Ravi pointed out in his answer, you also need to change your success function. The parameter passed through to this function is res not data, so instead of:
$('#charity_new').val(data.charity_new);
it should be:
$('#charity_new').val(res.charity_new);
MySQL
It also appears as though your query itself is invalid - you seem to be missing a comma in the column selection.
select f_charity charity_new from fundraiser limit 1
should be:
select f_charity, charity_new from fundraiser limit 1
or, seeing as you're not using the f_charity column in the results anyway:
select charity_new from fundraiser limit 1
You aren't using the value that is being POSTed either, meaning that whatever option is selected in the dropdown makes no difference to the query itself - it will always return the first record in the database.
Other
One other thing to be aware of is you're using a class selector on your change function. This means if you have multiple dropdowns with the same class name in your HTML, they will all be calling the same AJAX function and updating the textbox. I don't know if this is what you're aiming for, but from your code posted, you only have one dropdown in the form. If you only want that one dropdown to be calling the AJAX function, you should use an ID selector instead:
$('#fundraiser').on("change", function() {
// ...
}
I think, it should be
$('#charity_new').val(res.charity_new);
instead of
$('#charity_new').val(data.charity_new);
I'm currently developing a web app that demonstrates how to "sign" different words in ASL. There's a list of terms on the left, and a video and comment section on the right.
See screenshot here: http://i917.photobucket.com/albums/ad19/brycematheson/Screen%20Shot%202015-06-16%20at%2010.05.36%20PM.png
I'm struggling to get the comments to change using AJAX whenever a new term is clicked. Currently, the comments stay the same as new terms are selected. How would I go about using AJAX to change the comment section to update when a new term is selected?
My comment section looks like so. Updating the $id_post=3 section in PHP will change the comment to match the comments with that ID in the database, so that's not an issue, I just need it to do it on the fly.
Here is my comment code in my index.php page:
<?php
// Connect to the database
require_once('models/db-settings.php');
$id_post = '$_POST['rowID']; //the post or the page id
?>
<div class="cmt-container">
<?php
$sql = mysqli_query($mysqli, "SELECT * FROM comments WHERE id_post = '$id_post' ORDER BY id ASC") or die(mysqli_error($mysqli));
while($affcom = mysqli_fetch_array($sql,MYSQLI_ASSOC)) {
$id = $affcom['id'];
$name = $affcom['name'];
$email = $affcom['email'];
$comment = $affcom['comment'];
$date = $affcom['date'];
// Get gravatar Image
// https://fr.gravatar.com/site/implement/images/php/
$default = "mm";
$size = 35;
$grav_url = "http://www.gravatar.com/avatar/".md5(strtolower(trim($email)))."?d=".$default."&s=".$size;
?>
<div class="cmt-cnt">
<img src="<?php echo $grav_url; ?>" />
<div class="thecom">
<h5><?php echo ucfirst($name); ?></h5><span data-utime="1371248446" class="com-dt"><?php echo $date; ?></span>
<br/>
<p>
<?php echo $comment; ?>
</p>
<div style="float:right;"><span class="action">X</span></div>
</div>
</div><!-- end "cmt-cnt" -->
<?php } ?>
<div class="new-com-bt">
<span>Write a comment ...</span>
</div>
<div class="new-com-cnt">
<textarea class="the-new-com"></textarea>
<div class="bt-add-com">Post comment</div>
<div class="bt-cancel-com">Cancel</div>
</div>
<div class="clearfix"></div>
</div>
And my Javascript:
$('#matrix tr').click(function (event) {
var rowID = ($(this).attr('id')); //trying to alert id of the clicked row
$(function(){
e.preventDefault();
$.ajax({
type: 'POST',
url: 'index.php',
data: rowID,
success: function(msg) {
}
});
});
});
What am I doing wrong? Am I missing something?
Thanks in advance.
You aren't actually doing anything with the page once it's returned to you
success: function(msg) {
}
When the ajax completes successfully the code inside this function will execute, whatever was returned by the page will be inside the msg param.
success: function(msg) {
$('#comments-container').html(msg);
}
This will entirely replace the contents of the element(s) that have id="comments-container" with whatever the ajax request returned.
You might properly read the jQuery AJAX documentation page and study some of the examples. http://api.jquery.com/jquery.ajax/
Once you've fixed that you'll run into a problem where it still won't change, this is because you're not sending properly formatted POST data.
data: rowID,
In order to access the POST data like you are trying to (with $_POST[key]) the POST data also needs to be in key-value pairs.
data: "rowID=" + rowID,
Read the comments on the PHP manual page for the $_POST superglobal for a better understanding of this. http://php.net/manual/en/reserved.variables.post.php
EDIT: Oh and if you're planning on releasing this website to the public you might want to look at SQL Injection and how to harden your websites against it. As it stands this would be pretty easily broken into and your database compromised.