Reputation: 331
So I'm using a Jinja2 Template in Flask to render a HTML document. Im passing a dict named "healthy_alerts" into the Jinja template. The dict snippet looks likes this (sensitive values manipulated):
healthy_alerts = {
...
"52.NE": {
"appliance_id": 123456,
"severity": "green",
"ip": "x.x.x.x",
"hostname": "HG-EDGE-FranceAntony-ECV01",
"serial": "11-11-11-11-11",
"critical_alarms": 0
},
"6.NE": {
"appliance_id": 7891011,
"severity": "green",
"ip": "y.y.y.y",
"hostname": "HG-EDGE-Schiltach-ECV01",
"serial": "22-22-22-22-22",
"critical_alarms": 0
}
}
This is a code snippet:
<div id="alarms" align="center">
{% if healthy_alerts %}
<div class="healthy_div">
{% for dev in healthy_alerts %}
<button class="btn_healthy" id="{{ healthy_alerts.get(dev).get('hostname') }}Btn"></button>
<div id="{{ healthy_alerts.get(dev).get('hostname') }}Modal" class="modal">
<!-- Modal content -->
<div class="modal-content">
<span class="close">×</span>
<p>{{ healthy_alerts.get(dev) }}</p>
</div>
</div>
<script>
// Get the modal
var modal = document.getElementById('{{ healthy_alerts.get(dev).get("hostname") }}Modal');
// Get the button that opens the modal
var btn = document.getElementById("{{ healthy_alerts.get(dev).get("hostname") }}Btn");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks the button, open the modal
btn.onclick = function() {
modal.style.display = "block";
}
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
{% endfor %}
</div>
{% endif %}
</div>
It seems like everything is almost there but the only problem is when I click on any of the modal buttons, it always shows me the same entry ("6.NE").
When I inspect the page in Chrome I can see the correct info is getting populated for all the modals. However, as you can see from the following chrome output, when I click on the the modal button it still always shows the same info (the "6.NE" entry) no matter what.
I think it may be some trivial JavaScript issue but I'm not a JavaScript coder.
Upvotes: 0
Views: 98
Reputation: 29092
I'm not familiar with Jinja but based on the JavaScript code I'd say it's because you aren't scoping your variables correctly, so they're being treated as globals. The variables modal
, button
and span
aren't declared in a function so they'll be treated as globals despite using var
. Even though each of your <script>
tags is separate they still share the same globals. It's only modal
that is a problem as it's used inside the event handlers and will reference the last value assigned to modal
.
If you wrap that script code in an IIFE you should be fine:
(function() {
// Get the modal
var modal = document.getElementById('{{ healthy_alerts.get(dev).get("hostname") }}Modal');
// ...
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
})();
If you aren't familiar with IIFEs:
https://developer.mozilla.org/en-US/docs/Glossary/IIFE
Upvotes: 1