How to render items in succession with Flask/Jinja2? - python

I'm trying to cycle through a list of variables on my application's front-end. The only caveat is I want the variables to cycle through a list showing one variable at a time. How can I achieve this? Is there some functionality in Jinja2 that allows you to do this?
<div class="vert-al" align="center">
{% for x in [1,2,3,4,5] %}
<span class="badge badge-danger">{{x}} alligators in the pool!</span>
{% end for %}
</div>
As is, the snippet will render a line for each of the elements in the list. Instead, I would like to cycle through them in place.
The CSS for vert-al looks like this:
.vert-al{
vertical-align:middle;
margin-bottom: 1rem;
margin-top: 1rem;
}
Javascript that fades the variable in and out:
setInterval(function(){
$(".badge-danger").fadeOut(2100);
$(".badge-danger").fadeIn(900);
}, 3000);
I'm not sure whether to tackle this problem with python/jinja or more of a js/css route so any guidance would be super helpful!

Jinja is going to render your variables only once, when the page loads. If you want to cycle through them, you'll have to make sure that they're all there. Then you can show/hide them with JS.
Maybe something like this:
<div class="vert-al" align="center">
{% for x in [1,2,3,4,5] %}
<span class="badge badge-danger" id="gator-{{x}}" style="display:none">{{x}} alligators in the pool!</span>
{% end for %}
</div>
Then:
for (var i = 0; i < num_gators; i++) {
document.getElementById("gator-" + i).fadeIn(900);
}
Note: Not sure about that Javascript, but you get the idea.

Related

How to make a drop-down menu scrollable

I am trying to build a drop-down menu in a navbar. I have done this, but the list of items is too long to fit on the page (the bottom of the list is hidden) so I therefore need to make the list scrollable. As of now, when the menu is "open" and I scroll, it scrolls the page behind the menu rather than the menu. Please help me figure this out! Below I have posted a bit of my HTML and CSS as it pertains to this drop down menu.
<li class="nav-item dropdown">
INSTRUMENTS
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
{% for instrument in instruments %}
{{ instrument.name }}
{% endfor %}
</div>
</li>
.scrollable-menu {
height: auto;
max-height: 500px;
overflow-x: hidden;
}
Have you tried using overflow-y: auto or overflow-y: scroll yet? Don't have the time to work on an example at the moment, but that should point you in the right direction.
You can find a similar post here for more info.
I think you are missing the correct selector.dropdown-menu is the correct selector if not solved then try overflow:auto;
if not solved then try this example

Get individual graphs from Plotly using Flask and Python

I am trying to show graphs made in plotly on a webpage served by flask.
The way it is set up now, they both display on the same page, one on top of the other. I want to show them individually on different pages.
The solution I found for plotly displays all of the graphs made, and I'm not sure how to get individual graphs
My flask/python
graphs = [
dict(
data=[thetaGraph, deltaGraph, alphaGraph, betaGraph,gammaGraph ],
layout=dict(
title='Brain Data'
)
),
dict(
data=[xGraph,yGraph,zGraph],
layout=dict(
title='Accelerometer Data'
)
),
]
ids = ['graph-{}'.format(i) for i, _ in enumerate(graphs)]
graphJSON = json.dumps(graphs, cls=plotly.utils.PlotlyJSONEncoder)
return render_template('index.html', title='Home',ids=ids, graphJSON=graphJSON)
And then the webpage
<div class="container">
<div class="row">
<!-- LEFT SIDE -->
<div class="col-6">
{% for id in ids %}
<div id="{{id}}"></div>
{% endfor %}
</div>
</div>
</div>
<footer>
<script type="text/javascript">
var graphs = {{graphJSON | safe}};
var ids = {{ids | safe}};
for(var i in graphs) {
Plotly.plot(ids[i], // the ID of the div, created above
graphs[i].data,
graphs[i].layout || {});
}
</script>
</footer>
Im unsure how to get just the first graph in that html, and then the second graph elsewhere on the page. Ive tried using {% for id in range(0,1) %} just to get the first element, or just putting <div id="{{ids[0]}}"></div>
but I get 'ids' in undefined
When printing out ids i get ['graph-0', 'graph-1'] which means that this is a list and I should be able to index it, but apparently that is not a thing with flask. I'm sure there is some strange way that flask needs it similarly to it's ways of reading from 2D arrays
I was able to figure out a way to complete my task, but it does not involve indexing arrays. Since the javascript creates usable id's I am able to show individual graphs by simple referencing them
Replacing
<div class="col-6">
{% for id in ids %}
<div id="{{id}}"></div>
{% endfor %}
</div>
With
<div class="col-6">
<div id="graph-0"></div>
</div>
Gave me the outcome I was looking for

Can We use page breaks in for loops?

