# Trigger an event by changing tab

**URL:** <https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987>\
**Category:** Dash Python\
**Created:** [September 28, 2017, 5:22pm UTC](https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987 "2017-09-28T17:22:41Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gustiii](https://avatars.discourse-cdn.com/v4/letter/g/ee7513/32.png) [@Gustiii](https://community.plotly.com/u/Gustiii)\
**Post date:** [September 28, 2017, 5:22pm UTC](https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987/1 "2017-09-28T17:22:41Z")

</div>

Hii,

I want to ask if someone has a clue how to trigger an Event (@app.callback…) by changing a tab.  
So it’s similar like a button, only that a butten has one trigger, but a tab with 3 slots have 3 triggers.

---

<div class="post-metadata">

**Author:** ![DongyaoLi](https://avatars.discourse-cdn.com/v4/letter/d/49beb7/32.png) [@DongyaoLi](https://community.plotly.com/u/DongyaoLi)\
**Post date:** [September 28, 2017, 10:20pm UTC](https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987/2 "2017-09-28T22:20:42Z")

</div>

It should be similar with how you trigger a callback for dropdown.

---

<div class="post-metadata">

**Author:** ![Gustiii](https://avatars.discourse-cdn.com/v4/letter/g/ee7513/32.png) [@Gustiii](https://community.plotly.com/u/Gustiii)\
**Post date:** [October 3, 2017, 2:31pm UTC](https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987/3 "2017-10-03T14:31:51Z")

</div>

Hi, my problem is I have ah tab with an graph who gets live updated by an interval, but if I change the tab, the graph waits for the interval and is first visible after the interval.  
So I have to wait until the interval is done

---

<div class="post-metadata">

**Author:** ![DongyaoLi](https://avatars.discourse-cdn.com/v4/letter/d/49beb7/32.png) [@DongyaoLi](https://community.plotly.com/u/DongyaoLi)\
**Post date:** [October 3, 2017, 3:30pm UTC](https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987/4 "2017-10-03T15:30:54Z")

</div>

Then you use tab to trigger interval and then use interval to trigger the figure. It seems to me that tab behaves almost exactly like drop-down. It’s just in a different form and you could see all the options.

---

<div class="post-metadata">

**Author:** ![Gustiii](https://avatars.discourse-cdn.com/v4/letter/g/ee7513/32.png) [@Gustiii](https://community.plotly.com/u/Gustiii)\
**Post date:** [October 3, 2017, 3:50pm UTC](https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987/5 "2017-10-03T15:50:34Z")

</div>

Yes of course, but my problem is, if I have an interval of 10 sec. and change my tab, I have to wait 10 sec before my graph appears.

---

<div class="post-metadata">

**Author:** ![DongyaoLi](https://avatars.discourse-cdn.com/v4/letter/d/49beb7/32.png) [@DongyaoLi](https://community.plotly.com/u/DongyaoLi)\
**Post date:** [October 3, 2017, 3:54pm UTC](https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987/6 "2017-10-03T15:54:05Z")

</div>

I don’t understand. You have to wait 10 secs right? Because that’s the time it takes to generate the figure. How do you want it to behave?

---

<div class="post-metadata">

**Author:** ![chriddyp](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/chriddyp/32/16855_2.png) [@chriddyp](https://community.plotly.com/u/chriddyp)\
**Post date:** [October 3, 2017, 3:57pm UTC](https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987/7 "2017-10-03T15:57:34Z")

</div>

Would something like this work?

```auto
@app.callback(Output('container', 'children'), [Input('tab', 'value')]):
def display_content(selected_tab):
    return html.Div([
          html.H1(selected_tab),
          dcc.Graph(id='graph', figure=generate_figure(selected_tab))
    ])

def generate_figure(selected_tab):
    return {'data': [{'x': [1, 2, 3]}], 'layout': {...} # fill in with your figure

app.callback(
    Output('graph', 'figure'), 
    events=[Event('my-interval', 'interval')],
    state=[State('tab', 'value')
)(generate_figure)

```

---

<div class="post-metadata">

**Author:** ![Gustiii](https://avatars.discourse-cdn.com/v4/letter/g/ee7513/32.png) [@Gustiii](https://community.plotly.com/u/Gustiii)\
**Post date:** [October 4, 2017, 8:19am UTC](https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987/8 "2017-10-04T08:19:43Z")

</div>

This is the way I have build it now, the problem is if you make a interval of 60 sec, will have to wait after tab changing for the figure until its recreated…

---

<div class="post-metadata">

**Author:** ![chriddyp](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/chriddyp/32/16855_2.png) [@chriddyp](https://community.plotly.com/u/chriddyp)\
**Post date:** [October 4, 2017, 7:19pm UTC](https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987/9 "2017-10-04T19:19:01Z")

</div>

> [@Gustiii](#):
>
> This is the way I have build it now, the problem is if you make a interval of 60 sec, will have to wait after tab changing for the figure until its recreated…

Hm, @Gustiii could you share your solution then? The sketch that I posted in [Trigger an event by changing tab - #7 by chriddyp](https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987/7) works for me. It generates a dynamic graph on tab click (inside the `display_content` function) and _again_ after `interval` seconds from the second callback around `generate_figure`.

Here’s a GIF if this solution in action. Note how clicking on the tab updates the graph’s title immediately and notice how the title updates again after 3 seconds on that current tab.

 ![tabs-and-intervals](https://us1.discourse-cdn.com/flex024/uploads/plot/original/2X/c/c86b017fe244fb8c03fbb7e8401b10276bd7e55c.gif)

Here’s the full code example:

```auto
import dash
from dash.dependencies import Input, Output, Event, State
import dash_core_components as dcc
import dash_html_components as html

import datetime

app = dash.Dash()
app.scripts.config.serve_locally = True
app.config['suppress_callback_exceptions'] = True

app.layout = html.Div([
    dcc.Tabs(
        tabs=[
            {'label': 'Tab {}'.format(i), 'value': i} for i in range(1, 5)
        ],
        value=3,
        id='tab'
    ),
    html.Div(id='container'),
    dcc.Interval(id='my-interval', interval=3*1000)
])

def generate_figure(selected_tab):
    now = datetime.datetime.now()
    return {
        'data': [{'y': [1, 5, 3]}],
        'layout': {
            'title': 'Tab {} at {}:{}:{}'.format(
                selected_tab, now.hour, now.minute, now.second
            )
        }
    }

@app.callback(Output('container', 'children'), [Input('tab', 'value')])
def display_content(selected_tab):
    return html.Div([
          html.H1(selected_tab),
          dcc.Graph(id='graph', figure=generate_figure(selected_tab))
    ])

app.callback(
    Output('graph', 'figure'),
    events=[Event('my-interval', 'interval')],
    state=[State('tab', 'value')])(generate_figure)

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

```

---

<div class="post-metadata">

**Author:** ![Gustiii](https://avatars.discourse-cdn.com/v4/letter/g/ee7513/32.png) [@Gustiii](https://community.plotly.com/u/Gustiii)\
**Post date:** [October 5, 2017, 8:14am UTC](https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987/10 "2017-10-05T08:14:57Z")

</div>

Hey @chriddyp thank your for your work.  
I give you a simplified sample of my code.  
If you run it, you will see it takes 5 second after tab changing until the random number appears.

```
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, Event
import plotly
import numpy as np
from random import randint

app = dash.Dash()

app.css.config.serve_locally = True
app.scripts.config.serve_locally = True
app.config['suppress_callback_exceptions']=True

app.layout = html.Div([
                #TABS
                dcc.Tabs(
                    tabs=[
                        {'label': 'Tab1', 'value': 1},
                        {'label': 'Tab2', 'value': 2}],
                    value=1,
                    id='tabs',
                    vertical=False),
                html.Div(id='tab-output'),
                dcc.Interval(id='interval-component5000',interval=1*5000),

            ],
            style={
                'width': '80%',
                'fontFamily': 'Sans-Serif',
                'margin-left': 'auto',
                'margin-right': 'auto'}
            )

@app.callback(Output('live1', 'children'),
              events=[Event('interval-component5000', 'interval')])
def rand_num1():
    
    return (html.H4(str(randint(0,9))))

@app.callback(Output('live2', 'children'),
              events=[Event('interval-component5000', 'interval')])
def rand_num2():
    
    return (html.H4(str(randint(0,9))))

@app.callback(Output('tab-output', 'children'),
              [Input('tabs', 'value')])
def display_tab(value):
    
    if value == 1:
        return (html.Div(id='live1'))
            
    if value == 2:
        return (html.Div(id='live2'))

if __name__ == ' __main__':
    app.run_server(debug=True, threaded=True)
```

---

<div class="post-metadata">

**Author:** ![chriddyp](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/chriddyp/32/16855_2.png) [@chriddyp](https://community.plotly.com/u/chriddyp)\
**Post date:** [October 6, 2017, 3:02am UTC](https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987/11 "2017-10-06T03:02:42Z")

</div>

@Gustiii - You’ll need to modify your example so that your `display_tab` function calls your `rand_num2` or `rand_num1` functions to _get the most recent data_. I’d recommend taking a closer look at the example that I posted in [Trigger an event by changing tab](https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987/9?u=chriddyp) - clicking on tab calls `generate_figure` to get the most recent figure _and_ the interval callback calls `generate_figure` after N seconds.

---

<div class="post-metadata">

**Author:** ![chriddyp](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/chriddyp/32/16855_2.png) [@chriddyp](https://community.plotly.com/u/chriddyp)\
**Post date:** [October 6, 2017, 3:07am UTC](https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987/12 "2017-10-06T03:07:51Z")

</div>

@Gustiii - And here is your example updated with my suggestions above:

```auto
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, Event
import plotly
import numpy as np
from random import randint

app = dash.Dash()

app.css.config.serve_locally = True
app.scripts.config.serve_locally = True
app.config['suppress_callback_exceptions']=True

app.layout = html.Div([
                #TABS
                dcc.Tabs(
                    tabs=[
                        {'label': 'Tab1', 'value': 1},
                        {'label': 'Tab2', 'value': 2}],
                    value=1,
                    id='tabs',
                    vertical=False),
                html.Div(id='tab-output'),
                dcc.Interval(id='interval-component5000',interval=1*5000),

            ],
            style={
                'width': '80%',
                'fontFamily': 'Sans-Serif',
                'margin-left': 'auto',
                'margin-right': 'auto'}
            )

def rand_num1():
    return (html.H4(str(randint(0,9))))

app.callback(
    Output('live1', 'children'),
    events=[Event('interval-component5000', 'interval')])(rand_num1)

def rand_num2():    
    return (html.H4(str(randint(0,9))))

app.callback(
    Output('live2', 'children'),
    events=[Event('interval-component5000', 'interval')])(rand_num2)

@app.callback(Output('tab-output', 'children'),
              [Input('tabs', 'value')])
def display_tab(value):
    
    if value == 1:
        return (html.Div(id='live1', children=rand_num1()))
            
    if value == 2:
        return (html.Div(id='live2', children=rand_num2()))

if __name__ == ' __main__':
    app.run_server(debug=True, threaded=True)

```

---

<div class="post-metadata">

**Author:** ![chriddyp](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/chriddyp/32/16855_2.png) [@chriddyp](https://community.plotly.com/u/chriddyp)\
**Post date:** [October 6, 2017, 3:09am UTC](https://community.plotly.com/t/trigger-an-event-by-changing-tab/5987/13 "2017-10-06T03:09:00Z")

</div>

I recommend reading through [https://stackoverflow.com/questions/739654/how-to-make-a-chain-of-function-decorators/1594484#1594484](https://stackoverflow.com/questions/739654/how-to-make-a-chain-of-function-decorators/1594484#1594484) to get a better sense of how these decorators work and how you can refactor your code around them. 🍻
