问题
I am still in the process of learning how everything works, but I am trying to put together a project that has a table that needs to be sorted. I am using flask to generate the pages, and plan to keep the information for the table stored in sql. For the time being, I am using a hard-coded table of dictionaries that will eventually be converted from this sql database. I have successfully gotten my html page to load the flask table element into a table on the webpage. However, I would like to allow users to be able to sort through this table, and I believe using Javascript would be the best way to do this.
However, before I begin to write the sorting function, the problem I am having is somehow passing the table of dictionaries that is rendered in Flask into my Javascript file. I believe it would be best to have the html render the table from Flask first, and then have Javascript retrieve the table information straight from the html page.
To be clear, the format of the table in Flask is like this:
items = [{'item 1': "Name", 'item 2': "Name"}, {'item 1': "Name2", 'item 2': "Name2"}]
and is rendered in the html page like this:
{% for row in items %}
<tr>
<td class="item1">{{ row.item1 }}</td>
<td class="item2">{{ row.item2 }}</td>
</tr>
{% endfor %}
And somehow, I would like to render the same "items" variable in Javascript using the html page as its source. I have been able to find tutorials explaining a sorting function in Javascript however, these tutorials assume that the table already exists in JS, and I am unsure how to render it dynamically like this. Does anyone know how I would go about doing this? Thanks.
回答1:
As mentioned, datatables would be a good fit for your frontend, as it handles all the pagination, sort and search functionality automatically.
You may wish to have a look at the repo search-generic-tables. This is my implementation that uses an SQLite database, but most of what you're probably looking for is there.
The templates are built in such a way that data isn't hard coded into them. Many Flask tutorials involve hard-coding headers into the template <td>Header Name</td>
which stops the templates from being generic.
If you don't want to clone the whole repo, you could probably just copy both templates from the templates folder, which include the required CDN links to make datatables work.
To make this work with your code, (note the following assumes every dictionary in your list has the same keys!) you could do the following. Let's call your list of dictionaries original_items
and make the values unique for clarity:
original_items = [{'item 1': "Banana", 'item 2': "Car"}, {'item 1': "Apple", 'item 2': "Bike"}]
Define a function which makes this into a list of OrderedDicts
. This will keep the column order predictable in the table:
import collections
def sort_dict(d):
return collections.OrderedDict(sorted(d.items()))
ods = [sort_dict(d) for d in original_items]
Now make these into a list of lists:
table_items = [ list(v for _,v in od.items()) for od in ods]
table_items
is now a list of lists, which looks like:
[['Banana', 'Car'], ['Apple', 'Bike']]
Then get the headers from the first dictionary in the ods
list:
headers = [k for k,_ in ods[0].items()]
headers
now looks like:
['item 1', 'item 2']
So passing these through to the template becomes as simple as a view function which looks like:
@app.route('/all')
def all():
return render_template('index.html', headers=headers, objects=table_items)
This renders nicely in the browser:
If you want to change the left-right ordering of the columns, datatables provides a convenient way to do this natively without the need to change your Python code.
来源:https://stackoverflow.com/questions/61639807/manipulate-html-table-rendered-from-flask-in-javascript