I am trying to pass a variable from Flask, to an HTML template, and then use that variable in a separate JavaScript file.
routes.py
fav_photo_index = Photo_Index()
@app.route("/slideshow", methods=["POST", "GET"])
def slideshow():
cur_image_index = fav_photo_index
print(cur_image_index.index, image_urls[cur_image_index.index])
if request.method == "POST":
update_index(request, cur_image_index)
favorite = is_favorite(image_urls[cur_image_index.index])
return render_template('slideshow.html',
title="Slideshow",
images=image_urls,
favorite=favorite,
index=cur_image_index.index)
I want to use index
variable in a JS file. I've seen in various places how to use that variable in the HTML template, but not how to pass it to a .js file for use there...
slideshow.js
var slideIndex = "{{index}}";
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("slide");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length} ;
for (i = 0; i < x.length; i++) {
// x[i].style.display = "none";
x[i].classList.remove('slide-visible');
}
// x[slideIndex-1].style.display = "block";
x[slideIndex-1].classList.add('slide-visible');
}
As you can hopefully see, I want the index
variable to get used in the .js
file...How can I do that?
So far I've just tried adding the variable in the head of slideshow.html
but it's not working:
Current slideshow.html
:
{% extends "layout.html" %}
{% block topscripts %}
<link rel="stylesheet" type="text/css" href= "{{ url_for('static',filename='styles/slideshow.css') }}">
{% endblock %}
{% block content %}
{% include "/HTML Snippets/favorite_button.html" %}
<div class="slideshow-container">
{% for image in images %}
{% if image != "favicon.ico" %}
<img class="slide" src="{{ url_for('static', filename='images/' + image) }}">
{% endif %}
{% endfor %}
<form action="" method="post">
<input type="hidden" name="prev-next-buttons">
<button class="w3-button w3-display-left" name='prev-photo' onclick="plusDivs(-1)">❮</button>
<button class="w3-button w3-display-right" name='next-photo' onclick="plusDivs(+1)">❯</button>
</div>
</form>
{% endblock %}
{% block endscripts %}
<script type="text/javascript" src="{{ url_for('static', filename='scripts/slideshow.js') }}"></script>
{% endblock %}
But it doesn't pass that variable to the .js
file for use. The console shows the error:
Uncaught TypeError: Cannot read property 'classList' of undefined
at showDivs (slideshow.js:24)
at slideshow.js:2
FYI here's layout.html
:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href= "{{ url_for('static',filename='styles/layout.css') }}">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
{% block topscripts %}
{% endblock %}
</head>
<body>
<div class="topnav">
<a class="active" href="{{url_for('main')}}">Index</a>
<a class="active" href="{{url_for('favorites')}}">Favorites</a>
<a class="active" href="{{url_for('slideshow')}}">Slideshow</a>
</div>
<div class="container">
{% block content %}
{% endblock %}
</div>
</body>
<script type="text/javascript" src="{{ url_for('static', filename='scripts/jscript.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='scripts/jQueryRotate.js') }}"></script>
{% block endscripts %}
{% endblock %}
</html>
Try this. Place the variable inside the slideshow.html within the {% block content %} .. {% endblock %} because it needs to be declared and created first and passed to the base template. Anything outside of the block will likely be ignored by the base template.
{% block content %} <script> var slideIndex= {{ index }} </script> ...rest of your content {% endblock %}
It might be a problem because by doing inline scripting, you're defining the variable slideIndex
outside the scope of the JavaScript code imported (thus making the function showDivs(n)
not recognize that variable)
<script type="text/javascript" src="{{ url_for('static', filename='scripts/slideshow.js') }}"></script
One way I found to tackle the problem was by looking at: How can I pass data from Flask to JavaScript in a template?
Answer: mcote
Basically he is saying that you can embed a data attribute in your HTML inside a tag, for example a div, which can later be retrieved from inside JavaScript, like so:
<div id="hisDiv" data-slindex="{{slideIndex|tojson}}">
var slideIndex = JSON.parse(document.getElementById("hisDiv").dataset.slindex);
Put your JS in the HTML file and it will work just fine.
<html> <head> </head> <body> {% extends "layout.html" %} {% block content %} {% include "/HTML Snippets/favorite_button.html" %} <div class="slideshow-container"> {% for image in images %} {% if image != "favicon.ico" %} <img class="slide" src="{{ url_for('static', filename='images/' + image) }}"> {% endif %} {% endfor %} <form action="" method="post"> <input type="hidden" name="prev-next-buttons"> <button class="w3-button w3-display-left" name='prev-photo' onclick="plusDivs(-1)">❮</button> <button class="w3-button w3-display-right" name='next-photo' onclick="plusDivs(+1)">❯</button> </div> </form> {% endblock %} </body> {% block scripts %} {% endblock %} <script type="text/javascript"> var slideIndex = "{{index}}"; showDivs(slideIndex); function plusDivs(n) { showDivs(slideIndex += n); } function showDivs(n) { var i; var x = document.getElementsByClassName("slide"); if (n > x.length) {slideIndex = 1} if (n < 1) {slideIndex = x.length} ; for (i = 0; i < x.length; i++) { // x[i].style.display = "none"; x[i].classList.remove('slide-visible'); } // x[slideIndex-1].style.display = "block"; x[slideIndex-1].classList.add('slide-visible'); } </script> </html>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.