2

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>&nbsp;

<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>&nbsp;

<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

0

2 Answers 2

2

.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.

Recommended Solution

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>


Specific Solution

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 event
  • var 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() docs
  • if (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() docs

I 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>&nbsp;

<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>&nbsp;

<span class="up_votes">0</span>

Sign up to request clarification or add additional context in comments.

3 Comments

i'm planning to keep my code as it is difficult for me to implement the whole new code, so through var clicked_button = $(this).attr('class'); i was able to store the value of span class in my original code but i need to get the id attribute value of <a> also
I can change the code to accommodate that, but could you add the resultant HTML (ie not with the PHP) so I know exactly what it looks like so I can find the best jquery selectors to use.
I've updated my answer to include one for your code structure, it just tweaked a few lines of your jquery code, rather than making any changes to the HTML. I added some styling so that you could see what was going on.
0

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)

1 Comment

console.log($(this).attr('class')); gives output glyphicon glyphicon-plus red but console.log($(this).attr('id')); gives undefined

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.