0

Happy new year to everybody ! I would like to get your help because I'm thinking how I can rewrite a little part from my code.

I have a django variable sets in my context and I pick up this variable in my HTML template (especially in my JavaScript part in my HTML template).

It works, but it's not a good idea because I would like to set all JS in one JS file and don't have piece of JavaScript in each HTML template.

In Django I have :

submethods = SubMethod.objects.all()
submethods_item = []
for item in submethods:
    submethods_item.append({'id': item.id, 'text': item.name})
context['submethods_item'] = submethods_item

In my HTML template, I have this piece of JavaScript :

function get_sub_method_options(keep_cur) {
  var sel_option = $('select#id_method-group').find("option:selected");
  var sel_val = sel_option.val();
  if (!sel_val) {
    $("select#id_method-sub_method").empty();
    let all_sub_methods = {{ submethods_item|safe }};
    for (var i = 0; i < all_sub_methods.length; i++) {
      $("select#id_method-sub_method").append('<option value="' + all_sub_methods[i].id + '">' + all_sub_methods[i].text + '</option>'); //here add list of all submethods
    }
    return;
  };
  ...
}

As you can see, I get the Django variable here :

let all_sub_methods = {{ submethods_item|safe }};

How I can make the same things, but with a method which let to write JS in my JavaScript file containing Django variable ?

If I write in my HTML template :

<script>
   let all_sub_methods = {{ submethods_item|safe }};
</script>

And I write my JS part inside an external file .js, it should work right ?

Thank you !

Essex
  • 6,042
  • 11
  • 67
  • 139
  • So you know how to do this, but instead of simply trying it, you decided to post a lengthy question here? Why? Also, there's another way: create an endpoint in Django that sends JSON and request it via AJAX / fetch(). –  Jan 03 '19 at 09:53
  • @ChrisG because by asking, it helps anyone else with a similar problem, and as you have demonstrated, there might be other solutions. – SpoonMeiser Jan 03 '19 at 09:58
  • @SpoonMeiser [But there's this already](https://stackoverflow.com/questions/23740548/how-to-pass-variables-and-data-from-php-to-javascript). I do know that dupes can be useful, but how many do we need? –  Jan 03 '19 at 10:01
  • 1
    I'm not sure why you have JS here at all. Why not just create the option list in the Django template? – Daniel Roseman Jan 03 '19 at 10:08
  • Possible duplicate of [Django Template Variables and Javascript](https://stackoverflow.com/questions/298772/django-template-variables-and-javascript) – Vaibhav Vishal Jan 03 '19 at 10:14

1 Answers1

3

Your approach might work, but only by accident.

Your context variable submethods_item is a Python list containing dictionaries. If you use that variable in a template with the safe filter, it gets rendered as a string that is valid JavaScript, but there are many ways this can go wrong.

The recommended approach is to serialize your variable to JSON, apply the escapejs in the template and then parse it in JavaScript.

# view
import json
...
context['submethods_item'] = json.dumps(submethods_item)

# template
<script>
   let all_sub_methods = JSON.parse("{{submethods_item|escapejs}}");
</script>
Daniel Hepper
  • 28,981
  • 10
  • 72
  • 75