'Access Django variable from JavaScript variable

First of all, I will like to say this is my first question here! (pardon me if this is redundant or duplicated)

I am having some problems with calling JS scripts from Django template:

{% for suggestion in suggestions %}
    <img class="catalogue-poster" src="{{ suggestion.poster }}" alt="Portada"  onclick="                 
        document.getElementById('{{form.title.auto_id}}').value = '{{suggestion.title}}'
        document.getElementById('{{form.year.auto_id}}').value = '{{suggestion.year}}'
        document.getElementById('{{form.director.auto_id}}').value = '{{suggestion.director}}'
        document.getElementById('{{form.rating.auto_id}}').value = '{{suggestion.rating}}'
        document.getElementById('{{form.poster.auto_id}}').value = '{{suggestion.poster}}'
        document.getElementById('{{form.trailer.auto_id}}').value = '{{suggestion.trailer}}'
        document.getElementById('{{form.synopsis.auto_id}}').value = '{{suggestion.synopsis}}'
        document.getElementById('{{form.cast.auto_id}}').value = '{{suggestion.cast}}'  
    " />
{% endfor %}

So, first of all, how can I declare a function outside. I'm a C developer, sorry for my ignorance.

I've tried to create a script outside, such as

<script>
    function foo() {
      console.log('Hey');
    });
</script>

And invoke it this way:

<img class="catalogue-poster" src="{{ suggestion.poster }}" alt="Portada"  onclick="foo()"/>  

But this simple thing that works on pure HTML, with django templates does not seem to work...

On the other hand, the real question was, is there a way to access a Django variable passed in render with a js variable?

Such as:

const jsVariable = 'title';
document.getElementById('{{form.jsVariable.auto_id}}').value = '{{suggestion.jsVariable}}'

I have not found any way to accomplish this, maybe there is another great idea!



Solution 1:[1]

I have tried one example. where is send a variable from python script and access its value in JavaScript

1) In views.py

from django.shortcuts import render

def home_view(request):
    var_name = 'hello'
    return render(request, 'home.html', {'var_name':var_name})

2) In html file(home.html)

<html>
    <h1>Home Page</h1>
    <input type="button" value="Submit" onclick="fun()">

    <script>
        function fun(){
            console.log('hello world '+ '{{var_name}}' );
        }
        var temp = '{{var_name}}';
        console.log(temp + 20);
    </script>
</html>

If i click submit button ( hello world hello ) is printed in console.

I stored value of var_name in temp which can be further used.

Solution 2:[2]

From your example, it looks you want to programmatically access a Django model's attribute in Javascript.

The main takeaway is that you first need to expose the data structure you want to access (i.e. the model) in Javascript.

Here's a simple, redacted, proof-of-concept you can try.

import json

def my_view(request):
    obj = MyModel.objects.get(1)
    obj_dict = {
        "foo": obj.foo,
        "bar": obj.bar,
    }
    return render(request, 'my_view.html', context={'obj_json': json.dumps(obj_dict)} )

<script>
var obj = {{obj_json}};

var field = 'foo';
console.log(obj[field]);

Check out Convert Django Model object to dict with all of the fields intact for a run-down on options to serialize Django models into dictionaries.

Solution 3:[3]

Well, finally I found a solution for both exposed problems.

  1. First of all, the script function I declared was not working because it seems that there is an attribute called autocomplete (see autocomplete HTML attribute) So, you can not declare a JavaScript function with this name, my fail. Uncaught TypeError: autocomplete is not a function

  2. Finally, the simple solution I found was passing an array of dicts to the template:

return render(request, 'example.html', {'form': form, 'suggestions': suggestions })

And then in the template:

{% for suggestion in suggestions %}
    <img src="{{ suggestion.poster }}" onclick="autocompleteMovie({{suggestion}});" />
{% endfor %} 

<script>
    function autocompleteMovie(suggestion){
        for (let field in suggestion)
            document.getElementById('id_' + field).value = suggestion[field] 
    }
</script

Which, comparing it with the question, really simplifies the problem.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 SahilDesai
Solution 2 Sebastian
Solution 3 asm4ever