Issue
This is my first time building a web app and I wanted to start from scratch to learn the basics. So I had a Python script that I wanted to practice with that printed tables of data on the terminal and decided to use Flask, HTML, CSS, JS to display that table on a web page. I got that working so far.
Now, I want to sort that table by clicking on the table headers.
This is the overall breakdown of my code and what I got up to so far:
Python script
from flask import Flask, render_template, request, url_for
app = Flask(__name__)
def get_table():
...
return dict //returns list of dictionaries, for example...
//dict = [{'name':'Joe','age':'25'},
// {'name':'Mike','age':'20'},
// {'name':'Chris','age':'29'}]
@app.route("/")
def home():
return render_template('home.html')
@app.route("/table", methods = ['POST','GET'])
def table():
if request.method == 'GET': //When button pressed on homepage
dict_table = get_table() //return list of dictionaries of names and ages
return render_template('table.html', dict_table=dict_table)
if __name__ == '__main__':
app.run(debug=True)
HTML file table.html
<!DOCTYPE html>
<html>
<head>
<title>Display Table</title>
<script type="text/javascript" src="/scripts/app.js"></script>
</head>
<body>
<table id="table">
{% if dict_table %}
<tr>
{% for key in dict_table[0] %}
<th onclick="sortTable(1)" style="cursor:crosshair">{{ key }}</th>
{% endfor %}
</tr>
{% endif %}
{% for dict in dict_table %}
<tr>
{% for value in dict.values() %}
<td>{{ value }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
</body>
</html>
So the table displays correctly on my web browser. I used the sort function they taught on the W3 schools website in my app.js script.
app.js
function sortTable(n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("myTable");
switching = true;
//Set the sorting direction to ascending:
dir = "asc";
/*Make a loop that will continue until
no switching has been done:*/
while (switching) {
//start by saying: no switching is done:
switching = false;
rows = table.rows;
/*Loop through all table rows (except the
first, which contains table headers):*/
for (i = 1; i < (rows.length - 1); i++) {
//start by saying there should be no switching:
shouldSwitch = false;
/*Get the two elements you want to compare,
one from current row and one from the next:*/
x = rows[i].getElementsByTagName("TD")[n];
y = rows[i + 1].getElementsByTagName("TD")[n];
/*check if the two rows should switch place,
based on the direction, asc or desc:*/
if (dir == "asc") {
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
//if so, mark as a switch and break the loop:
shouldSwitch= true;
break;
}
} else if (dir == "desc") {
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
//if so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
}
}
if (shouldSwitch) {
/*If a switch has been marked, make the switch
and mark that a switch has been done:*/
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
//Each time a switch is done, increase this count by 1:
switchcount ++;
} else {
/*If no switching has been done AND the direction is "asc",
set the direction to "desc" and run the while loop again.*/
if (switchcount == 0 && dir == "asc") {
dir = "desc";
switching = true;
}
}
}
}
This is the example I got from https://www.w3schools.com/howto/howto_js_sort_table.asp
These are my issues so far
- When I call that function sortTable, in the example they feed in the parameters 0 and 1 for sortTable(n) because their table is not dynamically rendered like mine. How do I handle this situation if im trying to use that function to sort my table since my table is dynamically created? I'm referring to the line in my HTML file. I can't find sources where they teach how to handle this scenario and I would like to learn.
- If I feed it a parameter 1, when I click on my table header, nothing happens. Can someone guide me towards where my mistake is and how I can fix it? I'm thinking it's because the table gets created in the loop after the headers are created so it has nothing to iterate over.
I would like it if someone could guide me through this. I'm also open to hearing if there are better ways for me to do this as well, as long as it's not overly complicated and involve installing external applications like some solutions I've seen to similar problems like this (since i'm just a beginner and trying to learn). Thanks!
Solution
Paremeter n
in the sortTable
function is the number of the row. And when you render header of your table, you always pass 1. To fix it you can try
{% for key in dict_table[0] %}
<th onclick="sortTable({{ loop.index0 }})" style="cursor:crosshair">{{ key }}</th>
{% endfor %}
That should do the trick.
For further information visit this jinja tricks page and the full jinja documentation.
UPD Also there is a list of control structures.
Answered By - Montreal
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.