DarkFantasy
DarkFantasy

Reputation: 320

How to change image on image click in Plotly?

In my app, I need to change an image on image click. How can I do that?

Folder structure:

- app.py
- assets/
    |-- custom-script.js

app.py

app = dash.Dash(__name__)
app.layout = html.Div(
[
html.Img(
            className="myImg",
            id="speak_btn",
            src="assets/img/microphone.png",


              style={},
            ),

])

custom-script.js

$(document).ready(function () {
    $(".myImg").click(function () {
        if ($(this).attr("src") === "assets/img/microphone.png")
            $(this).attr("src", "assets/img/voice_gif.gif");
        else if ($(this).attr("src") === "assets/img/voice_gif.gif")
            $(this).attr("src", "assets/img/microphone.png");
    })
});

Here is a guide to understanding why I have put it in the assets folder https://dash.plotly.com/external-resources

The custom-script.js is tested and working. Need help adapting it to dash. Thanks

Upvotes: 0

Views: 1552

Answers (1)

rahlf23
rahlf23

Reputation: 9019

You can use app.clientside_callback() to run JS clientside like so:

import dash
from dash.dependencies import Input, Output, State
import dash_html_components as html

app = dash.Dash(__name__)

app.layout = html.Div([

    html.Img(id='speak_btn', src='assets/img/microphone.png', className='myImg', n_clicks_timestamp=0)

])

app.clientside_callback(
    """
    function(click, src) {
        if ( src == 'assets/img/microphone.png' && click != 0 ) {
            return 'assets/img/voice_gif.gif';
        } else {
            return 'assets/img/microphone.png';
        }
    }
    """,
    Output('speak_btn', 'src'),
    [Input('speak_btn', 'n_clicks_timestamp')],
    [State('speak_btn', 'src')]
)

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

You can also accomplish this task without JS by writing a callback to change the src attribute of html.Img every time n_clicks_timestamp is updated, like so:

import dash
from dash.dependencies import Input, Output, State
import dash_html_components as html
from dash.exceptions import PreventUpdate

app = dash.Dash(__name__)

microphone = 'assets/img/microphone.png'
voice_gif = 'assets/img/voice_gif.gif'

app.layout = html.Div([

    html.Img(id='speak_btn', src=microphone, className='myImg', n_clicks_timestamp=0)

])

@app.callback(
    Output('speak_btn', 'src'),
    [Input('speak-btn', 'n_clicks_timestamp')],
    [State('speak_btn', 'src')])
def change_img(click, src):

    if not click: raise PreventUpdate

    return gif if src==microphone else microphone

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

Upvotes: 1

Related Questions