I wanted to print barcodes using for loop in python. This is my code:
`{%- from "templates/print_formats/standard_macros.html" import add_header -%}
<hr>
{% set a = doc.end %}
{% set count = 0 %}
<div class="row">
{%- for i in range(doc.start,doc.end) -%}
<div class="col-md-4 text-center">
<p style="font-family: Code39AzaleaFont;font-weight: normal;font-style: normal;font-size:30px;">
00000000000000{{ i }}</p>
{% set count = count + 1 %}
{{count}}
<br/>
</div>
{%- endfor -%}
</div>
<hr>
<br>
<p class="strong">
<br>
<br>
<br>
{{ _("Authorized Signatory") }}
</p>
</div>`
The problem is,I wanted to restrict the number of barcodes printed on one sheet of paper to 24.Is there any way to do that?
You can add a page break after every 24th barcode using:
{% if count % 24 %}<div style="page-break-before: always;"></div>{% endif %}
HTML doesn't have a really good concept of "paper sheet size". A HTML page has an infinite height and browser's are notoriously bad a printing HTML in a readable way (with the notable exception of Opera).
With CSS 3, three page break properties were defined.
They might be supported by your browser. If they are, then wrap 24 bar codes in a <div> and give that <div> a class which tells the browser to break the page afterwards.
If the browser emits an empty page at the end, then you need two classes: One for the first <div> without a page break and one for every successive <div> and a page-break-before: always;
If that doesn't work well, you should look at PDF. PDF allows you place elements exactly on pages with a known, fixed size.

To use charts in app (created using Django) created using pylab in the HTML file

My code:
<html>
<style type="text/css">
h1 {
position: absolute;
top: 5px;
left: 200px;
}
form #Edit1 {
position: absolute;
top: 37px;
left: 410px;
}
form #Edit2 {
position: absolute;
top: 37px;
left: 840px;
}
</style>
<font size="4" face="arial" color="#0000FF">
<h1>XML Search</h1>
</font>
<br/>
<br/>
<Form Action ="/search/" Method ="POST">
<div id="Edit1">
<INPUT TYPE = 'VARCHAR' name ='word' VALUE ="" size = "50">
</div>
<div id="Edit2">
<INPUT TYPE = "Submit" VALUE = "Search">
</div>
<br/>
<hr/>
{% csrf_token %}
</Form>
{% if list1 %}
<br/>
<head>
#!/usr/bin/python
# make a horizontal bar chart
from pylab import *
val = 3+10*rand(5) # the bar lengths
pos = arange(5)+.5 # the bar centers on the x axis
figure(1)
barh(pos,val, align='center')
{% for l in list1 %}
xticks(pos, ({{l.file_name}},))
{% endfor %}
xlabel('Performance')
title('How fast do you want to go today?')
grid(True)
show()
</head>
<body>
<div id="chart_div" style="width: 1000px; height: 500px;"></div>
</body>
{% endif %}
</html>
I have created an app in Django called 'search' which searches the keywords entered by the user in 10xml documents and maintain the frequency of their occurrence for each file. When user enters the words he gets the results as graphs. This above mentioned HTML code file is redirected from views.py file. On running the app on the server, the Python code employed alongwith the HTML code, gets printed as it is when user enters the keywords. How can I display the charts created in pylab in HTML page?
I have another idea, I used up Google charts earlier and they are working fine. The only problem with them is that they will not work if there is no Internet, and this will be a drawback in may app. Is there any way out to solve this, I mean how can we use Google charts statically? If anyone of you want you want me to upload my Google charts code, I can do that.
You need to use the FigureCanvasAgg backend and return a HttpResponse. See for instance:
[Django with Matplotlib][1]
How to use Matplotlib in Django?

How would I modify jinja2 to keep CSS and JavaScript with the corresponding HTML in included files?

This is my first question ever on SO and I'm happy to take any tips on improving. Be gentle :)
To increase maintainability, I am trying to keep CSS, JS and HTML all together in the same file. This becomes difficult with include files, or macros, etc. The final output template.render() should grab all that CSS and JS, and place it at the top and bottom of the base HTML template.
Example should explain what I mean:
base.html
<html>
<head>
<style>
{{ print_css() }}
</style>
</head>
<body>
{% include 'bolded_text.html' %}
<script>
{{ print_js() }}
</script>
</body>
</html>
bolded_text.html
{# this doesn't need to be a filter. It could be a block, or anything else that would make this work #}
{% filter add_css %}
strong {
background: #ccc;
}
{% endfilter %}
<strong>Bolded text</strong>
{% filter add_js %}
alert('javascript included!');
{% endfilter %}
Output would of course be:
<html>
<head>
<style>
strong {
background: #ccc;
}
</style>
</head>
<body>
{% include 'bolded_text.html' %}
<script>
alert('javascript included!')
</script>
</body>
</html>
Predictably, the problem is that print_css() outputs nothing.
I tried doing this with context filters, where add_js and add_css append to a variable in the context, and then print_css and print_js output that variable. This works nicely and simply for JavaScript, since the print statement follows all the filters.
However, I can't think of a way to make it work with CSS. If I could make the print_css() call lazy, or swap in the output in the jinja2 AST somehow, that might work. I'm trying to avoid hacky string manipulation (such as outputting the CSS at the bottom and then using regexes to move it to the top).
I figured there might be a way to do this elegantly and my experience with jinja2's low-level API is limited.
Any help is much appreciated, thanks!
Macros will do that, but I don't see the point why you wouldn't use StyleSheets, this enables the browser a way better caching and it's also easier to maintain.
EDIT:
Example:
{% macro generate_css(strong_bg='#ccc', additional_options=None) -%}
strong {
background: {{ strong_bg }};
}
{%- endmacro %}
<head>
<style>
{{ generate_css() }}
</style>
</head>

Categories