toggleClass in Ajax request not working - javascript

I am having a little trouble getting my .toggleClass to work. I am very new to javascript so forgive me if im missing something really simple here. I want users to be able to favourite things like images and posts. I have a little heart icon that when clicked should turn red/black depending if they're adding/removing. Everything works apart from the .toggleClass. Can anyone point out where i am going wrong?
index.php
<div class="heart-box">
<?php
//Check if user has fav'd the image..
$hasFav = db::getInstance()->query("SELECT * FROM favourites WHERE userID = ? AND img_id = ?", array($the_user, $img_id));
$action = $hasFav->results() ? 'unfav-heart' : 'fav-heart';
?>
<div class="<?php echo $action; ?> fa fa-heart" id="<?php echo $img_id; ?>" ></div>
</div>
Script
$(document).ready(function(){
//add to favourites...
$('.fav-heart').click(function(){
var img_id = $(this).attr('id');
$.ajax({
url: 'favourites.php',
type: 'post',
async: false,
data:{
'fav' : img_id
},
success:function(){
$(img_id).toggleClass("unfav-heart");
}
});
});
// remove from favourites...
$('.unfav-heart').click(function(){
var img_id = $(this).attr('id');
$.ajax({
url: 'favourites.php',
type: 'post',
async: false,
data:{
'fav' : img_id
},
success:function(){
$(img_id).toggleClass("fav-heart");
}
});
});
});

As pointed out in the other answer, you left out the # prefix to indicate an ID in a selector. But there's no need to use a selector at all, since you have a variable pointing directly at the element.
$('.fav-heart').click(function(){
var img = $(this);
var img_id = this.id;
$.ajax({
url: 'favourites.php',
type: 'post',
async: false,
data:{
'fav' : img_id
},
success:function(){
img.toggleClass("unfav-heart");
}
});
});

JQuery id's need a # in the selector :
$(document).ready(function(){
//add to favourites...
$('.fav-heart').click(function(){
var img_id = $(this).attr('id');
$.ajax({
url: 'favourites.php',
type: 'post',
async: false,
data:{
'fav' : img_id
},
success:function(){
$("#"+img_id).toggleClass("unfav-heart");
}
});
});
// remove from favourites...
$('.unfav-heart').click(function(){
var img_id = $(this).attr('id');
$.ajax({
url: 'favourites.php',
type: 'post',
async: false,
data:{
'fav' : img_id
},
success:function(){
$("#"+img_id).toggleClass("fav-heart");
}
});
});
});

Your click handlers for both selectors are registered on document ready. That's why only these elements who match the selector classes are assigned to the click handler. If you toggle the class afterwards you have to reassign the click handlers.
A better approach would be to register a click handler for all heart elements. Inside the click handler you do a switch case statement where you toggle the class accordingly.

Related

Changes done in ajax success not loading in page without refreshing

I have an ajax block in javascript, which does a few operations, and then changes a text box in my page.
$.ajax({
type: "POST",
url: "/post_to_page/",
data: JSON.stringify({'titleid': parseInt(count_id)}),
cache: false,
success: function(data){
var content_id = "count_" + count_id;
var votes = $(content_id ).val();
$(upvotes_id).html(votes);
//window.location.reload();
}
});
The content value is reflected only after I refresh the page. I tried setting cache parameter as false and alse the same in ajaxSetup when document is ready. Still the changes arent getting reflected. Please help.
It looks like your return variable 'data' isn't being referenced in the success function. As pointed out elsewhere, also missing an id or class reference. Try this (or any other relevant variables):
var content_id = "#count_" + data.count_id;
add hash to get value like
var votes = $('#'+content_id ).val();
i think you forgot add "#" before the id
$.ajax({
type: "POST",
url: "/post_to_page/",
data: JSON.stringify({'titleid': parseInt(count_id)}),
cache: false,
success: function(data){
var content_id = "count_" + count_id;
var votes = $('#'+content_id ).val(); // add hash for id or . for class
$(upvotes_id).html(votes);
//window.location.reload();
}
});
I am assuming upvotes_id is either id or class. Use $("#upvotes_id").html(votes) or $(".upvotes_id").html(votes) instead.same in the case of "content_id" .
I can see few issues with your code like- no '#' for referring an element.
corrections:
$.ajax({
type: "POST",
url: "/post_to_page/",
data: JSON.stringify({'titleid': parseInt(count_id)}),
cache: false,
success: function(data){
**var content_id = "#count_" + count_id;**
var votes = $(content_id ).val();
$(upvotes_id).html(votes);
//window.location.reload();
}
});
Also you have not mentioned how you are getting upvotes_id. Use # there too. You are not using the response returned in success method. Is it intended?

