google-charts not getting displayed on the server - python

My code:
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['FileName', 'Frequency'],
{% for l in list1 %}
[{{l.file_name}},{{l.frequency_count}}],
{% endfor %}
]);
var options = {
title: 'Search Performance',
hAxis: {title: 'FileName', titleTextStyle: {color: 'red'}}
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="chart_div" style="width: 900px; height: 500px;"></div>
</body>
</html>
On running my app (created in Django) on the server this chart is not getting displayed, why? This page is "results.html" which is directed from my views.py file. Here "list1" contains the data stored in the table namely "file_name" and "frequency_count". Why is this happening?
I'm new to Django, google-charts and JavaScript.

You may have a problem in the loop that prints the javacript array of values for the chart. I guess the filenames are strings, and as such they need to be delimited with ' or ", like this:
{% for l in list1 %}
['{{ l.file_name }}', {{ l.frequency_count }}],
{% endfor %}
To test this, I just got rid of the loop and put a couple of rows of sample static data, like this:
var data = google.visualization.arrayToDataTable([
['FileName', 'Frequency'],
['this', 100],
['that', 200]
]);
And I got the chart working:

Related

Prevent duplicated scans in a single QR code scan in DJango

The current camera scans the QR code and posts the same value to view_nurse.py multiple times till the QR code is moved away from the camera. This causes my database to have many repeated values shown in the image below. How do I prevent this from happening?
In situations where I scan another QR code without relaunching the camera, the program should be able to detect that it is a new QR code and POST the results into the views_nurse.py.
<nurse_home.html>
{% load static %}
{% block mainbody %}
<title>Django Online Barcode Reader</title>
<meta charset="utf-8">
{% csrf_token %}
<script src={% static "js/html5-qrcode.min.js" %}></script>
<style>
.result{
background-color: green;
color:#fff;
padding:20px;
}
.row{
display:flex;
}
</style>
<!--<form action="" method="POST">-->
{% csrf_token %}
<div class="row">
<div class="col">
<div style="width:500px;" id="reader"></div>
</div>
<div class="col" style="padding:30px;">
<h4>Scanned Result</h4>
<!--<div id="result" name="result">Result Here</div>-->
<output type="POST" id="result" name="result" placeholder="qrCodeMessage">
{% csrf_token %}
</div>
</div>
<script type="text/javascript">
// 1) Create a function to get the CSRF token
function getCookie(name) {
let cookie = document.cookie.match("(^|;) ?" + name + "=([^;]*)(;|$)");
return cookie ? cookie[2] : null;
}
// 2) After generating the qrcode in the onScanSuccess callback, you invoke sendQrCode function with the qr code as argument
function onScanSuccess(qrCodeMessage) {
document.getElementById("result").innerHTML = '<span class="result">' + qrCodeMessage + "</span>";
// Call the function here
sendQrCode(qrCodeMessage);
}
//3) Fetch to send a POST request to nurse_qrscan route:
async function sendQrCode(qrCode) {
console.log(qrCode)
const response = await fetch("/nurse_qrscan", {
method: "POST",
headers: {
"X-CSRFToken": getCookie("csrftoken"),
},
body: JSON.stringify({
result: qrCode,
}),
})
.then((response) => response.json())
.then((data) => {
console.log(data)
}
);
}
function onScanError(errorMessage) {
//handle scan error
}
var html5QrcodeScanner = new Html5QrcodeScanner("reader", {
fps: 10,
qrbox: 250,
});
html5QrcodeScanner.render(onScanSuccess, onScanError);
</script>
{% endblock %}
<view_nurse.py>
#api_view(['GET',"POST"])
# Nurse scans QR
def nurse_qrscan(request):
if request.method == 'POST':
# parse the JSON data
data = json.load(request)
result = data.get("result")
if result != None:
c = connection.cursor()
# Saving the result to database, nurse_QR
c.execute("INSERT INTO nurse_QR (output) VALUES ('{0}');".format(result))
return Action.success()
<Image: Output shown in database - Values of the single QR code is repeated multiple times from the POSTS>

chartjs data isn't passing to django webpage

I'm trying to build a webpage with a chart in it. For the chart i'm using Chartjs.
Hardcoded data is no problem for the Chartjs chart. But if I'm trying to pass dynamic data the chart doesn't render.
The labels and results output is 46 (the dataframe is 46 rows with 1 column)
View.py
def results(request):
return render(request, 'results.html')
def result(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
data = request.FILES['file']
# handle_uploaded_file(data)
data = pd.read_csv(data,header=0, sep=',')
df = data.values
df2 = pd.DataFrame(df.reshape(-1,len(data.columns)))
x = getPredictions(df2)
x = np.array(x)
result = x.reshape(-1,1).round()
df = pd.DataFrame(data=result, columns=['output'])
labels = len(df)
# result = list(result)
return render(request, 'results.html', {'result': result, 'labels': labels})
else:
form = UploadFileForm()
return render(request, 'index.html', {'form': form})
html page
{% extends "base.html" %}
{% block content %}
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.9.3/dist/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/0.2.0/Chart.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<div class="content">
<div class="row">
<div class="col-sm-8">
<div class="card card-tasks">
<h4>Chart.</h4>
<canvas id="line-chart" width="500" height="350"></canvas>
<script>
new Chart(document.getElementById("line-chart"), {
type: 'line',
data: {
labels: {labels|safe},
datasets: [{
data: {result|safe},
label: "output chart",
borderColor: "#3e95cd",
fill: false
}
]
},
options: {
title: {
display: true,
text: 'output chart'
}
}
});
</script>
</div>
</div>
</div>
</div>
{% endblock content %}
For the variables to show up, in your template, you have to wrap them inside two curly braces: {{ }}, you are using only one.
Modify your chart code as follows:
{% extends "base.html" %}
{% block content %}
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.9.3/dist/Chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/0.2.0/Chart.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<div class="content">
<div class="row">
<div class="col-sm-8">
<div class="card card-tasks">
<h4>Chart.</h4>
<canvas id="line-chart" width="500" height="350"></canvas>
<script>
new Chart(document.getElementById("line-chart"), {
type: 'line',
data: {
labels: {{ labels |safe }},
datasets: [{
data: {{ result|safe }},
label: "output chart",
borderColor: "#3e95cd",
fill: false
}
]
},
options: {
title: {
display: true,
text: 'output chart'
}
}
});
</script>
</div>
</div>
</div>
</div>
{% endblock content %}
Thanks Amir for helping with the sugestion.
I had to update the scripts from chartjs. that made it work
had to put "{}" around the data and labels

Update a variable every 5 second using jquery

I am using django to create a webpage and this is the first time I am doing so. I am trying to fetch the value of a variable from .py file at an interval of 5 seconds. Below is the HTML code:
<!DOCTYPE html>
<html>
<head>
<title>Like Post App</title>
<script
src="https://code.jquery.com/jquery-3.4.1.js"
integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU="
crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</head>
<body>
<div class = "display-3 color-red"><center>DataFlair AJAX Tutorial<br>Post APP</center></div>
{% for post in posts %}
<div class = 'container jumbotron'>
<h3 class="display-5">{{ forloop.counter }}. {{ post.post_heading }}</h3>
<p class="lead">{{ post.post_text }} </p>
<p>
<div type="text/css" class = "container">Author : {{ post.post_author }}</div>
<a class="likebutton btn btn-primary btn-lg" id="like{{ post.id }}" data-catid="{{ post.id }}">Like({{ post.like_ref.counter }})</a> </p> <p id="message{{post.id}}">
</p>
</div>
{% endfor %}
<script type="text/javascript">
setInterval(function() {
getvalue(); // Do something every 5 seconds
}, 5000);
getvalue();
function getvalue(){
var id;
id = $(this).attr("data-catid");
$.ajax(
{
type:"GET",
url: "like",
data:{
post_id: id
},
success: function( data )
{
$( '#like'+ id ).text("Like(" + data +")");
var i=parseInt(data);
console.log("Value= "+i);
}
}
)
}
</script>
</body>
</html>
Below is the views.py code:
import json
from django.shortcuts import render
from .models import Post, Like
from django.http import HttpResponse
# Create your views here.
#DataFlair #AJAX_tutorial
def index(request):
posts = Post.objects.all()
return render(request, 'post/index.html', { 'posts': posts })
def like(request):
if request.method == 'GET':
post_id = request.GET['post_id']
likedpost = Post.objects.get(id = post_id )
m = Like.objects.filter( post=likedpost ).first()
m.counter +=1
m.save()
value1= int(m.counter)
#data1= {'cmd': 'success', 'ctr': str(m.counter) }
return HttpResponse(value1)
#return HttpResponse(json.dumps(data1))
else:
return HttpResponse("unsuccesful")
I keep getting the following errors:
1) GET http://localhost:8000/ajax/like/ 500 (Internal Server Error)
2) GET http://localhost:8000/favicon.ico 404 (Not Found)
Please help.
I believe:
id = $(this).attr("data-catid");
is not pointing to the button... maybe you should try:
id = $(".likebutton").attr("data-catid");

