How to send selected data from a datatable? How to send selected data from a datatable? flask flask

How to send selected data from a datatable?


Here is my attempted solution to your problem. I'm making the assumption that the user can only select one row at a time.

index.html

<!DOCTYPE html><html lang="en">  <head>    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">    <link href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" rel="stylesheet">  </head>  <body>    <div class="container">      <div class="header">        <h3 class="text-muted">Create a pretty table</h3>      </div>      <div>        <p>Number of rows</p>        <input type="text" size="5" id="a" value="10">        <p>Number of columns</p>        <input type="text" size="5" id="b" value="2">        <p><a href="javascript:void();" id="calculate">get a pretty table</a></p>        <p><a href="javascript:void();" id="send_data">send selected data</a></p>         <p>Result</p>        <p>Number of elements:</p>          <span id="elements">Hallo</span><br>          <table id="a_nice_table" class="table table-striped">Here should be a table</table>      </div>    </div>    <script src="https://code.jquery.com/jquery-1.12.4.js" type="text/javascript"></script>    <script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js" type="text/javascript"></script>    <script type="text/javascript">      $(document).ready(function() {        var table = null;        var selected = null;        $('#calculate').bind('click', function() {          $.getJSON('/_get_table', {            a: $('#a').val(),            b: $('#b').val()          }, function(data) {            $("#elements").text(data.number_elements);            if (table !== null) {              table.destroy();              table = null;              $("#a_nice_table").empty();            }            table = $("#a_nice_table").DataTable({              data: data.my_table,              columns: data.columns            });            var drawn_table = document.getElementById('a_nice_table'),                selected = drawn_table.getElementsByClassName('selected');            drawn_table.onclick = highlight;            function highlight(e) {              if (selected[0]) selected[0].className = '';              e.target.parentNode.className = 'selected';            }          });          return false;        });        $('#send_data').bind('click', function() {          var selected = $("tr.selected").html();          if (selected != null) {            console.log("<thead>" + $("#a_nice_table thead").html() + "</thead><tbody><tr>" + selected + "</tr></tbody>");            $.getJSON('/_selected_data', {              sel_data: "<thead>" + $("#a_nice_table thead").html() + "</thead><tbody><tr>" + selected + "</tr></tbody>"            }, function(data) {              alert('This worked');            });          } else {            console.log($("#a_nice_table").html());            $.getJSON('/_selected_data', {              sel_data: $("#a_nice_table").html()            }, function(data) {              alert('This worked');            });          }          return false;        });      });    </script>  </body></html>

app.py

from flask import Flask, render_template, request, jsonifyimport pandas as pdimport numpy as npimport json# just for reproducibilitynp.random.seed(0)# Initialize the Flask applicationapp = Flask(__name__)@app.route('/')def index():    return render_template('index.html')@app.route('/_get_table')def get_table():    a = request.args.get('a', type=int)    b = request.args.get('b', type=int)    df = pd.DataFrame(np.random.randint(0, 100, size=(a, b)), columns=['C1', 'C2'])    return jsonify(number_elements=a * b,                   my_table=json.loads(df.to_json(orient="split"))["data"],                   columns=[{"title": str(col)} for col in json.loads(df.to_json(orient="split"))["columns"]])@app.route('/_selected_data')def get_selected_data():    sel_data = request.args.get('sel_data')    df_list = pd.read_html("<table>" + sel_data + "</table>")    df = pd.concat(df_list)    print(df)    return jsonify(dummy_data=1)if __name__ == '__main__':    app.run(debug=True)

So basically what happens is that after a table is randomly generated, I have to create a couple of variables (drawn_table and selected) to track the table and its selected row. As of now, there's no visual change to when a row is selected but it's up to you if you want to make any CSS modifications to denote when a row is selected. When a user does click a row, the row gets a class assignment of "selected", and any other row gets deselected. This is so that JQuery will know what row is selected when sending it back to the server.

Then in the send_data link, I'll find the tr (table row) element that has the "selected" class (tr.selected) and grab the html code inside this element. If the element exists, then I will send the html along with the table header info as JSON to flask. If there is no tr.selected element, then the html code is obviously undefined, so the code will run the else part of the block and send the entire table.

In app.py, I read the JSON value, which is a string of HTML code. Since Pandas has a read_html method, I can pass the HTML string to the method to create a list of dataframes. Then I concat the list of dataframes to make my final df.

You can see the result of the dataframe in Python's console log (print(df)). You can also see the html code result in your browsers inspector because I added some console.log statements.