1

Let's say we have in a template a table like

{% for object in object_list %}
   <tr>
      <td id="id-{{object.id}}">{{ object.id }}</td>
   </tr>
{% endfor %}

I'm thinking of using object.id for events, like onclick, to know exactly which object.id was used.

How do you use json_script to get the object.id in a JavaScript script?

Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145
  • You want just the IDs? Why use `json_script` then? You could simply give a specific class to your elements (to select them by) and specify the value in a data attribute. Or do you want a list of the IDs? – Abdul Aziz Barkat Oct 21 '22 at 13:26
  • As I said have you thought of using [data attributes](https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes)? – Abdul Aziz Barkat Oct 21 '22 at 13:47
  • 2
    `json_script` will end up giving you things like `` and so on and so forth, for (repeated) single attribute data like yours it is unwieldy / overkill, an attribute on your element is much more suitable for your case. Go for `json_script` in case you have a proper collection (list / dictionary, etc.) that you want to pass to JavaScript. – Abdul Aziz Barkat Oct 21 '22 at 13:56

1 Answers1

2

In the case of the question we have a table and we want to have a button to copy the object.id to use in JavaScript.

There are various ways to do that and json_script is not one of them.

As noted by Abdul Aziz Barkat

json_script will end up giving you things like <script id="id-you-passed" type="application/json">1</script> and so on and so forth, for (repeated) single attribute data like yours it is unwieldy / overkill, an attribute on your element is much more suitable for your case. Go for json_script in case you have a proper collection (list / dictionary, etc.) that you want to pass to JavaScript.

Instead, we could do something like this in the button

  • onclick="copyId('{{object.id}}')"
  • id="js-copy-id-btn-{{object.id}}"
<table>
  <thead>
    <tr>
      <th>ID</th>
      <th></th>
    </tr>
  </thead>
  <tbody>
      {% for object in object_list %}
      <tr>
          <td>{{object.id}}</td>
          <td><button id="js-copy-id-btn-{{object.id}}" onclick="copyId('{{object.id}}')">Copy ID</button></td>
      </tr>
      {% endfor %}
  </tbody>
</table>

Then the JavaScript could look like

<script>
  function copyId(id) {
    // ...
}
</script>

Another solution for passing data to JavaScript in a Django Template is using the data attributes, as suggested by Adam Johnson

{% for object in object_list %}
   <tr>
      <td data-obj-id={{object.id}} class="obj">{{ object.id }}</td>
   </tr>
{% endfor %}


<script>
    const objs = document.querySelectorAll(".obj")
    objs.forEach(obj => {
        let id = obj.dataset.objId
        obj.addEventListener('click', function(event) {
          // Whatever you have to do with the id on click
        })
    })
</script>
Abdul Aziz Barkat
  • 19,475
  • 3
  • 20
  • 33
theeomm
  • 828
  • 7
  • 8
  • Hi theeomm thanks for taking the time to answer! I'd still want with `json_script` though. You can show then why the current method you're using is better – Tiago Martins Peres Oct 21 '22 at 18:42
  • 1
    I read an article concerning this the other day. For your use case, it seems the use of dataset is the easier and cleaner solution for what you want to accomplish. By the way, I'm not an expert in this error to determine why one method is better than the other. Article link -> https://adamj.eu/tech/2022/10/06/how-to-safely-pass-data-to-javascript-in-a-django-template/ – theeomm Oct 21 '22 at 19:52
  • I'm referencing this answer [here](https://stackoverflow.com/a/74164921/5675325) as well because observed that some devs can be lead to think that `json_script` is to be used all of the time when we want to pass data from Django templates to JavaScript. – Tiago Martins Peres Oct 22 '22 at 16:07