Django Template - List not rendering properly - javascript

I have the following list which is sent to django template using render function: ["9.8 m/s", "9.9 m/s", "1.0 m/s"].
When the list is printed in javascript function, it shows as: ["9.8 m/s", "9.9 m/s", "1.0 m/s"]
I have used the following to print the list: console.log("{{ options }}"); in javascript function.
I have tried iterating over as
{% for option in options %}
console.log("{{ option }}");
{% endfor %}
The above code displays single characters as opposed to printing list elements.
Also tried JSON.parse and JSON.stringify functions in javascript.

The template engine will HTML escape the strings it renders. You can avoid that with the |safe template filter:
var options = {{ option|safe }};
for (var i = 0; i < options.length; i++) {
console.log(options[i]);
}

Related

How do I set the variables in this javascript file to match variables from Flask/Python?

I have a Javascript file that enables drop down menus dynamic (i.e. a selection from one drop down impacts the others). I would like to use this file in conjunction with multiple forms but I have hard-coded the starting variables in this file to html elements 'inverter_oem' and 'inverter_model_name'.
In other forms, I will need to reference different objects.
How can I accomplish this?
I would like to create the variables in Javascript this way:
const selecting_dropdown_menu = document.getElementById(variable1_from_flask);
const filtered_dropdown_menu = document.getElementById(variable2_from_flask);
My current approach is to try and pass variables from the Flask route using render_template. (I have also tried other stack overflow solutions but no luck)
#db_queries.route('/db_query_dynamic_form/<form_name>', methods=['GET', 'POST'])
def db_query_dynamic_form(form_name):
# use methods to get form and endpoint for outside loop
if request.method == 'POST':
# inside loop when form complete
return render_template('list.html', result=query_results["filtered_tables"], columns=query_results["column_names"])
# added variable to pass to jinja template
return render_template(form_endpoint["endpoint"], form=form_endpoint["form"], var="value1")
The jinja template form is as follows
% extends "base.html" %}
{% block title %}Inverter Dynamic Search{% endblock %}
{% block heading %}Inverter Dynamic Search{% endblock %}
{% block content %}
<form method="POST">
{{ form.hidden_tag()}}
{{ form.inverter_oem.label }}{{ form.inverter_oem }}<br>
{{ form.inverter_model_name.label }}{{ form.inverter_model_name }}<br>
{{form.submit()}}
{{test}}
</form>
<script>
myVar = {{ var }}
</script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="{{ url_for('static', filename='search_inverter_dynamic.js') }}"></script>
{% endblock %}
However, I dont get a value in the javascript file when I try
console.log(myVar);
Here is the original JScode with the "hardcoded" variables
//acquire inverter_oem value from form
const inverter_oem_select = document.getElementById('inverter_oem');
const inverter_model_name_select = document.getElementById('inverter_model_name');
//add event listener to capture selected oem in dropdown
inverter_oem_select.addEventListener('click', (e) => {
let oem = '../modelNameByOEM//' + e.target.value;
console.log(oem);
getIt(oem);
});
//recover a JSON containing the list of models from a specific oem
async function getIt(input) {
try {
const res = await axios.get(input);
console.log(res.data);
optionHTML = '';
for (let modelName of res.data.modelNameOem) {
//console.log(res.modelName.name);
optionHTML += '<option value="' + modelName.name + '">' + modelName.name + '</option>';
//console.log(optionHTML);
}
inverter_model_name_select.innerHTML = optionHTML;
} catch (err) {
console.log('Could not reach endpoint modelNameByOEM')
console.log(err);
};
}
Jinja does not know that you want to pass a variable inside a JavaScript environment, so it cannot add the quotation marks automatically around a string variable. It just replaces {{ var }} with value1 causing a syntax error. Just add the quotation marks and then you can access myVar inside the JS environment:
<script>
myVar = "{{ var }}"
</script>
Note: if you want to pass a more complex data structure and/or user submitted values, you should look at the tojson filter that safely renders the data.

Inner HTML with Django tamplate if statement usig Js variable

I'm really new in JavaScript and I have a question:
I need to add inside an inner Html, a Django template if statement that uses a JavaScript variable to compare (in this case the variable is event_id)
I have tried a lot of alternatives after hours and also I have searched with no success.
This is my JS code.
eventClick: function (info) {
var event_id = info.event.id;
$('#exampleModalToggle').modal('show');
selected_group_member.innerHTML = `
{% for reservation in reservations_api %}
{% if reservation.id == ${event_id} %}
<option value="1" selected>{{reservation.id}}</option>
{% endif %}
{% endfor %}
`;
}
with this option, I'm getting this error:
Could not parse the remainder: '${event_id}' from '${event_id}'
and if I change it for {% if reservation.id == + event_id + %}, I'm getting this error: Could not parse the remainder: '' from ''
So, is that possible to do? Do you know how could it work please !!!
I really don't know how to solve it, I really appreciate your help
thanks :)
Something like this could work for you:
eventClick: function (info) {
const reservations = '{{ reservations_api | safe }}';
var event_id = info.event.id;
$('#exampleModalToggle').modal('show');
let innerHtml = '';
reservations.forEach((reservation) => {
if (reservation.id == event_id)
innerHtml += `<option value="1" selected>${reservation.id}</option>`;
});
selected_group_member.innerHTML = innerHtml
}
First of all you create a new javascript variable (called reservations), then you concatenate the desired <option> string into another variable (innerHtml). Finally you set the innerHtml to your selected_group_member.
Update
Added | safe template tag https://docs.djangoproject.com/en/3.2/ref/templates/builtins/#safe as discovered in comments.

