how can AJAX dynamically add rows to a table

Viewed 323

I was wondering if someone could help me figure out how to add rows to the following html dynamically using AJAX whenever a database query finds more records. I am using python flask and pandas to create a dataframe with nodes information such as when a node is ACTIVE, or in SLEEP mode, LOCKED or UNLOCKED. I was thinking that I could somehow pass that dataframe and iterate through it to create a table with that information and a link to another page for that specific node. Now,I think I have the first part down where I am POSTing the page when it is first brought up with all of the recorded nodes. But I think I'm doing that part wrong too. I suppose I have two questions then:

How can I pass a dataframe to the html and iterate through it correctly?

How can I use AJAX to add another row to the table whenever any other node that registers? I was thinking maybe I pass a list of nodeID's to the HTML when I POST and then have setInterval pass that to the python flask side, query the database, create a new list and compare..removing those that I already added, pass the dataframe of those that are new to AJAX function along with a full list of NodeID's....does that sound right?

So far I was only able to figure this out for a POST but no idea what to do next:

HTML

    <div class="container">
      <h2>Incubator List</h2>
      <p>List of Registered Encubators:</p>            
      <table class="table table-dark table-striped">
        <thead>
          <tr>
            <th>NodeID</th>
            <th>Last Update</th>
            <th>Status</th>
            <th>  </th>
            <th>Control Link</th>
          </tr>
        </thead>
      {% for node in nodes %}
        <tr>
          <td>{{ node.NodeID }}</td>
          <td>{{ node.last_update }}</td>
          {% if {{ node.Sleep }} == "True" %}
            <td><p class="bg-secondary text-white text-center">SLEEP</p>></td>
          {% else %}
            {% if {{ node.Active }} == "True" %}
              <td><p class="bg-success text-white text-center">ACTIVE</p></td>
            {% else %}
              <td><p class="bg-danger text-white text-center">NOT ACTIVE</p>></td>
            {% endif %}
          {% endif %}
          {% if {{ node.LOCK }} == "True" %}
            <i class="fas fa-lock"></i>
          {% else %}
            <i class="fas fa-unlock"></i>
          {% endif %}
          <td>
            <form action="/nodeslist" METHOD = "POST">
              <input type="hidden" id="NodeID" name="NodeID" value={{ node.NodeID }}>
              <input TYPE="SUBMIT" value="Access" class = "btn btn-success">
                </form>
          </td>
        </tr> 
      {% endfor %}
    </tbody>
  </table>
    </div>
<script>
    function UPDATEnodelist(nodeIDlist) { 
        $.get('/nodeDHT?nodeIDlist ='+nodeIDlist , 
            function(data){
                const parsed = JSON.parse(data)
                nodeIDlist = parsed.nodeIDlist;
                something-pandas-dataframe-something;
            };
        )
    };

    setInterval(function () {
            UPDATEnodelist(nodeIDlist);
            return false;
    }, 2500);
</script>
{% endblock content %}

python flask

@app.route('/nodeslist', methods=['POST','GET'])
def nodelist():
    df= DAO.Pull_Type_Nodes()
    if request.method == "POST":
        title='List of Registered Nodes')
        nodeIDlist = nodes.NodeID.unique()
        nodes = df.to_json(orient ='records')
        return render_template('nodeslist.html',title=title, nodes=nodes, nodeIDlist=nodeIDlist) 
    else:
        oldnodeIDlist = request.form['NodeID']
        add_df = df[~df['NodeID'].isin(oldnodeIDlist)]
        new_nodes = add_df.to_json(orient ='records')
        return new_nodes,nodeIDlist

Please any help would be greatly appreciated!

EDIT:

The response should be a dataframe with fields 'nodeID','sleep' (bool), 'lock' (bool), 'active' (bool)

1 Answers
<table id="table" class="table table-dark table-striped">
  <thead>
    <tr>
      <th>NodeID</th>
      <th>Last Update</th>
      <th>Status</th>
      <th></th>
      <th>Control Link</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>
        <form action="/nodeslist" METHOD="POST">
          <input type="hidden" id="NodeID" name="NodeID" value={{ node.NodeID }}>
          <input TYPE="SUBMIT" value="Access" class="btn btn-success" id="btn">
        </form>
      </td>
    </tr>
  </tbody>
</table>
const date = new Date();
const data = [...Array(10).keys()].map(id => {
  return {
    id: id+1,
    date: new Date((Math.random() * 10000000) + date.getTime()).toLocaleString(),
    status: Math.floor(Math.random() * 2),
  };
});

const tbody = document.querySelector('#table').querySelector('tbody');

function test(evt) {
  evt.preventDefault();
  let fragment = document.createDocumentFragment();
  data.forEach(d => {
    let tr = document.createElement('tr');
    Object.keys(d).forEach(x => {
      let td = document.createElement('td');
      let textNode = document.createTextNode(d[x]);
      td.appendChild(textNode);
      tr.appendChild(td);
    })
    fragment.appendChild(tr);
  });
  tbody.appendChild(fragment);
}

document.querySelector('#btn').onclick = test;

Here working example

Related