Reputation: 23
I was trying to implement like and dislike button to comments by the guidance from a tutorial, but i cannot get attributes from my code.
this is my html code including php
<a id="' . $quote->quote_id . '" data-toggle="tooltip" title="'. $language->list->tooltip->like .'" class="clickable like tooltipz"><span class="glyphicon glyphicon-plus red"></span></a>
<span class="up_votes"><?php echo ($vote_up); ?></span>
<a id="' . $quote->quote_id . '" data-toggle="tooltip" title="'. $language->list->tooltip->dislike .'" class="clickable dislike tooltipz"><span class="glyphicon glyphicon-minus red"></span></a>
<span class="up_votes"><?php echo ($vote_down); ?></span>
$quote->quote_id is integers like 1,2
$language->list->tooltip->like = Like comment
$language->list->tooltip->dislike = Dislike comment
$vote_up = total likes
$vote_up = total dislikes
this is the jquery part
//####### on button click, get user like and send it to vote_process.php using jQuery $.post().
$(".glyphicon").on('click', '.glyphicon', function (e) {
//get class name (down_button / up_button) of clicked element
var clicked_button = $(this).children().attr('class');
//get unique ID from voted parent element
var quote_id = $(this).parent().attr("id");
if(clicked_button==='glyphicon-minus') //user disliked the content
{
//prepare post content
post_data = {'quote_id':quote_id, 'vote':'down'};
//send our data to "vote_process.php" using jQuery $.post()
$.post('processing/process_votes.php', post_data, function(data) {
//replace vote down count text with new values
$('#'+quote_id+' .down_votes').text(data);
//thank user for the dislike
}).fail(function(err) {
//alert user about the HTTP server error
alert(err.statusText);
});
}
else if(clicked_button==='glyphicon-plus') //user liked the content
{
//prepare post content
post_data = {'quote_id':quote_id, 'vote':'up'};
//send our data to "vote_process.php" using jQuery $.post()
$.post('processing/process_votes.php', post_data, function(data) {
//replace vote up count text with new values
$('#'+quote_id+' .up_votes').text(data);
//thank user for liking the content
}).fail(function(err) {
//alert user about the HTTP server error
alert(err.statusText);
});
}
});
//end
});
in jquery part i am trying to know which button is clicked by user and get id of that button
Upvotes: 2
Views: 79
Reputation: 3293
.attr('class')
will return all classes that are assigned to the element, which is not working as you are comparing the entire class list against a specific class (i.e 'class1 class2 class2' != 'class2').
.hasClass('specific-class')
will return a boolean value depending on if that specific class has been assigned to the element in question.
You can simplify the code a little, the code below attaches a click event to anything with the class .glyphicon
before using hasClass(".glyphicon-minus")
or hasClass(".glyphicon-plus")
to check if it is a down or up vote.
From here there are two alternatives to update the total vote for each post, you can either use your current technique (finding the closest wrapping class - I've used .post
in this example) or you can add attributes to the UI elements which identify the elements that belong to that post - i.e. for="post1"
.
I've included the code for the second option as it is a bit shorter, but left it commented out.
There is also a check to see if the new total is 0, which then stops the process so that you cannot get negative votes. I've left this check commented out, but you can uncomment it if needed.
Hope that helps, let me know if you needed anything else.
$(".glyphicon").click(function() {
vote = 0;
// Check if negative vote
if ($(this).hasClass("glyphicon-minus")) {
vote = -1;
}
// Check if positive vote
if ($(this).hasClass("glyphicon-plus")) {
vote = 1;
}
// Update individual vote count
newVoteTotal =
parseInt($(this).closest(".post").find(".votes").text()) + parseInt(vote);
// Uncomment if statement and closing bracket if you want to stop usings from being able to give negative votes
//if ( newVoteTotal != "-1" ) {
$(this).closest(".post").find(".votes").text( newVoteTotal );
//}
// ALTERNATIVE using 'for' attributes
// postID = $(this).attr("for");
// newVoteTotal = parseInt($(".votes[for='" + postID + "']").text()) + parseInt(vote);
// $(".votes[for='" + postID + "']").text(newVoteTotal)
})
.post {
padding: 20px;
border: 1px solid black;
}
.post-body {
padding-bottom: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="post" id="post1">
<div class="post-body">
Lorem ipsum post 1.
</div>
<button class="glyphicon glyphicon-plus" for="post1">Vote Up</button>
<button class="glyphicon glyphicon-minus" for="post1">Vote Down</button>
<span class="votes" for="post1">0</span>
</div>
<div class="post" id="post2">
<div class="post-body">
Lorem ipsum post 2.
</div>
<button class="glyphicon glyphicon-plus" for="post2">Vote Up</button>
<button class="glyphicon glyphicon-minus" for="post2">Vote Down</button>
<span class="votes" for="post2">0</span>
</div>
I have tried to create a specific solution for your code structure, I believe this will work. Changes include:
$(".glyphicon").on('click', function(e) {
- corrected your creation of the click eventvar clicked_button = $(this).attr('class')
- you can gather all classes if you wish (as later we will just check for a presence of a single class) .attr() docsif (clicked_button.includes('glyphicon-minus')
- this checks the full list of classes we gathered early, to see if a specific class is present (and returns true if it is). .include() docsI have removed all the code that sends the info server side, and replaced it with a console.log()
message to prove we have gathered all the parameters you wanted. You can add your old code back in for your production site.
//####### on button click, get user like and send it to vote_process.php using jQuery $.post().
$(".glyphicon").on('click', function(e) {
//get class name (down_button / up_button) of clicked element
var clicked_button = $(this).attr('class');
//get unique ID from voted parent element
var quote_id = $(this).parent().attr("id");
if (clicked_button.includes('glyphicon-minus')) //user disliked the content
{
// POST like
console.log("Liked quote-id=" + quote_id + " (via class " + clicked_button + ")");
} else if (clicked_button.includes('glyphicon-plus')) //user liked the content
{
// POST dislike
console.log("Disliked quote-id=" + quote_id + " (via class " + clicked_button + ")");
}
});
//end
.glyphicon {
width: 50px;
height: 50px;
display: inline-block;
}
.red {
background: red;
}
.like {
border-bottom: 5px solid green;
}
.dislike {
border-bottom: 5px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a id="1" data-toggle="tooltip" title="Like comment" class="clickable like tooltipz"><span class="glyphicon glyphicon-plus red"></span></a>
<span class="up_votes">0</span>
<a id="1" data-toggle="tooltip" title="Dislike comment" class="clickable dislike tooltipz"><span class="glyphicon glyphicon-minus red"></span></a>
<span class="up_votes">0</span>
Upvotes: 2
Reputation: 24001
1st:
$(".glyphicon").on('click', '.glyphicon', function (e) {
//you need to change it to
$(document).on('click', '.glyphicon', function (e) { // if its dynamically generated element or you toggle `.glyphicon` class ..
// else you can just use
$('.glyphicon').on('click' , function(){
//code here
})
2nd: To check the classes you need to use hasClass
and on the next line
var clicked_button = $(this).children().attr('class');
you already in the click event of glyphicon
so no need to use children()
here .. and if you console.log($(this).attr('class'))
it will output glyphicon glyphicon-plus red
var clicked_button = $(this);
if(clicked_button.hasClass('glyphicon-minus')){
}
Note: after change your code with my notices above .. you can then console.log(quote_id)
Upvotes: 0