0

I am currently working on a django template wherein I want to use a javascript variable in the if condition. My code is as follows

{% extends 'base.html' %}
{% block content %}

    <br>
    <div class="buttonRow">
        {% for t in tickerList %}
            <button class="btn btn-dark" onclick="changeChart(this.value)" value="{{ t }}">{{ t }}</button>
        {% endfor %}

    </div>
    <br><br>
    {% if {{ currentTicker }} %}
        {{ currentTicker |safe }}
    {% else %}
        <p>NO Graph</p>
    {% endif %}
{% endblock %}

<style>
    .buttonRow {
        width: 100%;
        float: left;
        border: solid 1px blue;
        text-align: center;
    }

    button {
        background: black;
        color: white;
    }
</style>

<script>


    var currentTicker = {{ tickerList.0 }}
        function changeChart(ticker) {
            currentTicker = ticker;
        }
</script>

Here the dictionary I send from the server-side may look like this

{
  "tickerList" : ["GOOGL","TSLA"],
  "GOOGL" : (plotly object),
  "TSLA" : (plotly object)

}

Depending on the button clicked by the user I want to change the graph (plotly object) on the screen. As you can see I have made the necessary buttons and I change currentTicker variable but I am not sure how I can change the graph in real-time on the screen when the user clicks the button. Could anyone help with this?

CS1999
  • 303
  • 2
  • 10

1 Answers1

0

Django and JavaScript are evaluated in different runtimes: Your Django template is evaluated server-side once the request arrives, whereas your JavaScript code is evaluated client-side after it has been received by the browser. Therefore, the JavaScript variables cannot be read by your Django template engine.

From my understanding, you would like to update the information on the currently selected ticker in your HTML DOM. To achieve this, there are two possible solutions:

  1. You can send the selected ticker to your server as a query parameter:

    {% for t in tickerList %}
        <a class="btn btn-dark" href="?currentTicker={{ t }}">{{ t }}</a>
    {% endfor %}
    

    and read it there:

    request.GET.get("currentTicker")
    
  2. Or you can change it client-side only. For this, change the lines

    {% if {{ currentTicker }} %}
        {{ currentTicker |safe }}
    {% else %}
        <p>NO Graph</p>
    {% endif %}
    

    to

    <p id="currentTicker">NO Graph</p>
    

    and add this in your JavaScript code:

    function changeChart(ticker) {
        document.getElementById("currentTicker").innerText = ticker || 'NO Graph';
    }
    

With the first approach, you can do your business on Python only, re-rendering the page with each ticker selection change. This is useful for any computing-intensive calculations etc.

The second approach provides instant feedback for the user while for larger calculations increases the load on the client-side.

In the end for your use case, your decision might depend on your personal preference which language you are more comfortable with.

Janik
  • 688
  • 1
  • 6
  • 12
  • I am sorry but this does not seem to work. Also ```currentTicker``` is a javascript variable and does not exist in python dictionary which comes from server side – CS1999 Apr 01 '22 at 10:43
  • If there is no `currentTicker` in Django, just remove it and keep the default only (answer updated accordingly). Oh, and there was an error in the JavaScript part, maybe try again with the fixed snippet above? – Janik Apr 01 '22 at 10:47
  • I am sorry but I dont just want to change the ticker name but I want to display the plotly object associated with that ticker from the dictionary – CS1999 Apr 01 '22 at 11:13
  • Then you should go with the first approach, and once you read the `currentTicker` from the params, you can access the plotly object from your dict (`yourDict[currentTicker]`) and pass it to the template. [Have a look here](https://stackoverflow.com/q/36846395/9969672) on how to embed a plotly object into the html. I'm sorry, I've read over the last paragraph. – Janik Apr 01 '22 at 11:28