Use a javascript array to display specific HTML divs

Using django I have a HTML page with a table containing checkboxes:
{% for o in obj %}
<input class='germ_ids' name='{{o.id}}'>
{% endfor %}
<script>
var elements = document.getElementsByClassName("germ_ids");
var ids = [];
for(var i=0; i<elements.length; i++) {
ids.push(elements[i].name);
}
</script>
This has given me an array of specific 'germ ids'. These relate to other django objects I have:
the same .html page:
{% for k, v in add_state_dict.items %}
<div class='{{k.id}}_statement'>
<p>{{v}}</p>
</div>
{% endfor %}
<div class='all_germ'>
<p>{{additional_statement}}</p>
</div>
What I want to achieve is a statement for each germ_id when their checkbox is checked. However when more than one boxes are checked, it makes a concat statement called additional_statement in the 'all_germ' class.
I have hard coded it in in a JSFiddle http://jsfiddle.net/sDsCM/1037/
However I want to use the elements in the array to do this to account for different array values.
You should not be using class names with IDs but instead use class names that categorize your checkboxes. As example I'll be using .checkbox-plus-info. Also, use a data attribute to find the associated statement (unless you can render them inside one div):
{% for o in obj %}
<input class='germ_ids checkbox-plus-info' name='{{o.id}}'
data-info-tag="info-{{o.id}}">
{% endfor %}
{% for k, v in add_state_dict.items %}
<div id='{{k.id}}_statement' class="info info-{{k.obj_id}}">
<p>{{v}}</p>
</div>
{% endfor %}
In the above, k of course needs to contain a reference to the object (its PK/ID). You should have that information in your view and add it to the context. You haven't posted your view/context code but the business logic should mostly be ready while you create the template context, so prepare as much as you can there.
In your JS:
$(".checkbox-plus-info").click(function() {
$(".info").hide(); // hide all
stmtElId = $(this).target.data("info-tag");
$("#" + stmtElId).show();
// check whether something has to be shown when several checkboxes are checked
// e.g. count whether all checkboxes are checked, or other logic
});

Load json data for the first time request and to display the same in Home Page

I am using Vue.js for the first time. I need to serialize the objects of django
views.py
def articles(request):
model = News.objects.all() # getting News objects list
modelSerialize = serializers.serialize('json', News.objects.all())
random_generator = random.randint(1,News.objects.count())
context = {'models':modelSerialize,
'title' : 'Articles' ,
'num_of_objects' : News.objects.count() ,
'random_order' : random.randint(1,random_generator) ,
'random_object' : News.objects.get(id = random_generator ) ,
'first4rec' : model[0:4],
'next4rec' : model[4:],
}
return render(request, 'articles.html',context)
I have tried to display serialized json data in html its working fine there,
Now , how to intialize json data in vue instance and to access in html using v-repeat attribute.
https://jsfiddle.net/kn9181/1yy84912/
Please can any one help???
A simple example.
views.py
def articles(request):
context {
'articles' : ['a1','a2','a3']
}
return render(request, 'articles.html', context)
articles.html
{% verbatim %}
<div id="app">
<ul>
<li v-for="a in articles">{{ a }}</li>
</ul>
</div>
{% endverbatim %}
<script>
new Vue({
el : "#app",
data : function(){
return {
articles : {{ articles | safe }}
}
}
})
</script>
Things to watch out for :
The verbatim tag to stop Django from rendering the contents of this block tag since Vue uses the same interpolating symbols.
The safe filter to prevent Django from escaping the contents.
If you are passing a dictionary, consider turning it into JSON first
Generally speaking, prefer passing data to Vue via Ajax

Django interpreter a Javascript loop as a tag / variable

I try to insert a javascript loop into a Django template in order to inject it within a block from another template.
I don't know if it's possible :
{% extends 'upload_form.html' %}
#template.html
{% block FILE_INPUT %}
{{ block.super|safe }} <script type="text/javascript">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-upload fade">
<!-- ... -->
<td class="title"><label>Title: <input name="title[]" required></label></td>
<!-- ... -->
</tr>
{% } %}</script>
{% endblock %}
It seems that django interpreter loop " JS " as a tag / variable :
TemplateSyntaxError at /index/
'for' statements should use the format 'for x in y': for (var i=0, file; file=o.files[i]; i++) {
Request Method: POST
Request URL: http://localhost:8002/index/
Django Version: 1.8.5
Exception Type: TemplateSyntaxError
Exception Value:
'for' statements should use the format 'for x in y': for (var i=0, file; file=o.files[i]; i++) {
Exception Location: /usr/local/lib/python2.7/dist-packages/django/template/defaulttags.py in do_for, line 863
Python Executable: /usr/bin/python
Python Version: 2.7.6
Python Path:
Someone would have an idea so that the script is only interpreted by the browser ?
Many Thanks.
This is not the correct syntax for django loop in template.
It should be like this :
{% for item in items %}
(what you want to display)
{% endfor %}
Note that the "items" is a variable you've sent from your view.
Then, try to use a correct syntax for you loop, see what it does and tell us.
{% verbatim %}
{{ js/agular }}
{% endverbatim %}

Categories