0

I am trying to create a "like" button for my web app (which acts like the "like" button on Facebook), where the number of times clicked by a user is stored in an sqlite database, and will display as "liked" or "not liked" according to whether the number of times clicked is even or odd. I want to button to have a green background with text displayed as "liked" if previously liked (clicked an odd number of times), and grey background displaying "like" if not liked (clicked an even number of times).

This is my code:

HTML (the second button is the one I'm working on):

{% extends "layout.html" %}
{% block title %}
    School uploads
{% endblock %}
{% block main %}
<h1>School uploads</h1>
<table class="table">
  <thead>
    <tr>
      <th scope="col">Admission year</th>
      <th scope="col">Question</th>
      <th scope="col">Currency</th>
      <th scope="col">Price</th>
      <th scope="col">Action</th>
      <th scope="col">Your thoughts</th>
    </tr>
  </thead>
  <tbody>
    {% for row in rows %}
    <tr>
      <td>{{ row.admission_year }}</td>
      <td>{{ row.question }}</td>
      <td>{{ row.currency }}</td>
      <td>{{ row.price }}</td>
      <td>
      <form action="/uploads" id="view" method="post">
        <button>
          <input type="hidden" id="view" value="{{ row.filename }}" />
          View
        </button>
      </form>
      </td>
      <td>
        <button id="vote" class="upvote_button" data-id="{{ row.filename }}">Vote</button>
      </td>
    </tr>

    {% endfor %}
{% endblock %}

javascript:

$(document).ready(function() {
$(".upvote_button").each(function(){
        let parameters = {
            post_id: $(this).attr('data-id'),
        };
        $.getJSON("/countupvotes", parameters, function(data, textStatus, jqXHR){
            if (data.count % 2 == 0) {
                alert("even");
                $(this).css("background-color", "red");
            }
            else {
                alert("odd");
                $(this).css("background-color", "blue");
            }
        });
        });
});

application.py

@app.route('/countupvotes', methods=['GET'])
def countupvotes():
    filename=request.args.get("post_id")
    number=db.execute(
        "SELECT count(*) AS count FROM likes WHERE filename = :filename AND id=:id", filename=filename, id=5)
    return jsonify(number[0])

The problem is that because the content to be liked (or not liked) is generated dynamically by jinja, I need to use jquery syntax $(".upvote_button").each(function() to query sqlite for each button to determine the number of times clicked, and then set the color. However, the color does not change even though the alert("even") and alert("odd") are working fine.

Any help would be highly appreciated. Thanks in advance.

1

The $(this) is referring to the wrong this.

You could try something like

var that = this;

in the outer function, and use $(that) in the inner function.

An alternative could be to use an arrow function for the inner function. Those have neither this nor arguments, so that this would refer to the one of the outer function.

Another alternative is to use an IIFE (Immediately Invoked Function Expression), like

        $.getJSON("/countupvotes", parameters, (function(button){
            return function(data, textStatus, jqXHR){
                // now you can use $(button) instead of $(this)
                ...
            }
        }(this)));

Or, maybe bind it.

1
  • Thank you very much @Blauelf. I tried your methods and they work like a charm :)
    – Gladys Lau
    Mar 22 '19 at 4:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .