My HTML table has 5 columns, and I am using jinja to dynamically render the amount of columns depending on the amount of data. I would like to nest a hyperlink in the 5th column for every row.
from flask import Flask,render_template
from time import time as t
app = Flask(__name__)
#app.route('/offers')
def offers():
data = (
("user1","btc","ltc",t(),"127.0.0.1:5000/offer/abcd"),
("user2","xrp","xmr",t(),"127.0.0.1:5000/offer/efgh"),
("user3","bch","ltc",t(),"127.0.0.1:5000/offer/hijk")
)
return render_template("offers.html", data = data)
HTML:
<html>
<body>
<table class="GeneratedTable">
<thead>
<tr>
<th>Name</th>
<th>Have</th>
<th>Want</th>
<th>Created</th>
<th>Link</Link></th>
</tr>
</thead>
<tbody>
{% for row in data %}
<tr>
{% for cell in row %}
<td>{{cell}}
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</body>
</html>
This will create the table, however the links (127.0.0.1:5000/offers/xxxx) will not be hyperlinks. How do I only make the final column a hyperlink using the links provided by the dataset? thanks.
Jinja does not recognise URL by default. You still need to manually format it. There are 2 ways to do that.
You can prepare the data in HTML format such as
data = (
("user1","btc","ltc",t(),"<a href=xxx>127.0.0.1:5000/offer/abcd</a>"),
("user2","xrp","xmr",t(),"127.0.0.1:5000/offer/efgh"),
("user3","bch","ltc",t(),"127.0.0.1:5000/offer/hijk")
)
Or you can format it in jinja template as below:
<tbody>
{% for row in data %}
<tr>
{% for cell in row %}
<td>
{% if loop.index0 != 4 %}
{{cell}}
{% else %}
<a href={{ cell }}>{{ cell }}</a>
{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
Here the key is to use Jinja syntax loop.index0 to get the index number of row.
Related
Currently i'm dealing with timetable project, have a list of schedule saved in database and i want to print them in a table where a schedule should be placed on a right place based on row(days) and columns (timeslots).
i have tried to arrange schedule and it appear as follows:
appearance of current tried schedule arrangement picture
The view used is as follows
def lecturerTimeTable(request):
lecname=Lecturer.objects.get(user=request.user.id)
context={
'schedule': TeachingTimetable.objects.filter(lecturer=lecname).order_by('meet_time'),#get lecturer
'program': Program.objects.all(),
'days': MeetingTime.objects.all().values('day').distinct(), #day
'slots': MeetingTime.objects.all().values('time').distinct(),#timeslot
'url_name':'class',#for active link
'lecturer':lecname,
'StarterPage':'Class-Timetable'# for head
}
return render(request,'users/class_timetable.html',context)
The template table is as follows
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th colspan="8"><center>{{lecturer}}</center</th>
</tr>
<tr>
<th></th>
{% for time in slots %}
<th class="time">{{time.time}}</th>{% comment %} timeslot from 07:00-09:00 to 17:00-21:00 {% endcomment %}
{% endfor %}
</tr>
</thead>
<tbody>
{% for day in days %}
<tr>
<th>{{day.day}} </th>
{% for lesson in schedule %}
{% if lesson.meet_day == day.day%}
{% if lesson.meet_time == '13:00 - 15:00' %}
<td>{{lesson.course}} <br>
{{lesson.lecturer}}<br>
{{lesson.venue}}<br>
{{lesson.meet_day}} {{lesson.meet_time}}</td>
{% comment %} {% endif %} {% endcomment %}
{% endif %}
{% endfor %}
</tr>
{% endfor %}
So i appreciate i will get help soon!
Thanks
I am trying to modify part of code in a flask application. What the flask app does so far:
It has around 20 links, when someone clicks on the link it returns .json objects (formed by python dictionaries via jsonify).
What I am trying to do:
Return the same results in a table format that can be potentially extracted to .csv
I created the following function:
def tab_out(output = {}):
return render_template('output_tab.html',output=output)
that sends the dictionary out to an html page, that contains this:
{% block content %}
<body>
<pre>
<table>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
<th>Header 4</th>
<th>Header 5</th>
<th>Header 6</th>
</tr>
{% for key_1, value in output.items() %}
{% for key in value.keys() %}
<tr>
<td>
{{ key_1 | safe }}
</td>
<td>
{{ key | safe }}
</td>
<td>
{{ value[key]["Header_3"] }}
</td>
<td>
{{ value[key]["Header_4"] }}
</td>
<td>
{{ value[key]["Header_5"] }}
</td>
<td>
{{ value[key]["Header_6"] }}
</td>
</tr>
{% endfor %}
{% endfor %}
</table>
</pre>
</body>
{% endblock %}
What's the issue:
I need to make it dynamic.
Each page has different headers.
In each page the resulted .json comes from a dictionary that has sub-dictionaries and the number of keys in each dictionary can be different. So I can't specify the headers before hand. I want them dynamically created. Maybe flatten out the dictionary (up to a level 2 let's say) if there's 3 sub-dictionaries and get the results as headers and the rest as values.
I've read a couple similar questions in sa, but none of them really helped me. Any ideas?
The jinja code below will generate HTML table from any FLAT dict.
The headers are dynamic. entry_list is a list of dicts. Your code should create a flat dict.
<table style="width:100%">
<!-- table header -->
{% if entry_list %}
<tr>
{% for key in entry_list [0] %}
<th> {{ key }} </th>
{% endfor %}
</tr>
{% endif %}
<!-- table rows -->
{% for dict_item in entry_list %}
<tr>
{% for value in dict_item.values() %}
<td> {{ value }} </td>
{% endfor %}
</tr>
{% endfor %}
</table>
<h3>Out of severice vehicles</h3>
<table class="table table-hover">
<tbody>
<tr>
{% for col in caidian_oos.columns %}
<th>
{{col}}
</th>
{% endfor %}
</tr>
{% for row in caidian_oos.values %}
<tr>
{% for cell in row %}
<td>
{{cell}}
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
<br />
--
The data object is a pandas dataframe
I want to add a column that user can click.
On user's click it should save the corresponding row to mysql database.
So im trying to create an HTML table using Jinja2 from a list of dictionaries (as returned by a Flask SQL select statement).
Right now test_list has stored a list of dictionaries (with the key's being the DB columns).
Right now im using this:
<table style="width:100%">
{% for dict_item in history_list %}
{% for key, value in dict_item.items() %}
<tr>
<th> {{ key }} </th>
<td> {{ value }} </td>
</tr>
{% endfor %}
{% endfor %}
</table>
It does work, but it's basically producing 2 columns (one being the keys and one being the columns). Im wanting to get the DB keys as columns titles in the table and then just the values placed into each column.
Is this possible? since I would want to iterate through the key's just once?
You need something like this, that provides a header row of th elements, then proceedes to the data rows (the body of the table).
<table style="width:100%">
<!-- table header -->
{% if history_list %}
<tr>
{% for key in history_list[0] %}
<th> {{ key }} </th>
{% endfor %}
</tr>
{% endif %}
<!-- table rows -->
{% for dict_item in history_list %}
<tr>
{% for value in dict_item.values() %}
<td> {{ value }} </td>
{% endfor %}
</tr>
{% endfor %}
</table>
I have a simple flask app and need to display a table of values, with the cell backgrounds colour coded based on the cell value according to thresholds. I'm generating the table content as follows:
{% block dashboard_table2 %}
<table>
{% for row in data %}
{% for item in row %}
<td>{{ item }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
{% endblock %}
I tried wrapping the values in style tags like this in Python but it didn't work:
if int(value) <= 10:
value = '<p style="background-color:Red">' + value + '</p>'
I'm guessing the CSS for the page is overriding the style attribute. I also tried just setting the text color attribute instead of background-color but no dice. Any suggestions on a good way to do this? I'd like to have a concise way to specify threshold values that aren't hard-coded in the templates.
The easiest way would be to put this display logic in your template:
<table>
{% for row in data %}
<tr>
{% for item in row %}
{% if item <= 10 %}
<td class="under-limit">{{ item }}</td>
{% else %}
<td>{{ item }}</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</table>
Then, in your CSS you can use:
.under-limit { background-color: red; }
<table>
{% for row in row %}
{% if item <= 10 %}
<tr style ="background-color: red">
<td> {{ item }} </td>
</tr>
{% else %}
<tr>
<td> {{ item }} </td>
</tr>
{% endif %}
{% endfor %}
</table>
This works for me.