1

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!

General Grievance
  • 4,555
  • 31
  • 31
  • 45
asm4ever
  • 27
  • 1
  • 7

3 Answers3

4

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.

SahilDesai
  • 512
  • 3
  • 6
  • Thank you @SahilDesai, I've already achieved this. What I was asking for was to access a django variable with a JavaScript variable. Something like, const a = 'var_name' console.log({{a}}) So, variable 'a' will be replaced with 'var_name' !!! I believe this is not possible, this is why I was asking – asm4ever May 25 '20 at 15:30
  • No it is not possible as Jinja template will only give response to variables which are sent throught context object from view function. Jinja template would not know about the variable created by javascript – SahilDesai May 25 '20 at 15:44
0

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.

Sebastian
  • 2,678
  • 25
  • 24
  • A side note is that you probably "shouldn't be doing this": it sounds like you would benefit from using something like Django Rest Framework to provide an API to your models and integrate the javascript to that. But this is all beside the point to your specific question. – Sebastian May 25 '20 at 16:49
  • Alright, thank you @Sebastian, thats a good point. Of course, I should not be doing this but this is a nice trick to pass json variables to django templates! – asm4ever May 28 '20 at 15:21
  • By the way, I know Django Rest Framework, but this was for a collage project and we have to fit with pure django! – asm4ever May 28 '20 at 15:27
0

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.

asm4ever
  • 27
  • 1
  • 7