How to add javascript snippet into my app?

refer to the answer from Nandita Arora Sharma in this stackoverflow link, how can we insert the snippet below into dash app?

<script>
  $(".summary").on("click", function() {
    $(this).next().toggleClass("show");
  })
</script>

i try this way but it is not working:

  html.Script('''
    $(".summary").on("click", function() {
      $(this).next().toggleClass("show");
    })''')

i tested both html.Script and app.scripts.append_script but none of them work

app.layout = html.Div([
  html.Hr(),
  
  html.Div([
    dcc.Dropdown(
      id='select-par',
      options=[{'label': par, 'value': par} for par in df_fmaxl_int.partition],
      placeholder='select partition...'
    )
  ], className='row'),
  
  html.Hr(),

  html.Div([create_card('partition', corner) for corner in corners[0:2]]),


  # html.Script(type='text/javascript', children='''$(".summary").on("click", function() {$(this).next().toggleClass("show")})'''),

], className='row ten columns offset-by-one')

app.scripts.append_script({"external_url": "https://codepen.io/zh1611/pen/RJxeGg.js"})

Hey @zhsee

Have you had a look at the docs https://dash.plot.ly/external-resources or one of Plotly’s examples on github https://github.com/plotly/dash-vanguard-report/blob/master/app.py#L1317-L1321

yes, i tried both app.scripts.append_script({“external_url”: “https://codepen.io/zh1611/pen/RJxeGg.js”}) and html.Script(src=’“https://codepen.io/zh1611/pen/RJxeGg.js”), both are not working.

in my case the sequence of the js is important. i tried this

html.Script(src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js')
html.Script(src='https://codepen.io/zh1611/pen/RJxeGg.js')

and this

app.scripts.append_script({"external_url": 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'})
app.scripts.append_script({"external_url": 'https://codepen.io/zh1611/pen/RJxeGg.js'})

none of them work as expected.

you may use this snippet to test the impact of different sequence in sourcing the js files

.summary {
color: #1D2951; text-decoration: none;
font-size: 2.2rem; line-height: 1.5;
letter-spacing: -.05rem; margin-bottom: 0.6rem;
margin-top: 0.6rem; cursor: pointer;}

  .summary:hover {
    color: #0038A8; text-decoration: none;
    cursor: pointer;}

  .summary:focus {
    color: #1D2951; text-decoration: none;
    cursor: pointer;}

  .summary:visited {
    color: ##0038A8; text-decoration: none;
    cursor: pointer;}

  .summary:hover+.detail,
  .detail:hover {
    display: block;}
    
  .show.detail {
    display: block;}

  .detail {
    display: none;}
</style>

<a class="summary cc" href="javascript:void(0);">Sample1</a>
<div class="detail">Detail of this summary</div>

<br>

<a class="summary" href="javascript:void(0);">Sample2</a>
<div class="detail">Detail of this summary</div>

<br>

<a class="summary" href="javascript:void(0);">Sample3</a>
<div class="detail">Detail of this summary!!!</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://codepen.io/zh1611/pen/RJxeGg.js"></script>

adding dash-plotly testcase:

import dash
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash()
app.config.suppress_callback_exceptions = True
app.css.append_css({"external_url": 'https://codepen.io/zh1611/pen/RJxeGg.css'})

# html.Script(id='js1', src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'),
# html.Script(id='js2', src='https://codepen.io/zh1611/pen/RJxeGg.js'),

app.layout = html.Div([
html.Div([html.A(children='summary-1', href='javascript:void(0);')], className='summary'),
html.Div('detail of this summary-1', className='detail'),

html.Br(),

html.Div([html.A(children='summary-2', href='javascript:void(0);')], className='summary'),
html.Div('detail of this summary-2', className='detail'),

html.Br(),

html.Div([html.A(children='summary-3', href='javascript:void(0);')], className='summary'),
html.Div('detail of this summary-3', className='detail'),

html.Br()

])

app.scripts.append_script({"external_url": 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'})
app.scripts.append_script({"external_url": 'https://codepen.io/zh1611/pen/RJxeGg.js'})

if __name__ == '__main__':
  app.run_server(port='8084')

The output looks okay but it just not work as expected :frowning:

Are you sure that your js script is correct? Perhaps, try:

$(document).ready(function(){
  $(".summary").click(function(){
    $(this).next().toggleClass("show")
  })
});

FWIW, in case you didn’t know, there is html.Details() see help(html.Details)

same result. it is working in html implementation but no effect when it is implemented in my dash-app.

i knew about html.Details(), the thing is it cannot do display-on-mousehover

works for me - the only difference to your script is:

app.scripts.append_script({"external_url": ['https://code.jquery.com/jquery-3.2.1.min.js',
                                            'https://codepen.io/zh1611/pen/RJxeGg.js']})

So, maybe use 'https://code.jquery.com/jquery-3.2.1.min.js'

somehow it work for first time but after i rebuild again it is back to square.
maybe my luck is low at this moment.

is your testcase consistently works? mind to share your full code?

the output is not consistent. sometime it work and it fail again after i refresh the page to make it work again i have to try luck by hitting F5 more frequent. i found that the probability of success is higher when i turn on debugger (F12)…fed-up =.=

i found a way to fix this issue by using this js function. according to this link, i think the reason being is the summary element is added dynamically by the react script. so we have to use event delegation.

$(document).ready(function(){
  $(document).on("click",".summary",function(){
    $(this).next().toggleClass("show")
  })
});
1 Like

I think you could just write a .js file with the javascript code you want to run and import it using grasia-dash-components library.
Read this message for more: Append script when dash components are loaded.

Also (for any latecomers to this thread) if you are looking to render local js, it looks like you can do so easily per the docs:

## Adding Your Own CSS and JavaScript to Dash Apps
    **New in dash 0.22.0**
    Including custom CSS or JavaScript in your Dash apps is simple.
    Just create a folder named `assets` in the root of your app directory
    and include your CSS and JavaScript
    files in that folder. Dash will automatically serve all of the files that
    are included in this folder. By default the url to request the assets will
    be `/assets` but you can customize this with the `assets_url_path` argument
    to `dash.Dash`.
    
    **Important: For these examples, you need to include `__name__` in your Dash constructor.**
    
    That is, `app = dash.Dash(__name__)` instead of `app = dash.Dash()`. [Here's why](https://community.plotly.com/t/dash-app-does-not-load-assets-and-app-index-string/12178/10?u=chriddyp).
    ### Example: Including Local CSS and JavaScript
    We'll create several files: `app.py`, a folder named `assets`, and
    three files in that folder:
    ```
    - app.py
    - assets/
        |-- typography.css
        |-- header.css
        |-- custom-script.js
    ```

(the website version of the docs is here: Adding CSS & JS and Overriding the Page-Load Template | Dash for Python Documentation | Plotly)

hi, you can try visdcc.Run_js, it allows you run javascript in callback

Hi all - looking to implement appending local JS similar to the assets approach from @chriddyp … however looking to have it appended after a table is built, as we are doing some class toggling on a table. loading from /assets… renders the JS immediately.

moving the JS file to a diff folder “other stuff” and trying to append with html.Script() does not appear to be working.

html.Script(src="…/other_stuff/my-script.js", type=‘text/javascript’)

1 Like

@chriddyp Any guidance here?

Like @jezlax above, I’m running into issues running local javascript that I’ve placed into ./assets - it seems that the source of those issues is that the js is being loaded before the DOM.

Reading through the discussion above as well as related issues, it’s not obvious to me what the fix is. Also don’t see anything in the docs about this issue.

1 Like