Flask variables not showing up in HTML

I have a small flask app I am using it to:
Make an HTML page with a leaflet map
Take user input from the HTML page...
Run calculations on that input using certain python modules
Return those variable to JS functions in the page to populate the map
I cannot get ANYTHING but lat and lng to return into my HTML {{}} flask variables.
Here is my HTML page:
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.3.1/dist/leaflet.css"
integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet#1.3.1/dist/leaflet.js"
integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw=="
crossorigin="">
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<title>Page Title</title>
<meta charset="utf-8"/>
<style>
#mapid { height: 300px; }
</style>
<body>
<form method="POST">
Latitude to PY: <input name="lat" id="lat"/>
<br/>
Longitude to PY: <input name="lng" id="lng"/>
<br/>
<button>Get data</button>
</form>
{% if lat1 != None and lng1 != None %}
{{lat1}},{{lng1}}
<script>
var lat1 = {{lat1}}
var lng1 = {{lng1}}
</script>
{% endif %}
{% if point != None %}
<p>{{point}}</p>
{% endif %}
{% if GeJ != None %}
{{GeJ}}
<script>
var GeJ = {{GeJ}}
</script>
{% endif %}
<div id="mapid"></div>
<script>
var mymap = L.map('mapid').setView([51.505, -0.09], 13);
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 18,
id: 'mapbox.high-contrast',
accessToken: 'pk.eyJ1IjoiY2dyb3RoIiwiYSI6ImNqZ2w4bWY5dTFueG0zM2w0dTNkazI1aWEifQ.55SWFVBYzs08EqJHAa3AsQ'
}).addTo(mymap);
function zoomTo() {
mymap.panTo(new L.LatLng(lat1, lng1));
}
function addGJ(){
var myLayer = L.geoJson(GeJ).addTo(mymap);
}
window.onload = zoomTo();
window.onload = addGJ();
</script>
</body>
</html>
Here is my Flask Python code:
from flask import Flask, render_template, request, flash, redirect, url_for,jsonify
from forms import RegistrationForm
import json
import osmnx as ox
import networkx as nx
import matplotlib.pyplot as plt
from networkx.readwrite import json_graph
import pandas as pd
import mplleaflet
app = Flask(__name__)
app.config.update(dict(
SECRET_KEY="powerful secretkey",
WTF_CSRF_SECRET_KEY="a csrf secret key"
))
#app.route('/')
def my_form():
return render_template('map.html')
#app.route('/', methods=['GET', 'POST'])
def my_form_post():
lat = (request.form['lat'])
lng = (request.form['lng'])
lat = lat
lng = lng
point = (lat,lng)
G = ox.core.graph_from_point(point, distance = 500, network_type='walk')
fig, ax = ox.plot_graph(G)
GJ = mplleaflet.fig_to_geojson(fig=ax.figure)
#return lat, ",", lng
return render_template('map.html', lat1=lat, lng1=lng, GeJ=GJ, point="test_string")`
if __name__ == "__main__":
app.run(host='0.0.0.0',port=5000,debug=True)
The Flask app is working fine so the file structure is not a concern. I just cannot get any other variables to return into my HTML. I even tried making little string dummy variables other that the real ones. No Dice.
Thanks
You could try using the builtin none value http://jinja.pocoo.org/docs/templates/#none
Then do something like:
{% if lat1 is not none and lng1 is not none %}
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.3.1/dist/leaflet.css"
integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet#1.3.1/dist/leaflet.js"
integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw=="
crossorigin="">
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<title>Page Title</title>
<meta charset="utf-8"/>
<style>
#mapid { height: 300px; }
</style>
<body>
<form method="POST">
Latitude to PY: <input name="lat" id="lat"/>
<br/>
Longitude to PY: <input name="lng" id="lng"/>
<br/>
<button>Get data</button>
</form>
{% if lat1 is not Null and lng1 is not Null %}
{{lat1}},{{lng1}}
<script>
var lat1 = {{lat1}}
var lng1 = {{lng1}}
</script>
{% endif %}
{% if point != None %}
<p>{{point}}</p>
{% endif %}
{% if GeJ != None %}
{{GeJ}}
<script>
var GeJ = {{GeJ}}
</script>
{% endif %}
<div id="mapid"></div>
<script>
var mymap = L.map('mapid').setView([51.505, -0.09], 13);
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 18,
id: 'mapbox.high-contrast',
accessToken: 'pk.eyJ1IjoiY2dyb3RoIiwiYSI6ImNqZ2w4bWY5dTFueG0zM2w0dTNkazI1aWEifQ.55SWFVBYzs08EqJHAa3AsQ'
}).addTo(mymap);
function zoomTo() {
mymap.panTo(new L.LatLng(lat1, lng1));
}
function addGJ(){
var myLayer = L.geoJson(GeJ).addTo(mymap);
}
window.onload = zoomTo();
window.onload = addGJ();
</script>
</body>
</html>
It would help if you provided an example of what exactly happens when you pass all the values.
Otherwise, what according to me, could be causing the problem is that the 'Null' object in python is the singleton None. The best way to check things for "Noneness" is to use is not None or better still, something as simple as:
{%if lat%} {{lat}} {% endif %}
Also, can't you assign GeJ to the var GeJ within the div instead of putting a line of JS in an abrupt manner up there?
P.S. I wanted to add this as a comment, but don't have enough reputation. Apologies.

How to send selected data from a datatable?

I take some user input that results in a table which I can display. Now I want to allow the user to select some data and then send these data back to another function where it is further processed. For the toy example I use for demonstration purposes, it might look like this:
Unfortunately, I fail to do so. The critical parts are probably thisjquery part (the entire code can be found below):
$('#send_data').bind('click', function() {
$.getJSON('/_selected_data', {
sel_data: table.rows().data().toArray()
}, function(data) {
alert('This worked')
});
return false;
});
and this part of my Python code:
#app.route('/_selected_data')
def get_selected_data():
sel_data = request.args.get('sel_data')
When I print sel_data it prints None, when I use requests.json it does not work either; ideally it would be possible to get the results again as a pandas dataframe with the same columns headers.
How would I do this correctly? Also, if the user does not select any data, then of course the entire table should be returned.
This is the entire code:
from flask import Flask, render_template, request, jsonify
import pandas as pd
import numpy as np
import json
# just for reproducibility
np.random.seed(0)
# Initialize the Flask application
app = 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')
print(sel_data)
return jsonify(dummy_data=1)
if __name__ == '__main__':
app.run(debug=True)
and my 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>get a pretty table</p>
<p>send selected data</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;
$('#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
});
});
return false;
});
$('#send_data').bind('click', function() {
$.getJSON('/_selected_data', {
sel_data: table.rows().data().toArray()
}, function(data) {
alert('This worked')
});
return false;
});
});
</script>
</body>
</html>
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>get a pretty table</p>
<p>send selected data</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, jsonify
import pandas as pd
import numpy as np
import json
# just for reproducibility
np.random.seed(0)
# Initialize the Flask application
app = 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.

Categories

Resources