How to use flask framework to render the html, send JSON data and have ajax update table
How to use flask framework to render the html, send JSON data and have ajax update table
I was trying the Ajax data source (objects) example -- https://datatables.net/examples/ajax/objects.html. It worked as expected including running it via flask.
Rather than filling the table from a JSON file I would like to use flask to render the html and provide the JSON data to ajax to fill the table.
Flask starts to render the page except where the data is supposed to be it says loading. I also get a popup that says 127.0.0.1:5000 says DataTables warning: table id=example - Invalid JSON response. For more information about this error, please see http://datatables.net/tn/1
I tried the link but it didn't have any additional information. I tried various things but no change. Any ideas?
# flaskText.py
from flask import Flask, render_template, jsonify
import json
# Assume data comes from somewhere else
data = {
"data": [
{
"id": "1",
"name": "Tiger Nixon",
"position": "System Architect",
"salary": "$320,800",
"start_date": "2011/04/25",
"office": "Edinburgh",
"extn": "5421"
},
{
"id": "2",
"name": "Garrett Winters",
"position": "Accountant",
"salary": "$170,750",
"start_date": "2011/07/25",
"office": "Tokyo",
"extn": "8422"
}]
}
app = Flask(__name__)
@app.route('/index')
@app.route('/')
def index():
# return render_template('index.html',data=data)
return render_template('index.html',data=json.dumps(data))
if __name__ == '__main__':
app.run(debug=True)
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Datatables Example</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.18/css/jquery.dataTables.min.css"/>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdn.datatables.net/1.10.18/js/jquery.dataTables.min.js"></script>
</head>
<body>
<h1>My First Heading</h1>
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Extn.</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Extn.</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</tfoot>
</table>
<script>
$(document).ready(function() {
$('#example').DataTable( {
"ajax": {
// "url": "static/objects2.txt", // This works for the static file
"url": "/index", // This doesn't work
"dataType": "json",
// "dataSrc": "data",
// "contentType":"application/json"
},
"columns": [
{ "data": "name" },
{ "data": "position" },
{ "data": "office" },
{ "data": "extn" },
{ "data": "start_date" },
{ "data": "salary" }
]
} );
} );
</script>
</body>
</html>
This question has an accepted answers - jump to answer
Answers
The problem is you can't return the web page and data at the same time for Datatables. You will need to return the web page, it will load and Datatables will initialize then send the ajax request. This will need to be a different URL that will simply return the JSON data. You will have two Python functions; index and dt_index (or whatever you want to call the URL for the ajax request).
Kevin
Thank you so very much @kthorngren . I have literally been trying to get this to work for 40+ hours.
I have included the full solution below:
flaskTest.py
/templates/index.html
This works to paint the table, but this approach does not permit the code needed to click on rows and add a reaction to those clicked table lines.
Ordinarily that code is installed after the $().DataTable({ bracket in the $(document).ready function ... but it doesn't work because this code is only used for loading.
How do we work with the lines once loaded?
You could add that code inside
initComplete
, that would ensure the table is loaded and ready.Colin
Thanks @colin ; I added the initComplete but was unclear how to place it and I can't get it to alert or drive work based on single row clicks. Here's what I have so far ...
Sorry to take so long to respond to your note as well. I just saw it this evening. Cheers
I suspect if you look at the browser's console you will see an error complaining about something being undefined. You have this:
The variable
table
has not been defined. You can get an instance of the API in the click event like this:You are using
data[0]
but you have defined your data using objects so you will needdata.id
instead.Kevin
How to work in the setupData call with this approach though?
function setupData() {
?
}
$( window ).on( "load", setupData );
This doesn't load the table...
We're happy to take a look, but as per the forum rules, please link to a test case - a test case that replicates the issue will ensure you'll get a quick and accurate response. Information on how to create a test case (if you aren't able to link to the page you are working on) is available here.
Cheers,
Colin
I didn't intend for you to move the this line. With that you did you are creating a click event with setupData(). In order to load the table you will need to click on the table. I expected you to add the line
var table = $('#example').DataTable();
to your click event to get an instance of the Datatables API as described here. Like this:Also you update this line:
$var table = $('#example').DataTable({
The leading
$
will cause a syntax error. Make sure to remove it as shown in my updated code.Kevin
@kthorngren worked like a charm - thanks Kevin.
I think this will be a frequently referenced post because I searched for a solution for three weeks and there wasn't a single reference to database-driven selects.
This has to be a common requirement of every reactive webpage...
@kthorngren - A side note, is that the test case tools are great but I don't have a production url for the data ("url": "/indlist"). Is there a trick that emulates the json data returned from the ajax database call?
I think there are some Javascript ajax emulators but for most "test cases" I don't think that is needed. Unless the problem being worked is ajax related most of the time Javascript data is good enough. Here is en example. Many times you can just get a sample of the JSON response and apply it to Datatables using
data
.You can also use
ajax
as a functon. There is a simple example in the docs. This Scroller example shows how you can simulate using ajax. But there is no ajax request sent.HTH,
Kevin
Great examples - much obliged. I'm new to javascript so even though this might seem obvious to developers, it's a big help for noobs (like me ...
We all started at the noob level Glad you got it working.
Kevin
@kthorngen This table syntax page is generating the error:
[Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event. Consider marking event handler as 'passive' to make the page more responsive. See https://www.chromestatus.com/feature/5745543795965952
Do you have any ideas on what could be causing this ?
https://stackoverflow.com/questions/37721782/what-are-passive-event-listeners discusses the issue with a solution that crashes Mozilla browsers ...
What syntax are you referring to? Is there an example we can look at?
Kevin