Black Lives Matter. Please consider donating to Black Girls Code today.

Adding Javascript to my app

Hi fellow Dash users,

Apologies in advance if this is too simple of a question as I’m a beginner in Dash.

I’m trying to add a javascript from an online widget onto my Dash app. The widget provider is a FX broker and has kindly provided the code to embed as below (I had to delete some “<” notations to allow the code to show as block quotes)

script type=“text/javascript”>DukascopyApplet = {“type”:“economic_calendar_new”,“params”:{“showHeader”:false,“tableBorderColor”:"#D92626",“defaultTimezone”:0,“defaultCountries”:“c:AU,CA,CH,CN,EU,GB,JP,NZ,US,DE,FR,IT,ES”,“impacts”:[1,2],“dateTab”:2,“dateFrom”:1459036800000,“dateTo”:1459555200000,“showColCountry”:true,“showColCurrency”:true,“showColImpact”:true,“showColPrevious”:true,“showColForecast”:true,“width”:“100%”,“height”:“500”,“adv”:“popup”}};/script>script type=“text/javascript” src=“https://freeserv-static.dukascopy.com/2.0/core.js”>/script>

I’ve read through the documentation for Dash and I’ve written the below code, in attempt to conform to the format listed in the documentation

external_scripts =[
{
‘src’: ‘https://freeserv-static.dukascopy.com/2.0/core.js’,
‘type’:“economic_calendar_new”,
‘params’:{“showHeader”:False,“tableBorderColor”:"#D92626",“defaultTimezone”:0,“defaultCountries”:“c:AU,CA,CH,CN,EU,GB,JP,NZ,US,DE,FR,IT,ES”,“impacts”:[1,2],“dateTab”:2,“dateFrom”:1459036800000,“dateTo”:1459555200000,“showColCountry”:True,“showColCurrency”:True,“showColImpact”:True,“showColPrevious”:True,“showColForecast”:True,“width”:“100%”,“height”:“500”,“adv”:“popup”}
}]

I’m wondering if firstly what I wrote is correct, and also how to then add the widget to my app via the “add.layout” code block.

Many thanks

Felton

1 Like

The non-dash way to include this widget is to add two <script> tags: one with no src, just inline code, where you create a config object; and a second whose src is the widget code. If that’s all you need, I’d suggest a custom index string - see https://dash.plot.ly/external-resources, “Customizing Dash’s HTML Index Template” option 1, and add both of these to the <head> tag.

But what’s not clear to me from your post is how that widget is supposed to know where in the page to render, and when? If you just want this widget above or below the dash components, you could presumably add a container for that to the custom index as well. But if what you’re going for is putting it somewhere mixed in among other dash components, the containers for these aren’t going to exist until well after the above scripts have executed - and due to callbacks these containers can be deleted and recreated arbitrarily - so something will need to tell the widget when and where to run as the page changes; that’s normally what dash components themselves are for, so if you want to do this, the right way is to make a custom component https://dash.plot.ly/plugins

Hi Alex, thanks very much for your reply. Just to confirm my understanding of what you said, assuming my app currently displays in the format of a 2 by 2 grid, where each grid has some component (charts, table etc), and I want the widget to appear in one of those grids. The only way for me to do that is by writing my own DCC?

Thanks

Felton

I wouldn’t say it’s the only way, but it’s definitely the preferred way.

I mean, assuming there’s a function like Dukascopy.Render(DOMElement) you could always pick a special ID like my-dukas and create your own script like:

var dukasInterval = setInterval(function() {
    var dukasEl = document.getElementById('my-dukas');
    if (!dukasEl) { return; }
    # do something to check if the chart has already rendered here
    var dukasClass = 'some-class-added-by-dukas-script';
    if (dukasEl.className && dukasEl.className.split(' ').indexOf(dukasClass) !== -1) { return; }

    # now we know this is a new element to be rendered into
    Dukascopy.Render(dukasEl);
}, 1000);

Then have your app.layout include html.Div(id='my-dukas') and once a second the above script would check if that element exists and needs a widget rendered into it. That would cover a lot of cases, but with a little bit of a funny UX (waiting a second with nothing rendered), no ability to edit the widget after creating it, and probably some funny cases where it would break, I don’t know.

Whereas making a custom component for this is a fully robust and extensible solution. It’s a little more work but would serve you much better in the long run.

Thanks Alex. Sounds like a lot more involved than I thought and above my coding knowledge to be honest. Appreciate the thought nonetheless.