Skip to content
This repository has been archived by the owner on Dec 26, 2023. It is now read-only.

Generate HTML from JS before sending it over the wire #77

Open
RobSisson opened this issue Dec 1, 2022 · 0 comments
Open

Generate HTML from JS before sending it over the wire #77

RobSisson opened this issue Dec 1, 2022 · 0 comments

Comments

@RobSisson
Copy link

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>
` As can be seen, the stream is functioning as expected for the django information, however otherwise the html otherwise just copied across, without populating the related div.

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>
` with nothing in the console.

I've tried several different things with none of them working, but may have made mistakes when attempting them:

  1. 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.
  2. Editing turbo to use render() rather than render_to_string() in order to include the content_type variable in the template, and then trying to render a JS file with the appropriate mime type.
  3. 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).
  4. 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.
  5. I've tried using the turbo.TurboRender.response() as described here
  6. 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!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant