-
Notifications
You must be signed in to change notification settings - Fork 21
Generate HTML from JS before sending it over the wire #77
Description
Hi Everyone,
Is it possible to run javascript to create html before sending it through a stream?
or if this isn't,
Is it possible to run javascript which arrives into the client via a stream?
Currently it seems that any JS which is sent over via a stream just comes through as the plain text, without being ran before sending (example 1) or after arrival (example 2).
Example 1 - Not running JS before
message.html
`
{% for message in room.messages.all %}
{id: {{message.id}}, content: '{{message.text}}', start: '{{message.created_at.date}}'},
{% endfor %}
<div id="visualization"></div>
<script type="text/javascript">
(function (room, vis_id) {
// DOM element where the Timeline will be attached
var container = document.getElementById(vis_id);
// Create a DataSet (allows two way data-binding)
var items = new vis.DataSet([
{% for message in room.messages.all %}
{id: {{message.id}}, content: '{{message.text}}', start: '{{message.created_at.date}}'},
{% endfor %}
]);
// Configuration for the Timeline
var options = {};
// Create a Timeline
var timeline = new vis.Timeline(container, items, options)
})();
</script>
Comes out in the browser as
`
{id: 85, content: 'Test Message', start: 'Dec. 1, 2022'},
{id: 86, content: 'asd', start: 'Dec. 1, 2022'},
<div id="visualization"></div>
<script type="text/javascript">
(function (room) {
// DOM element where the Timeline will be attached
var container = document.getElementById(visualization);
// Create a DataSet (allows two way data-binding)
var items = new vis.DataSet([
{id: 85, content: 'Test Message', start: 'Dec. 1, 2022'},
{id: 86, content: 'asd', start: 'Dec. 1, 2022'},
]);
// Configuration for the Timeline
var options = {};
// Create a Timeline
var timeline = new vis.Timeline(container, items, options)
})();
</script>
The exact same code is used to load the visualisation on the initial page load, and works correctly.
Example 2 - Not running JS after
template.html
`
{% for message in room.messages.all %}
{id: {{message.id}}, content: '{{message.text}}', start: '{{message.created_at.date}}'},
{% endfor %}
<script type="text/javascript">
console.log('Test');
</script>
Comes out in the browser as
`
{id: 85, content: 'Test Message', start: 'Dec. 1, 2022'},
{id: 86, content: 'asd', start: 'Dec. 1, 2022'},
<div id="visualization"></div>
<script type="text/javascript">
console.log('Test');
</script>
I've tried several different things with none of them working, but may have made mistakes when attempting them:
- Putting the Javascript in different places, for example in a django variable which can then be called - I imagine this didn't work due to potential security issues of being able to run potentially unwanted JS.
- Editing turbo to use
render()
rather thanrender_to_string()
in order to include thecontent_type
variable in the template, and then trying to render a JS file with the appropriate mime type. - Loading the page with selenium, copying the resulting html into a file, then loading that as a template (not a scalable option, but was simply testing it).
- Running javascript in python using js2py, which doesnt work as the construction of the visualisation requires the use of
document.getElementById
, which I haven't been able to figure out how to connect it to a DOM. - I've tried using the
turbo.TurboRender.response()
as described here - I've tried using the
FrameElement.reload()
function - though didn't seem to have any luck getting it working at all, so my use may be off
Breaking it down, I think it would be possible to do if I was able to import the existing DOM, or a constructed one with something like dominate, into a javascript instance or reload the frame using the javascript
Any advice or pointers would be greatly appreciated!