I have a chart that is populated by django template variables. I have an update chart function that updates the data after certain buttons are clicked. Instead of writing the same js function 7x, can I update the javascript function to call the correct data within a Django template variable?
Basically, the btn_id will either be A, B, C, D, E, or F and I want the django template variable to display the correct data based on the btn_id value.
var results = {{ all_test_results.A.curve_series.curve_series }}.map(function(val, i) {
return val === 'None' ? null : val;
});
becomes
const btn_id = this.id.slice(-1); # A, B, C, D, etc
var results = {{ all_test_results.{{ btn_id }}.curve_series.curve_series }}.map(function(val, i) {
return val === 'None' ? null : val;
});
I am sure there is a simple way to inject a js string into a Django template variable, right?
CodePudding user response:
Simple, no
I am sure there is a simple way to inject a js string into a Django template variable, right?
Here's the problem. {{ all_test_results.A.curve_series.curve_series }}
is handled by the server, which is handled by Django, which takes this tag, and fills it in with the data and returns an HTML document back to the client. Now it is the client, that is the end user, who clicks on say a button C, but how does Django, who lives on the server know about this? It doesn't, and that's why this is not so simple.
Solution
When the user clicks C, you can have a simple AJAX request sent from the client to the server, with this information. The server can then send back the value of all_test_results.C.curve_series.curve_series
(you will have to write a query for this, you wouldn't be able to use a variable in place of C here), which can be received by your JavaScript, so that you don't have to do this 7 times.
Details
# views.py
from django.http import JsonResponse
def get_result(request, letter):
return JsonResponse({'answer': [result of your query that uses the variable, "letter", which corresponds to the letter the user clicked, here]})
Add a path to this view
# urls.py
urlpatterns = [
...
path('get_result/<str:letter>', views.get_result, name='get_result')
]
In your template you have your buttons with values that can be targeted by JavaScript, and the container that will show the result:
<button type="button" value="A" id="A">A</button>
<button type="button" value="B" id="B">B</button>
<button type="button" value="C" id="C">C</button>
<button type="button" value="D" id="D">D</button>
<button type="button" value="E" id="E">E</button>
<button type="button" value="F" id="F">F</button>
<div id="result">Result will appear here</div>
And finally the JavaScript, which will make the AJAX request, get the response from the server, and finally update the HTML with the result:
async function get_result(e) {
// Make the AJAX request to the server:
const response = await fetch('/get_result/' e.target.value);
// Once the response is received, turn it into json format:
const result = await response.json();
// Update the div you want to carry the result:
// NOTE: you should not use innerHTML here.
document.getElementById('result').innerHTML = result.answer;
}
// Get all the buttons of class result_btns from the HTML
let btns = document.querySelectorAll("button");
// For each button, create an event listener, that will
// send to the function get_result, it's value
btns.forEach((btn) => {
btn.addEventListener('click', get_result);
});
CodePudding user response:
Whats wrong with this as per the docs?
https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#json-script
You can then use or modify the resulting js object as you please.