I'm having trouble with a jQuery script for voting on posts. I have a "frontpage" with a list of posts from a mysql db. On each post there is a little votebox you can either vote up or down.
jQuery/ajax script:
<script type="text/javascript">
$(document).ready(function() {
$('.plus-button').click(function(){
var postid = <?php echo $postloopid; ?>;
$('.minus-button').removeClass('disliked');
$(this).toggleClass('liked');
alert(postid);
$.ajax({
type:"POST",
url:"php/votesystem.php",
dataType : 'html',
data:'act=like&postid='+postid,
success: function(data){
$('.plus-button').html(data);
}
});
});
$('.minus-button').click(function(){
var postid = $(this).attr('id');
$('.plus-button').removeClass('liked');
$(this).toggleClass('disliked');
$.ajax({
type:"POST",
url:"php/votesystem.php",
dataType : 'html',
data:'act=dislike&postid='+postid,
success: function(data){
$('.minus-button').html(data);
}
});
});
});
</script>
Votebox.php
<?php
// If postid is from frontpage use $postloopid as $postid
if(isset($postloopid)){
$postid = $postloopid;
}
$postid = htmlentities($postid, ENT_QUOTES);;
include("connect.php");
//For test purposes
echo $postid;
// If user logged in show votebox
if(isset($_SESSION['username'])){
$userid = $_SESSION['userid'];
$sql2 = mysqli_query($connect,"SELECT * FROM posts WHERE id='$postid' AND deleted=0");
if($sql2){
$voterow = mysqli_fetch_assoc($sql2);
$checkupvote = $voterow['upvoters'];
$checkdownvote = $voterow['downvoters'];
$checkupvote = explode(" ",$checkupvote);
$checkdownvote = explode(" ",$checkdownvote);
if($checkupvote = array_search($userid,$checkupvote) == true){
echo '<div class="plus-button liked" name="like">+ ' . $voterow['totalupvotes'] . '</div>';
echo '<div class="minus-button" name="dislike">- ' . $voterow['totaldownvotes'] . '</div>';
}
elseif($checkdownvote = array_search($userid,$checkdownvote) == true){
echo '<div class="plus-button" name="like">+ ' . $voterow['totalupvotes'] . '</div>';
echo '<div class="minus-button disliked" name="dislike">- ' . $voterow['totaldownvotes'] . '</div>';
}
else{
echo '<div class="plus-button" name="like">+ ' . $voterow['totalupvotes'] . '</div>';
echo '<div class="minus-button" name="dislike">- ' . $voterow['totaldownvotes'] . '</div>';
}
}
else {
echo 'No result <br />';
}
}
else {
echo 'Cant find user';
}
?>
Frontpage:
<?php
$sql1 = mysqli_query($connect,"SELECT * FROM posts WHERE totalupvotes < $trendmin AND deleted=0 ORDER BY added DESC LIMIT 0,10");
if($sql1){
while($row = mysqli_fetch_array($sql1)){
$postloopid = $row['id'];
?>
<div id="postlist">
<div style="width:400px; font-size:18px; font-weight:bold;">
<a target="_blank" href="post.php?id=<?php echo $row['id']; ?>"><?php echo $row['title']; ?></a>
</div><br />
<article class="slide"><?php echo nl2br($row['post']); ?></article>
<br />
<?php include("php/votebox.php"); ?>
<br />
by <a style="font-size:18px;" href="profile.php?id=<?php echo $row['submittedby']; ?>"><?php echo $row['submitteduser']; ?></a>
at <span style="font-size:12px;"><?php echo $row['added']; ?></span><span style="float:right; margin-right: 10px;"><a target="_blank" href="post.php?id=<?php echo $row['id']; ?>#commentfield"><?php echo $row['totalcomments']; ?> comments</a></span>
</div>
<?php
}
}
?>
The problem now is that when I click the votebox buttons it turns out I only get the postid from the first loaded post from the while loop. Another problem I have is that my total up- and downvotes changes in all the posts on the list, not the specific post.
Any ideas?
The Javascript code isn't in the loop, it can't reference postloopid. Or if it is, you're binding all buttons of the class every time through the loop, and clicking on them will run all the handlers, incrementing all the posts.
You should put the post ID as a data field in the button, and then access that from the Javascript:
echo '<div class="plus-button liked" data-postid="'+$postid+'" name="like">+ ' . $voterow['totalupvotes'] . '</div>';
echo '<div class="minus-button" data-postid="'+$postid+'" name="dislike">- ' . $voterow['totaldownvotes'] . '</div>';
Then your Javascript can do:
$('.plus-button').click(function(){
var postid = $(this).data('postid');
$(this).siblings('.minus-button').removeClass('disliked');
$(this).toggleClass('liked');
alert(postid);
$.ajax({
type:"POST",
url:"php/votesystem.php",
dataType : 'html',
data:'act=like&postid='+postid,
context: this,
success: function(data){
$(this).html(data);
}
});
});
I made the following changes to the JS:
Use $(this).data('postid') to get postid.
Only remove the disliked class from the sibling minus button, not all minus buttons on the page.
Put the returned HTML just in this element, not in all plus buttons. I pass this in the context: parameter, so that the success function can refer to it.
Alright lets go through your jQuery code(just the like function):
Bind click handler to all elements with the class plus-button
$('.plus-button').click(function(){
var postid = <?php echo $postloopid; ?>;
Remove disliked class from all elements with class minus-button
$('.minus-button').removeClass('disliked');
$(this).toggleClass('liked');
alert(postid);
$.ajax({
type:"POST",
url:"php/votesystem.php",
dataType : 'html',
data:'act=like&postid='+postid,
success: function(data){
Set inner html of all elements with class plus-button
$('.plus-button').html(data);
}
});
});
What you want is to store the postid as an attribute on the posts, then use
var postid = $(this).attr('postid')
only remove the disliked class from the current element
$(this)
.parents('{element containing plus and minus button}')
.find('.minus-button')
.removeClass('disliked')
;
store reference to the clicked element
var $this = $(this); // Cool guys do this right in the beginning and use only this variable instead of $(this)
then in your ajax success handler you want to set only the html of the button you clicked, so you may use the reference you stored in the parent function scope
$this.html(data);
EDIT in regards to infinite scroll script
When parts of your page are dynamic, you want to bind the click handler to a static parent element of the dynamic content using:
$("#postsParent").on('click', '.plus-button', function () {/*handler*/})
Related
Currently, if no images have been clicked, I get my selected image like this and it's also what's shown on first page load.
$pictures = Picture::getPictures($album->getId());
$selectedPicture = $pictures[0];
It selects the first picture and display it like this:
<img src="<?php echo $selectedPicture->getOriginalFilePath($user->getId()); ?>" >
I am trying to change the selected image when a user clicks on a different thumbnail because this is just one of many images of an album.
Attempt with a ajax, I'm not really experienced with it so I couldn't get it to work
<script type="text/javascript">
function Func() {
$.ajax({
type: "POST",
url: "RefreshImage.php",
success: function (json) {}, error: function () {}
})
}
</script>
Then the php portion also has something like to create the thumbnails so that a user can clicks on one, it displays the image. But I'm not sure how to do that.
foreach ($pictures as $pic) {
$output.= "<a href='" . $pic->getOriginalFilePath($user->getId()) . "'> <img style='width:120px;height:120px' "
. "src='" . $pic->getThumbnailFilePath($user->getId()) . "'"
. "name='" . $pic->getFileName() . "' "
. "onClick='Func'></a>";
}
RefreshImage.php content
session_start();
$user = $_SESSION['user'];
//$albums = Album::getAlbums($user->getId());
if (isset($_POST["chosenAlbid"])) {
$album_id = $_POST["chosenAlbid"];
$user = $_SESSION['user'];
$album = Album::getAlbumById($user->getId(), $album_id);
$pictures = Picture::getPictures($album->getId());
$selectedPicture = $pictures[1];
}
?>
<div id="imagecontainer">
<div>
<p style="float: left;"><img style="width:500px;height:400px" src="<?php echo $selectedPicture->getOriginalFilePath($user->getId()); ?>" ></p>
<p><span>
<h4> Description</h4>
</span><?php echo $selectedPicture->getDescription() ?></p>
</div>
</div>
If you rewrite your function into jQuery it will be more easy.
From this
function Func() {
$.ajax({
type: "POST",
url: "RefreshImage.php",
success: function (json) {}, error: function () {}
})
}
To jQuery
$('a[data-refresh-img]').click(function(e) {
e.preventDefault(); // block ahref redirect
$('#imagecontainer img').attr('src', $(this).attr('href')); // replace image
);
Then activate function add data-refresh-img attribute on a tag.
And all will work for you.
JSFIDDLE
** UPDATE **
If you need replace any data with image you can do this
<a data-refresh-img href="original_img_path">
<img
title="picture one"
src="thumbnail_img_path" height=50>
<span style="display: none"><?php echo $selectedPicture->getDescription() ?> AAA</span>
</a>
And change function to
$('a[data-refresh-img]').click(function(e) {
e.preventDefault(); // block ahref redirect
$('#imagecontainer img').attr('src', $(this).attr('href')); // replace image
$('#imagecontainer img').attr('title', $(this).find('img').attr('title')); // replace title
$('#imagecontainer span[data-description]').html($(this).find('span').html()); // replace description
});
JSFIDDLE 2
I successfully fetch the data from the database. The problem is that, I want to display the results using Ajax request. The results/Output which displayed twice, I mean the *first output which displayed through Ajax (#the bottom of index.php), and the Second output displayed through PHP ECHO (**#**the bottom of the page). What can I do to get a single output through Ajax without adding another file and without refreshing the page?
index.php
<head>
<script src="https://code.jquery.com/jquery-3.1.1.js"></script>
<script type="text/javascript" src="javas.js"></script>
</head>
<body>
<div id="table_content"></div>
<?php
include ("db.php");
error_reporting(~E_NOTICE);
function ShowForm($AnswerCommentId) {
echo '<form id="myForm">';
echo '<input id="user" name="user" />';
echo '<textarea id="text" name="text"></textarea>';
echo sprintf('<input id="ParentId" name="ParentId" type="hidden" value="%s"/>', ($AnswerCommentId));
echo '<button type="button" OnClick=SendComment()>Comment</button>';
echo '</form>';
}
$query="SELECT * FROM `comm` ORDER BY id ASC";
$result = mysqli_query($conn,$query);
if (isset($_REQUEST['AnswerId'])) $AnswerId = $_REQUEST['AnswerId'];
else $AnswerId = 0;
$i=0;
while ($mytablerow = mysqli_fetch_row($result)){ $mytable[$i] = $mytablerow; $i++; }
function tree($treeArray, $level, $pid = 0) {
global $AnswerId;
foreach($treeArray as $item){
if ($item[1] == $pid){
echo sprintf('<div class="CommentWithReplyDiv" style="margin-left:%spx;">',$level*60);
echo sprintf('<p>%s</p>', $item[2]);
echo sprintf('<div>%s</div>', $item[3]);
if ($level<=2) echo sprintf('Reply', $item[0]);
if ($AnswerId == $item[0]) echo sprintf('<div id="InnerDiv">%s</div>', ShowForm($AnswerId));
echo '</div><br/>';
tree($treeArray, $level+1, $item[0]); // Recursion
}
}
}
tree($mytable,0,0);
?>
Comment
<div id="MainAnswerForm" style="display:none;width:40%; margin:0 auto;"><?php ShowForm(0); ?></div>
<div id="AfterMainAnswerForm"></div>
<script>
$(document).ready(function(){
$("#Link").click(function () {
$("#InnerDiv").remove();
$("#MainAnswerForm").slideToggle("normal");
return false;
});
});
</script>
</body>
Page.php
<?php
include ("db.php");
$user = $_POST['user'];
$text = $_POST['text'];
$ParentId = $_POST['ParentId'];
$action = $_POST['action'];
if ($action=="add") $query= mysqli_query($conn,"INSERT into `comm` VALUES (NULL,'{$ParentId}','{$user}','{$text}',NOW())");
?>
Javas.js
function show_messages(){
$.ajax({
url: "index.php",
cache: false,
success: function(html){
$("#table_content").html(html);
}
});
}
function AnswerComment (id){
$.ajax({
type: "POST",
url: "index.php",
data: "AnswerId="+id,
success: function(html){
$("#table_content").html(html);
}
});
}
function SendComment (){
var user1 = $("#user").val();
var text1 = $("#text").val();
var ParentId1 = $("#ParentId").val() + "";
$.ajax({
type: "POST",
url: "page.php",
data: "user="+user1+"&text="+text1+"&ParentId="+ParentId1+"&action=add",
success: function(html){
show_messages();
}
});
return false;
}
OK I think its more simple than you think
while you're using .html() it should change all the content of your div but while you're using <div id="table_content"></div> then the <?php ?> your code will show both - one appended to the div and under it the one which echoed by php ... so instead of using
<div id="table_content"></div>
<?php ?>
just wrap the <?php ?> inside the div
<div id="table_content">
<?php ?>
</div>
Alternative way: by using jquery wrapAll() but while Id must be unique you'll need to .remove() the #table_content element first then wrap all your code inside a new #table_content div .. see the example below
$(document).ready(function(){
$('#table_content').remove();
$('.CommentWithReplyDiv').wrapAll('<div id="table_content"></div>');
});
#table_content{
margin : 50px;
background : red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="table_content"></div>
<div class="CommentWithReplyDiv">1</div>
<div class="CommentWithReplyDiv">2</div>
<div class="CommentWithReplyDiv">3</div>
<div class="CommentWithReplyDiv">4</div>
This first part isn't having any issues now.
<?php
session_start();
while($row = $result->fetch_assoc()){
echo "<div id='name' style='margin-top:50px;'><h2>" . $row['name'] . "</h2>";
echo "<a href='nextPage.php'><img class='pic' src='".$row['imageURL']."' data-id='".$row['id']."' height='100px'/></a></div>";
echo "<div id='bio' style='border-bottom:1px solid #000;'><p>" . $row['bio'] . "</p></div>";
}
?>
<script type="text/javascript">
$(document).on('click', '.pic', function(){
var id = $(this).data('id');
$.ajax({
type: 'POST',
url: 'setSession.php',
data: {myId: id}
});
});
</script>
After I click an image I just get php error messages telling me there is an undefined variable. I currently have 'setSession.php' as a separate page, not sure if it's supposed to be or not.
**Next Page**
<?php
session_start();
include("connect.php");
$result = mysqli_query($con, "select * from table");
mysqli_close($con);
?>
<!doctype html>
<html>
<head>
<title></title>
</head>
<body>
<div class="wrapper">
<img src="<?php echo $row['imageURL'];?>" height="200px"/><br/>
<div class="textSection" style="text-align:center;">
<h2><?php echo $row['name'];?></h2>
<p>
<?php echo $row['bio'];?>
</p>
</div>
</div>
</body>
</html>
firstly, you should start session in that page like this.
session_start();
then access the session variable like this.
$_SESSION['your_key_here'];// this will return the value stored in session.
Put data attribute data-id on img tag and change ids into class since ids should be unique like so :
<img class='pic' src='" . $row['imageURL'] . "' data-id='" . $row['id'] . "' height='100px'/></a></div>";
And register click handler to img using its class together with AJAX request to set data id into session variable like so :
$(document).on('click', '.pic', function() {
var id = $(this).data('id'); // get id value from data-id attribute
$.ajax({
type : 'POST',
url : 'setSession.php',
data : {
myId : id
},
success : function(msg) { /* do something here for success request */ }
});
});
Finally. in setSession.php page :
<?php
session_start();
$_SESSION['id'] = $_POST['myId']; // this come from ajax request
echo "something"; // and this will available on ajax success callback
?>
My project is a kind of blog, with posts and comments area. I'm trying to make it async with jquery ajax. My problem is that when a new comment gets inserted asynchronously it appears in the div twice, and all the other comments disappear. If i refresh the page it looks fine.
VIEW:
<section id="comments_section_<?php echo $p1['post_id'];?>"> //THIS IS THE OUTPUT WHERE NEW COMMENTS WILL BE APPENDED
<?php
$data['comments'] = $this->model_mutamba->getComments($p1['post_id']);
if($data['comments'] != ""){ ?>
<div class="comments_container" id="comments_container_<?php echo $p1['post_id'];?>">
<?php foreach ($data['comments'] as $c){
$user_img3 = $this->model_mutamba->getUserPicId($c->aluno_id);
?>
<div>
<img style="height:32px;" src="<?php echo site_url();?>img/users/portfolio/<?php echo $user_img3;?>" alt="" class="align-left" />
<p>
<?php echo $this->model_mutamba->addSmilies($c->comment);?>
<br>
<span class="comments_date">
<?php
$c_date = explode('-', substr($c->comment_date,0,-8));
$date_num_word = monthNumToWords($c_date[1]);
echo substr($c->comment_date, 11,-3)." ".$c_date[2]." de ". $date_num_word . " ". $c_date[0];?>
</span>
</p>
</div>
<?php } ?>
</div>
<?php } ?>
</section>
JS:
function comment(post_id,input){
var comment = $(input).val();
var output = '#comments_section_'+post_id;
if(comment != ""){
$.ajax({
type:"POST",
url:base_url+"mutamba/insertNewComment",
data: {comment: comment, post_id:post_id},
cache:false,
success:function(response){
$(output).html(response);
$(output).append(response);
}
});
}
}
CONTROLLER:
function insertNewComment(){
if($this->session->userdata('is_logged_in')){
$email= $this->session->userdata('email');
$comment= $this->FilterData($this->input->post('comment'));
$post_id= $this->FilterData($this->input->post('post_id'));
$this->load->model('model_mutamba');
if($this->model_mutamba->insertNewComment($email,$comment,$post_id)){
$this->load->model('model_user');
$count = $this->model_mutamba->countPostComments($post_id);
?>
<script>
var count = '<?php echo $count;?>';
var comments_count = '<?php echo "#comments_count_".$post_id;?>';
var content = "";
if(count == 1){
content = '<span class="comments_count">'+count+'</span> Comentário';
}else{
content = '<span class="comments_count">'+count+'</span> Comentários';
}
$(comments_count).html(content);
</script>
<?php
$this->load->model('model_user');
$user_img = $this->model_user->getUserPic($email);
echo '
<div>
<img style="height:32px;" src="'.site_url().'img/users/portfolio/'.$user_img.'" alt="" class="align-left" />
<p>
'.$this->model_mutamba->addSmilies($comment).'
<br>
<span class="comments_date">';
$date = date(date('Y-m-d H:i:s'));
$c_date = explode('-', substr($date,0,-8));
$date_num_word = monthNumToWords($date[1]);
echo substr($date, 11,-3)." ".$c_date[2]." de ". $date_num_word . " ". $c_date[0].'
</span>
</p>
</div>';
}
}else{
redirect("inicio");
}
}
Will appreciate any help,
Thanks in advance
This is happening because in your AJAX success callback, you are adding response to the output TWICE - once with .html() and then again with .append().
.html(response) removes the previous HTML in your webpage, thats why you dont see other comments and it adds response to it.
With .append(response), it is adding response to the bottom of the div, that is the reason you are seeing the response twice!
Remove $(output).html(response) from the success callback and it will work fine.
So, your function needs to look like this:
function comment(post_id,input){
var comment = $(input).val();
var output = '#comments_section_'+post_id;
if(comment != ""){
$.ajax({
type:"POST",
url:base_url+"mutamba/insertNewComment",
data: {comment: comment, post_id:post_id},
cache:false,
success:function(response){
$(output).append(response);
}
});
}
}
function comment(post_id,input){
var comment = $(input).val();
var output = '#comments_section_'+post_id;
if(comment != ""){
$.ajax({
type:"POST",
url:base_url+"mutamba/insertNewComment",
data: {comment: comment, post_id:post_id},
cache:false,
success:function(response){
//$(output).html(response); //Comment this line or the line below it.
$(output).append(response);
}
});
}
}
<div id="appenddiv">
<h1>append</h1>
</div>
<script type="text/javacript">
$("#appenddiv").append('<b>hello world</b>');
</script>
I am trying to fix this issues from last two days but :(
Now I have a index.php page where I am displaying all the data of adds from database.
this is my index page
<html>
<head>
<script>
$(document).ready(function(){
var overlayclass = $("<div id='overlayclass'></div>");
//pagination starts
$("#pagination li:first")
.css({'color' : '#FF0084'}).css({'border' : 'solid #dddddd 10px'});
$("#page").load("Controller/pagination_data_all_adds.php?page=1");
//Pagination Click
$("#pagination li").click(function(){
//CSS Styles
$("#pagination li")
.css({'color' : '#FF0084'})
.css({'border' : 'none'});
$(this)
.css({'border' : 'solid #dddddd 10px'})
.css({'color' : '#0063DC'});
//Loading Data
var pageNum = this.id;
$("#page").load("Controller/pagination_data_all_adds.php?page=" + pageNum);
});
//pagination ends
//for closing the div
$(".close").click(function () {
$(".divpopup").hide();
overlayclass.appendTo(document.body).remove();
return false;
});
//for close image
$(".x").click(function () {
$(".divpopup").hide();
overlayclass.appendTo(document.body).remove();
return false;
});
//onclick on button display div and overlay with button value and post the value to the index page where I can use it to select the specific adds data from database
$(':submit').live('click',function () {
var id = $(this).val();
overlayclass.show();
overlayclass.appendTo(document.body);
$(".divpopup").show('slow');
$.ajax({
url: 'index.php',
data:'button=' + $(this).val(),
dataType: 'json',
succss: function(data)
{
$('.divpopup').html('');
alert(data);
$('.divpopup').append('button:'+data);
}
});
return false;
});
});
</script>
</head>
<body>
<div class="divpopup">
<div class="divcontent">
<img src="http://www.catalyst-gc.com/images/icon_close_window.jpg" alt="icon_close_window"
class="x" id="imgclose" />
<div class="detail_data">
<?php
print "<h1>".$button."</h1>";
?>
</div>
Close
</div>
</div>
<div id="page"></div>
<ul id="pagination">
<?php
//Pagination Numbers
for($i=1; $i<=$pages; $i++)
{
echo '<li id="'.$i.'"-->'.$i.'';
}
?>
</ul>
<!--Pagging display ends -->
</body>
</html>
This is my pagination_data_all_adds page which will be load through jQquery load function in index page. inside page div. and the button which is inside table will be click to display the popupdiv with id of adds and than I will use it to display the rest of the data.
<?php include_once('dbconn.php');
$per_page = 6;
if($_GET)
{
$page=$_GET['page'];
}
$start = ($page-1)*$per_page;
$sql = "select * from adds order by add_id limit $start,$per_page";
$result = mysql_query($sql);
echo "<table cellspacing='0'>";
echo "<thead>";
echo "<th></th>";
echo "<th>Advertise</th>";
echo "<th>Title</th>";
//echo "<th>Description</th>";
echo "<th>Price</th>";
echo "</thead>";
while ($adds = mysql_fetch_array($result)) {
echo "<tbody>";
echo "<tr class='even'>";
$image_link = $adds["image"];
echo "<td><img class='image' src=adds_images/".$image_link."></td>";
echo "<td><b>".$adds["add_type"] . "</b></td>";
echo "<td><b>".$adds["add_title"] ."</b></td>";
echo "<td><b>".$adds["add_price"] ."</b></td>";
echo "<td>";
echo "<form method='post' action=''>"
echo "<button class='button' value='".$adds['add_id']."' type='submit'>Detail!</button>";
echo "</form>";
echo"</td>";
echo "</tr>";
echo "</tbody>";
}
echo "</table>";?>
Now the problem is when I click on the button which is page div it display nothing but when I look at Firebug response it shows there. It does not display when I click the button.
Your dataType in ajax call is json.
$.ajax({
url: 'index.php',
data:'button=' + $(this).val(),
dataType: 'json', <--------------------------------- JSON
But you are returning html.
echo "<table cellspacing='0'>";
echo "<thead>";
echo "<th></th>";
echo "<th>Advertise</th>";
..........................
..........................
Hence your call is actually failing (Which you could have spotted had you used fail).
So answer is return json or change data type.
N.B.
LOTS AND LOTS OF deprecated function. use .on instead of live. use .done instead of success. use mysqli/pdo instead of mysql.
if($_GET)
{
$page=$_GET['page'];
}
You need to use isset or empty that too on approriate index. $_GET is always set. So checking its existance is futile. You need to check the index. i.e.
if(isset($_GET['page']))
again echoing what #itachi has said, pass json data from your php. your js script is waiting for json object yet you passing html file.
to use your code the way it is comment out this line from your JavaScript //dataType: 'json',.
i would also encourage you to use jquery dataTables to save time. take a look at it here