Ajax request to php only works once per pageload

I have seen a few of these questions post on here but none of them are working for me. I have a favourite button that i would like my users to press to favourite things. The ajax request is working just fine and the favourite gets stored in the database but i can only use it once then i have to refresh the page to fav/unfav the item. The code for the button is:
<div id="fav-icon">
<?php
// Function checks if user has fav'd the item.
$isFav = favourite($user->id) ? 'un-fav' : 'fav';
?>
<i id="<?php echo $item->id; ?>" class="<?php echo $isFav; ?>"><span class="font-12 fa fa-heart"></span></i>
</div>
Jquery/Ajax
$('.fav').click(function(e){
var con = $(this).attr('id');
$.ajax({
url: 'fav.php',
type: 'POST',
async: true,
data:{
'fav' : con
},
success:function(){
$('#fav-icon').load(document.URL + ' #fav-icon');
}
});
});
$('.un-fav').click(function(e){
var con = $(this).attr('id');
$.ajax({
url: 'fav.php',
type: 'POST',
async: true,
data:{
'fav' : con
},
success:function(){
$('#fav-icon').load(document.URL + ' #fav-icon');
}
});
});
So this works but only once! I have tried a couple of different functions to try make this work including:
$('.fav').live('click', function(e) {
Can anyone tell me where i am going wrong and the correct method to get my button to work multiple times?
Use $(document).on() click event
$(document).on('click','.fav', function(e) {
...
});

how to make jquery remove() on just one item

this is the first time i use jquery and im trying to figure out to to make jquery remove(), remove just one item with a specific class, not every item with the same class.
my code is like this
jquery:
$(function() {
$(".vote").click(function()
{
var id = $(this).attr("id");
var name = $(this).attr("name");
var dataString = 'id='+ id ;
var parent = $(this);
if (name == 'up') {
$(this).fadeIn(600).html('<span class="glyphicon glyphicon-ok"></span>');
$.ajax({
type: "POST",
url: "up_vote.php",
data: dataString,
cache: false,
success: function(html) {
parent.html(html);
$(".vote").remove();
$(".escondido").css("display", "block");
}
});
}
(code continues with else vote down)
after clicking on a up button, the jquery code removes the button containing class vote, but if i have 2 buttons with class vote, both will be removed. i want to delete just the one clicked. any idea how?
<button type="button" class="btn btn-success btn-xs vote up" name="up" id="'.$reg['id'].'">BUTTON</button>
thank you!
you need to add a reference to this in the scope of the click for usage in your success callback, then jQuery it like you've jQueried other this's:
$(function() {
$(".vote").click(function()
{
var id = $(this).attr("id");
var name = $(this).attr("name");
var dataString = 'id='+ id ;
var parent = $(this);
var _this = this;
if(name=='up')
{
$(this).fadeIn(600).html('<span class="glyphicon glyphicon-ok"></span>');
$.ajax({
type: "POST",
url: "up_vote.php",
data: dataString,
cache: false,
success: function(html)
{
parent.html(html);
$( _this ).remove();
$( ".escondido" ).css( "display", "block" );
}
});
}
});
as a bonus, here's a refactored version that saves some cpu cycles and prettyfies the code a bit:
$(function() {
$(".vote").click(function()
{
var $this = $(this),
id = $this.attr("id"),
name = $this.attr("name"),
dataString = 'id='+ id;
if(name=='up')
{
$this.fadeIn(600).html('<span class="glyphicon glyphicon-ok"></span>');
$.ajax({
type: "POST",
url: "up_vote.php",
data: dataString,
cache: false,
success: function(html)
{
$this.html(html);
$this.remove();
$( ".escondido" ).css( "display", "block" );
}
});
}
});
});
You can declare a new variable that references $(this) so that you can use it in the scope of the $.ajax() function. Alternatively, you can also declare the context property of the $.ajax() function as follow:
$.ajax({
type: "POST",
url: "up_vote.php",
data: dataString,
cache: false,
context: this, // Passes $(this)
success: function(html) {
parent.html(html);
$(this).remove();
$(".escondido").css("display", "block");
}
});

AJAX request for many links

I'm new to jQuery AJAX. I want to build bookmarking system something like Twitter do (favorites). I have a lot of links. So it's not useful to write AJAX request for each link. That's why I want use just one request script for all links.
Let's say I have the links something link this:
<i class="icon-star-empty"></i>
<i class="icon-star"></i>
<i class="icon-star-empty"></i>
So I want to write AJAX request that do something like this when user clicks to one of those URLs.
if (class="icon-star-empty"){
ajaxURL = "/insertBoomark"
} else{
//it means class=icon-start
ajaxURL = "/deleteBookmark"
}
$.ajax({
url: ajaxURL,
type: "POST",
data: {id : linkID}, // I don't know how to get linkID too :(
success: if class was icon-star empty then change it to icon-star-empty else change it to icon-star
});
I know that is not correct syntax.
How can I solve this problem? Please help :(
Thanks in advance.
$("i").on("click", function() {
if ( $(this).hasClass("icon-star-empty") ){
ajaxURL = "/insertBoomark"
} else{
//it means class=icon-start
ajaxURL = "/deleteBookmark"
}
var linkID = $(this).parent().prop("id");
var obj = $(this);
$.ajax({
url: ajaxURL,
type: "POST",
data: {id : linkID},
success: function() {
obj.hasClass("icon-star") ? obj.removeClass("icon-star").addClass("icon-star-empty") : obj.removeClass("icon-star-empty").addClass("icon-star");
}
});
})
You can also use the href attribute and just prevent the default action from the jquery event.
html
javascript
$(function(){
$(document).on('click','a',function(e){
e.preventDefault(); //prevent default click action
var $this = $(this); // keeps "this" accessable
var ajaxURL = $this.attr('href'); // get the url from the "a" tag
$.ajax({
url: ajaxURL,
type: "POST",
data: {id : linkID},
success: function() {
if($this.hasClass("icon-star"))
$this.removeClass("icon-star").addClass("icon-star-empty");
else
$this.removeClass("icon-star-empty").addClass("icon-star");
}
});
});
});
$('a').click(function(){
var _ajaxURL,
_self = $(this);
if($(this).hasClass('icon-star-empty')){
_ajaxUrl = "/insertBookmark";
}else{
_ajaxUrl = "/deleteBookmark";
}
$.ajax({
url: _ajaxUrl,
type: 'POST',
data: {id : $(this).prop('id')},
success: {
//I have no idea what you want to do right here.
}
});
});
Okay, first, class is a reserved name in javascript.
Secondly, if you're doing it with a jQuery.click function, then you can just do $(this).attr('id') to get the id.
Also, for the success part, you seem to be confused about javascript's function syntax. What exactly are you trying to do?

merging two small pieces of jquery codes

Following are two pieces of jquery code. First one prints a text message when clicked on a link, and the second slides down a div when click on a link. I want to merge second code into first one, so that when I click the link, it displays the message (as the first code does), and also slides down the #votebox (as done in second code, and show content in that.
I will be very thankful for any help.
$("a.vote_up").click(function(){
the_id = $(this).attr('id');
$("span#votes_count"+the_id).fadeOut("fast");
$.ajax({
type: "POST",
data: "action=vote_up&id="+$(this).attr("id"),
url: "votes.php",
success: function(msg)
{
$("span#votes_up"+the_id).fadeOut();
$("span#votes_up"+the_id).html(msg);
$("span#votes_up"+the_id).fadeIn();
//Here, I want to slide down the votebox and content div (from code below).
}
});
});
The following code slides down votebox div and displays content in it, I want to include that in the above code.
$("a.vote_up").click(function(){
var id=$(this).attr("id");
var name=$(this).attr("name");
var dataString = 'id='+ id + '&name='+ name;
//I want to include this votebox in above code.
$("#votebox").slideDown("slow");
$("#flash").fadeIn("slow");
$.ajax({
type: "POST",
url: "rating.php",
data: dataString,
cache: false,
success: function(html){
$("#flash").fadeOut("slow");
//and want to use this div as well.
$("#content").html(html);
}
});
});
Thanks for any help.
Simple way is to define a seperate function for voteDown and call it from the success function:
e.g
$("a.vote_up").click(function(){
the_id = $(this).attr('id');
$("span#votes_count"+the_id).fadeOut("fast");
$.ajax({
type: "POST",
data: "action=vote_up&id="+$(this).attr("id"),
url: "votes.php",
success: function(msg)
{
$("span#votes_up"+the_id).fadeOut();
$("span#votes_up"+the_id).html(msg);
$("span#votes_up"+the_id).fadeIn();
var that = this;
voteDown.call(that);
}
});
});
function voteDown()
{
var id=$(this).attr("id");
var name=$(this).attr("name");
var dataString = 'id='+ id + '&name='+ name;
$("#votebox").slideDown("slow");
$("#flash").fadeIn("slow");
$.ajax({
type: "POST",
url: "rating.php",
data: dataString,
cache: false,
success: function(html){
$("#flash").fadeOut("slow");
//and want to use this div as well.
$("#content").html(html);
}
});
}
Edit: Corrected the JS for Votedown function.

Categories