Passing parameters / attributes to javascript in a template

101 views
Skip to first unread message

Déborah Leder

unread,
Aug 4, 2015, 9:14:29 AM8/4/15
to Django users
Hello

I am currently developping a django geolocalisation application. Therefore, I need both python and javascript.
I would like to give some parameters to a script in a template, that is to say, in my template, I want to use the script tag to define/modify some javascript variables.
Here is my code (that doesn't work) :
<script type="text/javascript" src="{% static "js/geomap_var.js" %}"></script>
{% for current_addr in mymodel.addresses.all %}
   
<script type="text/javascript">
    my_markers
.push(
       
{
            lat
: {{current_addr.lat}},
            lon
: {{current_addr.lon}},
            description
: {{current_addr.description | safe }}
       
}
       
);
   
</script>
{% endfor %}
<script type="text/javascript" src="{% static "js/geomap_body.js" %}"></script>


When I define the array of objects my_markers in my script by giving only "hard-coded" numbers and strings, it works fine, so I guess that the problem is to recognize and evaluate the lat, lon, and description attributes of my address class.

And I also don't know how to display the value of a javascript array in a template, so it makes it quite hard for debugging.

If it helps, mymodel is a model that has a field : addresses = ManyToManyField(address)


Larry Martell

unread,
Aug 4, 2015, 9:20:50 AM8/4/15
to django...@googlegroups.com
I do things like that all the time, so you must have some other issue.
I'd run the python script in the debugger and verify that values are
indeed getting passed in your context.

Déborah Leder

unread,
Aug 4, 2015, 9:39:50 AM8/4/15
to Django users
Hello Larry, thank you for your response.

I didn't run the debugger, but i know that my values are correctly passed in the template (when it it outside of the script tags), because at the end of my template, I have also written the code :
<div>

{% for
current_addr in mymodel.addresses.all
%}
    {{
current_addr.description | safe}}
    Latitude : {{
current_addr.lat }},
   
<br>
    Longitude : {{
current_addr.lon }},
   
<br>
{% endfor %}
</div>


And all the values are correctly displayed.

If you think that I can check something else with the debbuger, I don't know what you mean so it would help me if you were more precise

Vijay Khemlani

unread,
Aug 4, 2015, 11:45:51 AM8/4/15
to django...@googlegroups.com
Have you checked the HTML that is actually rendered by the Django template?

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/23f8bdd5-86b6-40d3-9cb6-964a8d808a6c%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Déborah Leder

unread,
Aug 4, 2015, 11:53:42 AM8/4/15
to Django users
After some more tests, I have managed to understand where my problem is (but I don't know how to resolve it).
Here is my final piece of code :
<script type="text/javascript" src="{% static "js/geomap_var.js" %}"></script>

<script type="text/javascript">
    my_markers
= [
   
{{ mymodel.set_first_call_true }}

   
{% for current_addr in mymodel.addresses.all %}

       
{% if not mymodel.first_call %},{% endif %}

       
{
            lat
: {{ current_addr.lat }},
            lon
: {{ current_addr.lon }},
            description
: {{ current_addr.description | safe }}
       
}

   
{{ mymodel.set_first_call_false }}
   
{% endfor %}
   
];
</script>

   
<script type="text/javascript" src="{% static "js/geomap_body.js" %}"></script>


I had to add an attribute "first_call" to mymodel, so that my javascript declaration was correct (in an array, we should always write the comma between 2 elements, but not after each element or before each element).
The only problem is that every time I call mymodel.set_first_call_true or mymodel.set_first_call_false, it inserts a "none" inside my javascript code.
Is it possible to "delete" the "non" statement ?


Alex Heyden

unread,
Aug 4, 2015, 12:32:11 PM8/4/15
to django...@googlegroups.com
I don't quite follow what you're doing with set_first_call_true and set_first_call_false. Are you using that to control the for loop behavior?

If you are, take a look at https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#for. Django's template language has that built in.

If you're pushing to an array like in your initial example, you don't need to handle commas at all. Here's an example out of Chrome's dev tools:

> var a = []
> a.push('foo')
> a.push('bar')
> a
< ["foo", "bar"]

If you want to define it in one go, try something more like:

<script type="text/javascript">
    my_markers = [
    {% for current_addr in mymodel.addresses.all %}
        {
            lat: {{ current_addr.lat }},
            lon: {{ current_addr.lon }},
            description: {{ current_addr.description | safe }}
        }{% if not forloop.last %}, {% endif %}
    {% endfor %}
    ];
</script>

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.

Daniel Roseman

unread,
Aug 4, 2015, 2:06:04 PM8/4/15
to Django users
On Tuesday, 4 August 2015 17:32:11 UTC+1, Alex Heyden wrote:
I don't quite follow what you're doing with set_first_call_true and set_first_call_false. Are you using that to control the for loop behavior?

If you are, take a look at https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#for. Django's template language has that built in.

If you're pushing to an array like in your initial example, you don't need to handle commas at all. Here's an example out of Chrome's dev tools:

> var a = []
> a.push('foo')
> a.push('bar')
> a
< ["foo", "bar"]

If you want to define it in one go, try something more like:

<script type="text/javascript">
    my_markers = [
    {% for current_addr in mymodel.addresses.all %}
        {
            lat: {{ current_addr.lat }},
            lon: {{ current_addr.lon }},
            description: {{ current_addr.description | safe }}
        }{% if not forloop.last %}, {% endif %}
    {% endfor %}
    ];
</script>


An even better solution is to keep this logic where it belongs, in the view, and use the accepted format for interchange of data with Javascript, which is JSON.

    my_markers = [{'lat': addr.lat, 'lon': addr.lon, 'description': addr.description} for addr in mymodel.addresses.all]
    return render(request, 'template.html', {'my_markers': json.dumps(my_markers)})

and refer to it directly in the template:

    <script type="text/javascript">
         my_markers = {{ my_markers|safe }}
    </script>

-- 
DR.

Déborah Leder

unread,
Aug 5, 2015, 5:47:08 AM8/5/15
to Django users
Thank you for your answers, everyone.
Alex, indeed I didn't know about the forloop last trick. It worked like a charm !
And Daniel, for some reasons I prefer not to mess with the views for now, but when if I need to clean up my code, I keep your answer in mind.
Reply all
Reply to author
Forward
0 new messages