2

I have a table. So I am looking to get the value of a <td> tag and pass it on to the python function when I click that.

HTML CODE:

<table border=5 id="mytable">
  <thead>
    <td>Erp</td>
    <td>Status</td>
    <td>name</td>
    <td>Days</td>
  </thead>

  {% for tr in df_excel_data%}
    <tr>
      <td onclick="passvaluefun()">{{tr[0]}}</td>
      <td>{{tr[1]}}</td>
      <td>{{tr[2]}}</td>
      <td>{{tr[3]}}</td>
    </tr>
  {% endfor %}
</table>

JSCODE:

var table = document.getElementById('mytable'),
  cells = table.getElementsByTagName('td');

for (var i = 0, len = cells.length; i < len; i++) {
  cells[i].onclick = function() {
    console.log(this.innerHTML);
  }
}

I am able to get the value by using javascript but I am unable to pass the value to my python function in flask. I just want to pass the value of <td> tag I click to my python function.

Michael M.
  • 10,486
  • 9
  • 18
  • 34
qcoder
  • 51
  • 6
  • 1
    You could either use AJAX or a `
    ` element. For your use case, you most likely want to use a `
    `. Research more about forms in Flask
    – Michael M. Oct 28 '22 at 02:13
  • Is there any other way to do this without completely shifting this code? – qcoder Oct 28 '22 at 02:20
  • 1
    Your JavaScript code (client-side) runs completely separately from your Flask code (server-side), so not really. I can try to write an answer, but it will be fairly hacky. – Michael M. Oct 28 '22 at 02:22
  • 1
    Yeah can you please write one because this application will be used only by one member. And its not a big deal if its hacky – qcoder Oct 28 '22 at 02:36
  • Does my answer below help? – Michael M. Oct 28 '22 at 02:44

1 Answers1

1

First understand this: your JavaScript code runs on the client completely separately from your Python code running on the server. Let this sink in until you understand it, then continue reading the question. This is something that trips up beginners a lot and ends up in a lot of poor design choices.

There are two ways of sending data from the browser to the server. They are forms and AJAX. Forms are exactly what they sound like: you fill out inputs (text boxes, checkboxes, radio buttons, etc.) and it is sent to the server in a very standard way. Forms were invented first, but they offer little flexibility and don't integrate well with JavaScript, so AJAX was invented. AJAX works by calling some functions from JavaScript to send any arbitrary data to a server. Forms are much easier to use, so use forms when you can, but in this case, you need more control and need to use AJAX.

In 2022, the best way to do an AJAX call is to use the Fetch API. Here's how it works:

First, create a POST handler in your Flask app to receive JSON data. See this question for more. Here is my basic example:

from flask import Flask, request, jsonify

# ... more code ...

@app.route('/api/getTableData', methods=['POST'])
def getTableData():
    value = request.json['value']
    print(value)
    # do something with the "value" variable

    # optionally, you can send a response back to your JavaScript code
    return jsonify({"response": "It works!"})

Once you have that down, you need to write the client-side JavaScript to make the AJAX call. This part is relatively easy:

const table = document.getElementById('mytable'),
  cells = table.getElementsByTagName('td');

for (let i = 0, len = cells.length; i < len; i++) {
  cells[i].addEventListener('click', async () => {
    const resp = await fetch('http://YOUR_FLASK_SERVER/api/getTableData', {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({
        value: cells[i].textContent,
      }),
    });

    // if the server sends a response, then it will be alerted here
    const json = await resp.json();
    alert('Server sent response: "' + json.response + '"');
  });
}

Make sure to change YOUR_FLASK_SERVER to the address of your flask server. This is probably localhost:5000.

Note: I used never ES6 JavaScript syntax. This is optional, however, it makes using the Fetch API much easier because it uses promises.

Michael M.
  • 10,486
  • 9
  • 18
  • 34