2

I would like to get some help to pass Django variable in HTML template into Javascript variable.

I believed it would be easy, but up to now, I don't overcome to do that. Especially with a Django for loop.

I have an HTML piece of code like this :

{% for document in publication.documents.all %}
    <table class="table table-condensed">
        <tbody>
            <tr>
                <td class="col-md-1">
                    <canvas id="test{{ document.id }}"></canvas>
                </td>
            </tr>
        </tbody>
    </table>
{% endfor %}

Then, I would like to use Javascript code to display the PDF for each document.

So, I have something like this with JS :

<script src="https://mozilla.github.io/pdf.js/build/pdf.js"></script>

<script type="text/javascript">

  var document_upload = "{{ document.upload }}"; //Django variable
  pdfjsLib.getDocument('http://localhost:8000/media/'+document_upload).then(function (pdf) {
    console.log("pdf loaded");
    pdf.getPage(1).then(function (page) {
        var scale = 0.30;
        var viewport = page.getViewport(scale);

        var canvases = document.getElementsByTagName('canvas');
        Array.from(canvases).forEach((canvas) => {
            var context = canvas.getContext('2d');
            canvas.height = viewport.height;
            canvas.width = viewport.width;

            var renderContext = {
                canvasContext: context,
                viewport: viewport
            };
            page.render(renderContext);
        });
    });
  });

</script>

But nothing appears in my template.

If I make a console.log() for these :

var document_upload = "{{ document.upload }}"; //returns blank
var document_upload = {{ document.upload }}    //returns Undefined

Maybe someone could help me? I don't know but I think I need to add a loop in my JS too according to this Django loop {% for document in publication.documents.all %} ?

11
  • stackoverflow.com/questions/8683922/… Commented Sep 26, 2018 at 9:01
  • 2
    But document is only in scope inside the loop, and your JS - even if it is in the same file - is not inside that loop. Commented Sep 26, 2018 at 9:05
  • 1
    Why can't you just put it there? JS can go anywhere in your HTML file. Commented Sep 26, 2018 at 9:09
  • 1
    Hum, I don't know because I believed that JS was executed only at the end, even if the JS script is placed at the beginning or at the end of HTML file. Commented Sep 26, 2018 at 9:11
  • 1
    probably you are overlapping all these documents. parse them one by one, by providing different viewport. Commented Sep 26, 2018 at 9:32

3 Answers 3

0
<script>
   const document_upload = {{document | safe}}
   console.log(document.upload)
</script>

Check if there is some data

It should print data if you have or it will give you an empty array

Sign up to request clarification or add additional context in comments.

2 Comments

I'm not sure that your code will work, because as said @DanielRoseman, I have to set my JS script inside the Django loop. If I print data from your code, the array will be always empty I assume.
i think you mean console.log(document_upload)
0

Put your django variable inside html as data-element. Then run a loop to render pdf. Your variable is available inside your {% for %} loop only, so either you put your js inside the loop(don't do it) or do this.
Scripts I have added use jQuery, so don't forget to add it.

{% for document in publication.documents.all %}
<table class="table table-condensed">
    <tbody>
        <tr>
            <td class="col-md-1">
                <canvas class="my-canvas" data-upload="{{ document.upload }}" id="test{{ document.id }}"></canvas>
            </td>
        </tr>
    </tbody>
</table>

Script, preferably just before < /body>

<script src="https://mozilla.github.io/pdf.js/build/pdf.js"></script>
// add jQuery
<script type="text/javascript">
    $(document).ready(function(){
        $('.my-canvas').each(function(){
            var document_upload = $(this).data('upload'); // Django variable saved as data attribute
            console.log(document_upload);
            /* Do rest of your pdf.js stuff here */\
            pdfjsLib.getDocument('http://localhost:8000/media/' + document_upload).then(function (pdf) {
                console.log("pdf loaded");
                pdf.getPage(1).then(function (page) {
                    var scale = 0.30;
                    var viewport = page.getViewport(scale);

                    var canvases = document.getElementsByTagName('canvas');
                    Array.from(canvases).forEach((canvas) => {
                        var context = canvas.getContext('2d');
                        canvas.height = viewport.height;
                        canvas.width = viewport.width;

                        var renderContext = {
                            canvasContext: context,
                            viewport: viewport
                        };
                        page.render(renderContext);
                    });
                });
            });
        });
    });
</script>

Comments

0

Thanks to Daniel Roseman, I found the answer and I overcome to display PDF cover page for each document.

This is my HTML file containing JS script :

{% for document in publication.documents.all %}
    <table class="table table-condensed">
        <tbody>
            <tr>
                <td class="col-md-1">
                    {% if document.format == 'pdf' %}

                            <script src="https://mozilla.github.io/pdf.js/build/pdf.js"></script>

                            <script type="text/javascript">
                            var document_upload = "{{ document.upload }}";
                            pdfjsLib.getDocument('http://localhost:8000/media/'+document_upload).then(function (pdf) {
                              pdf.getPage(1).then(function (page) {
                                  var scale = 0.30;
                                  var viewport = page.getViewport(scale);

                                  var canvas = document.getElementById('test{{ document.id }}');
                                  var context = canvas.getContext('2d');
                                  canvas.height = viewport.height;
                                  canvas.width = viewport.width;

                                  var renderContext = {
                                      canvasContext: context,
                                      viewport: viewport
                                  };
                                  page.render(renderContext);
                              });
                            });
                            </script>
                            <canvas id="test{{ document.id }}" style="border:1px solid #000000;"></canvas>
                          {% else %}
                            <span class="glyphicon glyphicon-blackboard"></span>
                          {% endif %}
                </td>
            </tr>
        </tbody>
    </table>
{% endfor %}

It takes just 3-4s to load all PDF (maybe there is another way to do that faster), but it works !

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.