Reputation: 1513
This thread here discussed using variables in inline JavaScript in templates. If I have separate .js
files containing scripts, sitting in static
folder, such as following:
utils.js
const createButton = (buttonCount) => {
containerId = "myContainerId"
container = document.getElementById(containerId)
for (var i = 0; i < buttonCount; i++) {}
newButton = document.createElement("button")
newButton.value = "Test"
newButton.id = "testButton" + i
container.appendChild(newButton)
}
}
createButton(buttonCount)
mytemplate.html
{% extends "base.html" %}
{% load static %}
{% block title %}Testpage{% endblock %}
{% block content-main %}
<link href="{% static "css/mycss.css" %}" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.4.0/css/bulma.css" />
<div id="myContainerId"></div>
<script src="{% static 'js/utils.js' %}"> </script>
{% endblock %}
If I have a variable buttonCount
passed into this template via a view function's context, how do I pass it to the utils.js
file to be called by function createButton()
?
views.py
def button_view(request):
...
buttonCount = 5
return render(request, 'mytemplate.html', {'buttonCount': buttonCount})
Upvotes: 1
Views: 1601
Reputation: 419
There can be a few ways:
<input id="buttonCount" value = "{{buttonCount}}" style="display:none;">
Then read value of element with id= buttonCount in utils.js.
Inline Script **Not Suggested,Use Document.onload instead.
<script>
set_button_count({{buttonCount}});
</script>
But this will create a problem when your utils.js is not loaded yet.
<head></head>
<script src="{% static 'js/utils.js' %}" defer> </script>
<script>
document.addEventListener('onload',function(
{set_button_count({{buttonCount}});
})
</script>
Warning: Inline scripts are to be used with strict CSP (Content Security Policy).Any inline script can be given a
src
asnonce
. CSP can be done on Server Side on apache or Nginx which are very common web server/reverse proxy or you can also mention the same in HTML if you don't have control on that.
<meta http-equiv="Content-Security-Policy"
content="default-src 'self';
script-src 'self' 'nonce-{{nonce}}';">
and this nonce
can be generated something like this:
import random,base64
def usersession_processor(request):
user = request.user
unbaked_nonce = '%32x' % random.getrandbits(16*8)
unbaked_nonce = unbaked_nonce.encode('utf-8')
baked_nonce = base64.b64encode(unbaked_nonce)
baked_nonce = baked_nonce.decode('utf-8')
Then <script src="{{nonce}}"></script>
can be used for safe inlines.
Upvotes: 2
Reputation: 152
I don't think this is recommended but you could do something like this if you're using the django template context. Put the script at the bottom of the page and include the buttoncount as a Django Templating Language variable. I don't think it's recommended to mix Django template variables with javascript though.
You can put a new block in your 'base.html' file, at the bottom inside the body tag like this:
{% block inline_javascript %}
{% enblock inline_javascript %}
Then inside the page you want the function to run on you put the script inside the same tags at the bottom of that page outside the 'block content' like:
{% block inline_javascript %}
<script>
const createButton = ({{ buttonCount }}) => {
containerId = "myContainerId"
container = document.getElementById(containerId)
for (var i = 0; i < {{ buttonCount }}; i++) {}
newButton = document.createElement("button")
newButton.value = "Test"
newButton.id = "testButton" + i
container.appendChild(newButton)
}
}
</script>
{% enblock inline_javascript %}
Upvotes: 1