This is a toggle of a ‘follow-unfollow’ button of a Twitter like following system. When the button has the class unfollow it takes two clicks to trigger to fire. When the button has the class follow it fires in one click. This is related to the if statement. If the script does not need to run through the if statement it fires well on one click which is the part of the else section of the script. It is worth noting, that when two clicks are needed, if there is no refresh in the page, you then can toggle back and forth with just one click as it is supposed to be. Do you know how can I avoid using two clicks when the script needs to go through the if statement?
Thanks in advance.
<button class="followUnfollow" id="boton<?php echo $member->id; ?>" type="button" data-member_id="<?php echo $member->id; ?>" user_id="<?php echo $id;?>"> <?php echo $status; ?> </button>
<script>
$(document).ready(function() {
$("#boton<?php echo $member->id; ?>").on('click', function() {
var memberId = $(this).attr('data-member_id');
var userId = $(this).attr('user_id');
if($("#boton<?php echo $member->id; ?>").hasClass('unfollow')) { // TWO CLICKS TO FIRE
$.get("follow_actions.php", {unfollow_id:memberId, user_id:userId} , function(data) {
});
$(this).html('follow');
$(this).removeClass('unfollow').addClass('follow');
} else { // WORKS WELL, ONE CLICK TO FIRE
$.get("follow_actions.php", {follow_id:memberId, user_id:userId} , function(data) {
});
$(this).html('unfollow');
$(this).removeClass('follow').addClass('unfollow');
}
});
});
</script>
Related
I have been working on Like and Unlike feature with jquery, ajax and php. My problem is little bit difficult to understand. Lets try to understand it first.
I have 2 php pages, viewProfile.php and LikeMail.php. LikeMail.php is being called by ajax function in viewProfile.php.
Here is Section of viewProfile.php page's description
-----------------
| Like/Unlike |
-----------------
Here is button which actually comes from LikeMail.php by this ajax function
function like()
{
var req = new XMLHttpRequest();
req.onreadystatechange = function()
{
if(req.readyState==4 && req.status==200)
{
document.getElementById('Like').innerHTML=req.responseText;
}
}
req.open('POST','LikeMail.php','true');
req.send();
}
setInterval(function(){like()},1000);
HTML:
<div id="Like"></div>
Output is being shown here in this div. Button above may be Like or Unlike depends on the condition in LikeMail.php which will be described below in LikeMail.php description section.
When one of them (buttons) Like or Unlike is clicked. It then calls respective jquery click function which sends post request to LikeMail.php.I have mentioned Indirect page in title because Like or Unlike buttons actually exists in LikeMail.php page. But due to ajax call these buttons are being shown in viewProfile.php page. So I then send post requests through viewProfile.php to actual page LikeMail.phpIt is jquery post for Unlike button
$(document).ready(function(){
$('#Unlike').unbind().click(function(){
$.post("LikeMail.php",
{Unlike: this.id},
function(data){
$('#response').html(data);
}
);
});
});
It is jquery post or Like button
$(document).ready(function(){
$('#Like').unbind().click(function(){
$.post("LikeMail.php",
{Like: this.id},
function(data){
$('#response').html(data);
}
);
});
});
End of description section of viewProfile.php page
Here is Section of LikeMail.php page's description
Like or Unlike button is shown in viewProfile.php page depends upon this code:
$check_for_likes = mysqli_query($conn, "SELECT * FROM liked WHERE user1='$user1' AND user2='$user2'");
$numrows_likes = mysqli_num_rows($check_for_likes);
if (false == $numrows_likes) {
echo mysqli_error($conn);
}
if ($numrows_likes >= 1) {
echo '<input type="submit" name="Unlike" value="Unlike" id="Unlike" class="btn btn-lg btn-info edit">';
}
elseif ($numrows_likes == 0) {
echo '<input type="submit" name="Like" value="Like" id="Like" class="btn btn-lg btn-info edit">';
}
Button depends upon these two above conditions.
Now when Like button is clicked, post request from viewProfile.php comes here
if(isset($_POST['Like'])) //When Like button in viewProfile.php is clicked then this peace of code inside if condition should run and insert some record in database
{
$total_likes = $total_likes+1;
$like = mysqli_query($conn, "UPDATE user SET user_Likes = '$total_likes' WHERE user_id = '$user2'");
$user_likes = mysqli_query($conn, "INSERT INTO liked (user1,user2) VALUES ('$user1','$user2')");
$query3 = "INSERT INTO notification (user1, user2, alert, notificationType) VALUE ('$user1','$user2','unchecked','like')";
if (mysqli_query($conn, $query3)) {
echo "Like";
} else {
echo mysqli_error($conn);
}
}
Similarly when Unlike button is clicked. This peace of code should run.
if(isset($_POST['Unlike'])) //This is the condition for Unlike button. It should delete record from databse
{
$total_likes = $total_likes-2;
$like = mysqli_query($conn, "UPDATE user SET user_Likes='$total_likes' WHERE user_id='$user2'");
$remove_user = mysqli_query($conn, "DELETE FROM liked WHERE user1='$user1' AND user2='$user2'");
$query3 = "DELETE FROM notification WHERE user1='$user1' AND user2='$user2' AND notificationType='like'";
$check = mysqli_query($conn, $query3);
if ($check) {
echo "Unlike";
} else {
echo mysqli_error($conn);
}
}
Problem:
Main problem which I faced is that when I click Like or Unlike both executes the condition of Like button code. Both inserts the data into database as Unlike condition should delete data from database but it also inserts data as condition for Like button do. Kindly can you please help me that how to tackle this problem. Thanks in advance!
Update:When I delete all the respective code for Like button. The condition for Unlike button starts working correctly.
I think there's a duplicated ID somewhere, perhaps the DIV. Take a look at this.
<div id="Like_2"></div>
<input type="submit" name="Unlike" value="Unlike" id="Unlike" class="btn btn-lg btn-info edit">
<input type="submit" name="Like" value="Like" id="Like" class="btn btn-lg btn-info edit">
<div id="response"></div>
$(document).ready(function(){
$(document).on('click','#Unlike', function(){
$('#response').html(this.id);
//ajax call
});
$(document).on('click','#Like', function(){
$('#response').html(this.id);
//ajax call
});
});
And the javascript function:
function like()
{
var req = new XMLHttpRequest();
req.onreadystatechange = function()
{
if(req.readyState==4 && req.status==200)
{
document.getElementById('Like_2').innerHTML=req.responseText;
}
}
req.open('POST','LikeMail.php','true');
req.send();
}
setInterval(function(){like()},1000);
https://jsfiddle.net/wx38rz5L/2103/
I have built a follow/unfollow Twitter like system using PHP. With help of this forum I have been successful creating a dynamic button that allows you to “follow” or “unfollow” each user, using AJAX/JQUERY to run the PHP/MySQL code in the back and avoid refreshing the page when the action happens. The thing is that I am able to run this script on the background only once. Let’s say a user unfollows a member by mistake (my AJAX/JQUERY script won’t have any problem with that), but then wants to follow him again, this is where I am stuck. The page will have to be refresh to make this happen. I know this is happening due to the PHP dynamic data that I am using as you will see in my code.
In the PHP code am running an iteration that output all the members in the database. I am outputting here (for simplicity) just the member’s name and a follow/unfollow button to each one. The php variable $what_class is the result of a PHP function that looks into the database to determine if the user is following or not that member. $what_class will output the strings “follow” of “unfollow” so the class can be defined, and then be targeted by either of the two the Jquery scripts.
PHP CODE
<?php foreach($members as $member){ ?>
<p class="member_name"><?php echo $member->name; ?></p>
<button class="<?php echo $what_class; ?>" type="button" data-member_id="<?php echo $member->id; ?>" user_id="<?php echo $id;?>" ><?php echo $what_class; ?></button>
<?php } ?>
Below is the JQUERY scripts, as mentioned before, the button class will be defined by PHP through $what_class. This is the problem when trying to re-use the button after the first time, class won´t change in PHP’s $what_class unless the page is refreshed. I tried to use $(this).removeClass('unfollow').addClass('follow') to change the class using Jquery and have the button to be re-usable but it isn’t working.
JQUERY SCRIPTS TO FOLLOW OF UNFOLLOW
<script type="text/javascript">
$(document).ready(function() {
$("button.unfollow").on('click', function() {
var memberId = $(this).attr('data-member_id');
var userId = $(this).attr('user_id');
$.get("follow_actions.php", {unfollow_id:memberId, user_id:userId} , function(data) {
});
$(this).html('follow');
$(this).removeClass('unfollow').addClass('follow');
});
});
</script>
<script type="text/javascript">
$(document).ready(function() {
$("button.follow").on('click', function() {
var memberId = $(this).attr('data-member_id');
var userId = $(this).attr('user_id');
$.get("follow_actions.php", {follow_id:memberId, user_id:userId} , function(data) {
});
$(this).html('unfollow');
$(this).removeClass('follow').addClass('unfollow');
});
});
</script>
Does anyone knows how I accomplish having a reusable button without reloading the page? I thank you in advance.
Previous Answer:
What I do for that kind of scenario is to have two buttons. One will be shown to the user, and the other one will be hidden.
<button class="follow" data-member_id="<?php echo $member->id; ?>" user_id="<?php echo $id;?>" >Follow</button>
<button class="unfollow" style="display:none" data-member_id="<?php echo $member->id; ?>" user_id="<?php echo $id;?>" >Unfollow</button>
Just tweak your php code what to show and what not.
When a button is click, hide this button and show the other one.
$(document).ready(function(){
$(".follow").on("click", function(){
$(".follow").hide(200);
$(".unfollow").show(200);
/* PUT YOUR OTHER PROCESSES HERE */
});
$(".unfollow").on("click", function(){
$(".follow").show(200);
$(".unfollow").hide(200);
/* PUT YOUR OTHER PROCESSES HERE */
});
});
Check this JSfiddle.
Update:
We can use toggleClass() of jQuery.
<button class="follow" data-member_id="12" user_id="12">Follow</button>
And the script:
$(document).ready(function(){
$(".follow, .unfollow").on("click", function(){
var memberId = $(this).attr('data-member_id');
var userId = $(this).attr('user_id');
$(".follow, .unfollow").toggleClass("follow unfollow");
$(this).text(function(i, text){
return text === "Follow" ? "Following" : "Follow";
});
});
});
Check this JSfiddle.
use <button class="followUnfollow <?php echo $what_class; ?>"
You need to write as less code as possible. Have a common class such as followUnfollow and then check if follow class exists within this element using hasClass function from jQuery.
Have a look at the code below.
<script type="text/javascript">
$(document).ready(function() {
$("button.followUnfollow").on('click', function() {
var memberId = $(this).attr('data-member_id');
var userId = $(this).attr('user_id');
if($(this).hasClass('follow')) { // FOLLOW
$.get("follow_actions.php", {follow_id:memberId, user_id:userId} , function(data) {
});
$(this).html('unfollow');
$(this).removeClass('follow').addClass('unfollow');
} else { // UNFOLLOW
$.get("follow_actions.php", {unfollow_id:memberId, user_id:userId} , function(data) {
});
$(this).html('follow');
$(this).removeClass('unfollow').addClass('follow');
}
});
});
</script>
I'm making a vote system thats using images and whenever you click one of the images, it will submit that one, and then it fades out and reloads it using a php page. Problem is, the first submit works, but once it reloads, clicking on the images does nothing. Not even an alert which I've tested.
vote.js
$('.firstDisplay').on("click", function () {
alert("work1");
var win = $(this).attr("title");
var loss = $('.secondDisplay').attr("title");
send_vote(win, loss);
console.log("<-CLIENT-> Click: Sent vote");
});
$('.secondDisplay').on("click", function () {
alert("work2");
var win = $(this).attr("title");
var loss = $('.firstDisplay').attr("title");
send_vote(win, loss);
console.log("<-CLIENT-> Click: Sent vote");
});
function send_vote(win, lose) {
var data = {'win': win, 'lose': lose};
$.ajax({
type: "POST",
url: 'actions/send-vote.php',
data: data,
success: function (html) {
$('#sent-vote').css('display', 'block');
$('#sent-vote').fadeOut(2000);
$('.imageBtn').fadeOut(2000);
$('#imageDisplay').load("source/templates/vote.php");
console.log("<-SYSTEM-> Ajax request sent and processed.");
},
error: function(e) {
$('#fail-vote').css('display', 'block');
$('#fail-vote').fadeOut(2000);
console.log("<-SYSTEM-> Ajax request failed to process.");
}
});
}
vote.php
<?php
$maximumPersons = 95;
$firstDisplay = rand(1, $maximumPersons);
$secondDisplay = rand(1, $maximumPersons);
function getScore($photo_id) {
$query = "SELECT *
FROM photo_scores
WHERE photo_id='".$photo_id."'";
$result = $database->query_select($query);
return $result;
}
?>
<a href="javascript:void(0);" class="imageBtn" id="firstDisplay" title="<?php echo $firstDisplay; ?>">
<img src="<?php echo $baseURL; ?>/images/persons/<?php echo $firstDisplay; ?>.png" />
<?php // $scoreFD = getScore($firstDisplay); echo "Wins: ".$scoreFD["wins"]." Losses: ".$scoreFD["losses"].""; ?>
</a>
<a href="javascript:void(0);" class="imageBtn" id="secondDisplay" title="<?php echo $secondDisplay; ?>">
<img src="<?php echo $baseURL; ?>/images/persons/<?php echo $secondDisplay; ?>.png" />
<?php // $scoreSD = getScore($secondDisplay); echo "Wins: ".$scoreSD["wins"]." Losses: ".$scoreSD["losses"].""; ?>
</a>
it's all loading correctly, just the img/buttons wont submit/work after its reloaded.
You need to use the form $(document).on('event', '.selector', function(){}); to listen for new elements on the DOM and attach your handler to them.
The answer here is event delegation.
Binding an event listener to an object will not bind it to all other dynamically loaded or created objects, or adding the(lets say class as in your example) to another object will not apply its event listeners , since they did not exists when the script was run
$('.firstDisplay').on("click", function () {
you say all current elements with firstDisplay class do something on click. If you then add a new .firstDisplay, it wont know that it needs to listen to the on click. in short the listener is not attached on the class itself, but on the elements that have the class when the script is run.
now to get it to work, we will use event delegation
$(document).on("click",'.firstDisplay', function () {
this time around we bind the event on document. we also tell the event that should it find a firstdisplay class on an element clicked inside the document, the following function must be executed. So if new element are added, the event, bound to document now, will properly fire
When a row's select button is clicked, a confirmation box pops up.
Upon confirming the box, the select-button shall become disabled, and a message is appended that shall fade out.
Both, button disabling and message appending work but only for a second.
The button does not remain disabled. Also the message appends correctly but only for a second too.
I could change the fadeOut(Int) to any Integer but still the message only shows up for a second. Why does functionality only work for a second?
<script>
$('#button_<?php echo $platform->id; ?>').click(function() {
var choice = confirm('Please confirm that you wish to do the following Platform: <?php echo $platform->company; ?>');
if (choice == true) {
$('#button_<?php echo $platform->id; ?>').prop("disabled", true);
$('.job_confirm').css('visibility', 'visible');
$('.job_confirm').append('The Job has been added to your Userarea -->');
$('.job_confirm').fadeOut(5000);
}
});
</script>
try event.preventDefault();
<script type="text/javascript">
$('#button_<?php echo $platform->id; ?>').click(function(event) {
event.preventDefault();
var choice = confirm('Please confirm that you wish to do the following Platform: <?php echo $platform->company; ?>');
if (choice == true) {
$('#button_<?php echo $platform->id; ?>').prop("disabled", true);
$('.job_confirm').css('visibility', 'visible');
$('.job_confirm').append('The Job has been added to your Userarea -->');
$('.job_confirm').fadeOut(5000);
}
});
</script>
I made a small script to record bugs in my projects
this picture will show you a file name and the bugs it have.
then I used javascript-jquery to save myself some time.
so when I click on an error (the red ones) it will turn to green, and if i click on the fixed error (the green ones) it will turn to red.
the problem is sometime I click on the wrong error and can't turn it back unless i refresh the page. ex. if I click on error like tags plugin (* it turns green *) then I click on tags plugin again to turn it back to red it won't turn back, unless I refresh the page then click on it again to turn it.
I checked my code its fine I don't know what the problem is.
in while (fetching the error)
while ($error = mysql_fetch_assoc($find_errors))
here I print the errors
<?php
switch ($error['status']) {
case 'notfixed':
$error_class = "error";
$error_link = "fix".$error['id']."";
break;
case 'fixed':
$error_class = "success";
$error_link = "unfix".$error['id']."";
break;
}
echo "
<a href='".$_SERVER['PHP_SELF']."?del=".$error['id']."'>
<span class='del'>×</span>
</a>
<input id='errorid".$error['id']."' value='".$error['id']."' type='hidden'>
<input id='errorname".$error['id']."' value='".$error['name']."' type='hidden'>
<div id='newdiv".$error['id']."'>
<a id='".$error_link."'>
<span class='".$error_class."'>".$error['name']."</span>
</a>
</div>
<div class='clear'></div>";
?>
inside the same loop before printing the errors I printed this which the javascript
<script type='text/javascript'>
$('document').ready(function(){
$("#fix<?php echo $error['id'] ?>").click(function(){
var errorid = $("#errorid<?php echo $error['id']?>").val();
jQuery.post('fix_error.php',{posterrorid : errorid},
function(data, textStatus){
if(data == 1){
setInterval(function(){
$("#newdiv<?php echo $error['id']?>").html("<a id='unfix<?php echo $error['id']?>'><span class='success'><?php echo $error['name']?></span></a>");
}, 1000);
}else{
setInterval(function(){
$("#newdiv<?php echo $error['id']?>").text('error insert');
}, 1000);
}
});
});
$("#unfix<?php echo $error['id'] ?>").click(function(){
var errorid = $("#errorid<?php echo $error['id']?>").val();
jQuery.post('unfix_error.php',{posterrorid : errorid},
function(data, textStatus){
if(data == 1){
setInterval(function(){
$("#newdiv<?php echo $error['id']?>").html("<a id='fix<?php echo $error['id']?>'><span class='error'><?php echo $error['name']?></span></a>");
}, 1000);
}else{
setInterval(function(){
$("#newdiv<?php echo $error['id']?>").text('error insert');
}, 1000);
}
});
});
});
</script>
Try using the syntax like this :
$("#fix<?php echo $error['id'] ?>").live('click',function(){
.....
});
$("#unfix<?php echo $error['id'] ?>").live('click',function(){
.....
});
Because when you click for the first time, you are replacing the html code dynamically,
so for the next time, when you click that dynamically generated html code will not be noticed, so you have to use .live function.
REFER