Search code examples
javascriptjqueryhtmladditionsubtraction

How to add +1 to a div temporarily until it refreshes, and subtract 1 if clicked a second time (etc etc)?


I have a like function on my site. It takes about 1 to 3 seconds (due to unavoidable sql queries for my site - not the best, but it works) to update the new number.

For example, if someone likes it then they click the thumbs up. The div there then updates with the new number.

If it has 3 likes, then when you like, it will have 4 likes. If you click again, it has 3 likes again. Repeat eternally.

The sole purpose of the javascript is to give instant gratification to users who, if not paying attention, may not be sure if it worked, especially during times when it takes longer than 1 second.

My idea is if I can simply do it with jquery to temporarily display the new number until my site rewrites the div to show the updated number, it will serve this function for what I need quite well.

Here is my idea. Please help me to get it working.

var likenum = $(".likenum").val(); // get the number inside the div
var newLikeNum = parseInt(likenum) + 1; // make sure the text is an integer for math functions, then do math and assign to a var
$(".likenum").val(newLikeNum); // refresh div with the new number

There are a couple problems.

  1. how do I run ONCE, and if clicked again, instead, it MINUS?
    (moreover, some other issues:
    It needs to keep original likenum for all future functions, instead of getting a new one. This way if my site refreshes the div, the jquery isn't paying attention to it. It knew the original number and now it ieither +1 or -1 to the original num.

So let's take this example for what I want.

<div class="likediv">3</div> <!-- original div on page load -->

x***click***x (pretend I clicked the thumbup)

<div class="likediv">4</div> <!-- updated number -->

x***click***x (pretend I clicked the thumbup again)

<div class="likediv">3</div> <!-- updated number -->

x***click***x (pretend I clicked the thumbup again)

<div class="likediv">4</div> <!-- updated number -->

x***click***x (pretend I clicked the thumbup again)

<div class="likediv">3</div> <!-- updated number -->

x***click***x (pretend I clicked the thumbup again)

<div class="likediv">4</div> <!-- updated number -->

I think you get the point.

So how can I do this? See my starter code above, I think I'm close.

Oh yeah, one more thing. There are many like buttons on the page, not just one. so it would need to store and remember any divs. Because we are liking comments and there are many per page.

For this, only need to use jquery please.


EDIT: UPDATE:

So, it wasn't working, @VIDesign's answer, but I see why. In fact, here is what the HTML actually looks like. (Please note I am also including the new working data-value as part of @VIDesign's answer)

<div class="likediv">
    <span class="dynamic-span" data-value="3">3</span>
</div>

Ok so apparently why it didn't work is because when you click, you actually click on .likediv, but the data-value="3" has to go inside the span which is nested inside the div and can't be touched.

So, how to we fire @VIDesign's answer, except the action is triggered when slicking on the div outside the span, when the span is what contains the number and the data-value?

I hope this was clear. Sorry for not specifying this originally, I didn't know until now.

So, we need to change this code below to work with above:

$(".likediv").click(function(){

    // Use the data-value as the constant to calculate with
    const actualValue = $(this).data("value");
    // Set a max value
    const maxValue = actualValue + 1;
    // Get the value the user sees
    const userValue = parseInt($(this).html());

    // create an empty variable for the new value to display
    let newValue;

    // If the value the user sees is equal to the max value
    if(userValue == maxValue){
        // then subtract one
        newValue = maxValue - 1;
    }else{
        // else add one
        newValue = actualValue + 1;
    }
    // Display the new value to the user
    $(this).html(newValue); 

});

Update 2: I tried this but it didn't work:

$(".likediv").click(function(){

    // Use the data-value as the constant to calculate with
    const actualValue = $(".dynamic-span").data("value");
    // Set a max value
    const maxValue = actualValue + 1;
    // Get the value the user sees
    const userValue = parseInt($(".dynamic-span").html());

    // create an empty variable for the new value to display
    let newValue;

    // If the value the user sees is equal to the max value
    if(userValue == maxValue){
        // then subtract one
        newValue = maxValue - 1;
    }else{
        // else add one
        newValue = actualValue + 1;
    }
    // Display the new value to the user
    $(".dynamic-span").html(newValue); 

});

Note: The only problem I am having is the speed to which it shows to the user in the front end after they clicked.

I am not trying to do any saving to the database and I do not want to try to get any value from the database, which would be redundant (cause it already happens successfully in other code in the php in the back end).

This is only a quick hack to update the speed at which the number shown is visible. Please be aware that when the php code in the back end updates the div (1 to 3 seconds usually), it will override anything that is in that div currently.

Also, anything done here should be lost on page reload by design. It is only a front-end display hack, not an actual updating of any code on the back end.


Solution

  • Fiddle https://jsfiddle.net/videsignz/n3e5u7bt/34/ Here is an example of using the data attribute. The data-value will be loaded from the database and you would end up with this to start.

    <div class="likediv">
        <span class="dynamic-span" data-value="3">3</span>
    </div>
    <div class="likediv">
        <span class="dynamic-span" data-value="3">3</span>
    </div>
    <div class="likediv">
        <span class="dynamic-span" data-value="3">3</span>
    </div>
    <div class="likediv">
        <span class="dynamic-span" data-value="3">3</span>
    </div>
    <div class="likediv">
        <span class="dynamic-span" data-value="3">3</span>
    </div>
    <div class="likediv">
        <span class="dynamic-span" data-value="3">3</span>
    </div>
    

    Then handle the restrictions within the click function of the button/div like so...

    $(".likediv").on("click", function(){
    
        const span = $(this).find("span.dynamic-span");
        // Use the data-value as the constant to calculate with
        const actualValue = span.data("value");
        // Set a max value
        const maxValue = actualValue + 1;
        // Get the value the user sees
        const userValue = parseInt(span.html());
    
        // create an empty variable for the new value to display
        let newValue;
    
        // If the value the user sees is equal to the max value
        if(userValue == maxValue){
            // then subtract one
            newValue = maxValue - 1;
        }else{
            // else add one
            newValue = actualValue + 1;
        }
        // Display the new value to the user
        span.html(newValue);    
    
    });