Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.

Commit 9d289fd

Browse files
Use new @plotly/dash-component-plugins to handle location path changes (#743)
1 parent baae1b1 commit 9d289fd

File tree

6 files changed

+87
-20
lines changed

6 files changed

+87
-20
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
44

55
## [Unreleased]
66
### Changed
7+
- [#743](https://github.com/plotly/dash-core-components/pull/743) Location component now emits an event on link update
78
- [#739](https://github.com/plotly/dash-core-components/pull/739) Async Slider and RangeSlider
89
- [#729](https://github.com/plotly/dash-core-components/pull/729) Handle case where dcc fails to load when used inside an iframe with a sandbox attribute that only has allow-scripts
910

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
6060
"@babel/preset-env": "^7.4.1",
6161
"@babel/preset-react": "^7.0.0",
62-
"@plotly/dash-component-plugins": "^1.0.2",
62+
"@plotly/dash-component-plugins": "^1.1.0",
6363
"@plotly/webpack-dash-dynamic-import": "^1.1.4",
6464
"babel-eslint": "^10.0.1",
6565
"babel-jest": "^24.5.0",

src/components/Link.react.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export default class Link extends Component {
4747
window.location.pathname = href;
4848
} else {
4949
window.history.pushState({}, '', href);
50-
window.dispatchEvent(new CustomEvent('onpushstate'));
50+
window.dispatchEvent(new CustomEvent('_dashprivate_pushstate'));
5151
}
5252
// scroll back to top
5353
window.scrollTo(0, 0);

src/components/Location.react.js

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import {Component} from 'react';
22
import PropTypes from 'prop-types';
33
import {type} from 'ramda';
4+
5+
import {History} from '@plotly/dash-component-plugins';
46
/* global window:true */
57

68
/**
@@ -11,6 +13,7 @@ export default class Location extends Component {
1113
constructor(props) {
1214
super(props);
1315
this.updateLocation = this.updateLocation.bind(this);
16+
this.onLocationChange = this.onLocationChange.bind(this);
1417
}
1518

1619
updateLocation(props) {
@@ -81,23 +84,25 @@ export default class Location extends Component {
8184
}
8285
}
8386

87+
onLocationChange() {
88+
const {setProps} = this.props;
89+
setProps({
90+
pathname: window.location.pathname,
91+
href: window.location.href,
92+
hash: window.location.hash,
93+
search: window.location.search,
94+
});
95+
96+
History.dispatchChangeEvent();
97+
}
98+
8499
componentDidMount() {
85-
const listener = () => {
86-
return () => {
87-
const {setProps} = this.props;
88-
setProps({
89-
pathname: window.location.pathname,
90-
href: window.location.href,
91-
hash: window.location.hash,
92-
search: window.location.search,
93-
});
94-
};
95-
};
96-
window.addEventListener('onpopstate', listener());
97-
window.onpopstate = listener('POP');
100+
window.onpopstate = this.onLocationChange;
98101

99-
// non-standard, emitted by Link.react
100-
window.addEventListener('onpushstate', listener());
102+
window.addEventListener(
103+
'_dashprivate_pushstate',
104+
this.onLocationChange
105+
);
101106
this.updateLocation(this.props);
102107
}
103108

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import time
2+
from multiprocessing import Value
3+
import dash
4+
from dash.dependencies import Input, Output, State
5+
import dash.testing.wait as wait
6+
import dash_core_components as dcc
7+
import dash_html_components as html
8+
9+
10+
def test_link001_event(dash_dcc):
11+
app = dash.Dash(__name__)
12+
app.layout = html.Div(
13+
[
14+
dcc.Link("Page 1", id="link1", href="/page-1"),
15+
dcc.Location(id="url", refresh=False),
16+
html.Div(id='content'),
17+
]
18+
)
19+
20+
@app.callback(Output("content", "children"), [Input("url", "pathname")])
21+
def display_page(pathname):
22+
if pathname is None or pathname == "/page-1":
23+
return html.Div("1", id="div1")
24+
elif pathname == "/":
25+
return html.Div("base", id="div0")
26+
else:
27+
return "404"
28+
29+
dash_dcc.start_server(app)
30+
dash_dcc.driver.execute_script(
31+
'''
32+
window.addEventListener('_dashprivate_pushstate', function() {
33+
window._test_link_event_counter = (window._test_link_event_counter || 0) + 1;
34+
});
35+
36+
window.addEventListener('_dashprivate_historychange', function() {
37+
window._test_history_event_counter = (window._test_history_event_counter || 0) + 1;
38+
});
39+
'''
40+
)
41+
42+
dash_dcc.wait_for_element_by_id("div0")
43+
44+
dash_dcc.find_element('#link1').click()
45+
46+
dash_dcc.wait_for_element_by_id("div1")
47+
48+
link_counter = dash_dcc.driver.execute_script(
49+
'''
50+
return window._test_link_event_counter;
51+
'''
52+
)
53+
54+
history_counter = dash_dcc.driver.execute_script(
55+
'''
56+
return window._test_history_event_counter;
57+
'''
58+
)
59+
60+
assert link_counter == 1
61+
assert history_counter == 1

0 commit comments

Comments
 (0)