This repository was archived by the owner on Aug 29, 2025. It is now read-only.

determine which element was clicked - #45

Merged
chriddyp merged 9 commits into
masterfrom
prev-clicks
Jun 1, 2018
Merged

determine which element was clicked#45
chriddyp merged 9 commits into
masterfrom
prev-clicks

Conversation

@chriddyp

Copy link
Copy Markdown
Member

This PR adds a n_clicks_timestamp property to all dash_html_components properties.

This can be used to determine which element was clicked on if multiple elements are Inputs in a callback.

This is just a workaround. In the future, we should enable this behaviour through something more abstract in dash-renderer and the @app.callback signature to handle this for all components and all of their properties.

Determining “which button was clicked” in a callback is the most common use case, so we’ll just support it through this n_clicks_timestamp property for now.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

This PR requires a fix in plotly/dash-renderer#54

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Usage would be:

app = dash.Dash()
app.layout = html.Div([
html.Div(id='container'),
html.Button('Click', id='button-1', n_clicks=0, n_clicks_timestamp=-1),
html.Button('Click', id='button-2', n_clicks=0, n_clicks_timestamp=-1)
])
@app.callback(
Output('container', 'children'),
[Input('button-1', 'n_clicks'),
Input('button-1', 'n_clicks_timestamp'),
Input('button-2', 'n_clicks'),
Input('button-2', 'n_clicks_timestamp')])
def update_output(button_1_clicks, button_1_timestamp,
button_2_clicks, button_2_timestamp):
if button_1_timestamp > button_2_timestamp:
# button 1 was clicked
elif button_1_timestamp > button_2_timestamp:
# button 2 was clicked
else:
# neither has been clicked

@chriddyp

Copy link
Copy Markdown
MemberAuthor

And you can try it out with:

pip install dash-html-components==0.11.0rc5
pip install dash-renderer==0.12.2rc1

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Could someone from @plotly/dash please review?

@bpostlethwaite
bpostlethwaite self-requested a review April 30, 2018 14:28

@bpostlethwaitebpostlethwaite left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well for the particular fix this is 💃

Is there an issue for the more complete solution of giving users the ability to inspect callback inputs for meta data?

I don't think this is going to be the last time we need a stopgap to work around the limitation of only getting values in a callback. It would be nice to avoid similar "needs to get done now" type stopgaps in the future.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

There isn't, but there definitely should be a greater discussion around this.

n_clicks_previous won’t work unless dash-renderer is handling - it’ll
always just be n_clicks - 1.
Instead, we could attach a timestamp to the event and use that for
comparison.
This is a stopgap until we serve this property for all components in
the framework itself.
@chriddyp
chriddyp merged commit 03ed130 into masterJun 1, 2018
@chriddyp
chriddyp deleted the prev-clicks branch June 1, 2018 00:24
@radekwlsk

Copy link
Copy Markdown

@chriddyp Is there a possibility to make n_clicks_timestamp equal -1 or 0 by default for all buttons or even all components? Now before comparing values in callback one has to check if it is None (default) and then adapt comparison based on it or set it to 0 if it is None.

The way you specified in example about explicitly setting it to -1 in the component constructor call is cumbersome and requires modifying all layouts where one wants to use that new functionality.

Simply making that property equal to 0 by default would solve it.

@rmarren1

Copy link
Copy Markdown
Contributor

@radekwlsk This will eventually be the case in plotly/dash#288.

@zhangy6x

Copy link
Copy Markdown

@chriddyp Thanks for providing this workaround. I have implemented this to determine which button was clicked in my app. But it starts to crush with memory limitation complaints after it running a while on the server. I don't know how n_clicks_timestamp works, I assume it has a continuously running timestamp even though the button was not clicked. Will this cause the memory error? Thanks!

@rmarren1

Copy link
Copy Markdown
Contributor

@zhangy6x This should not be causing the memory error you are describing. The timestamp is updated on the client side here, so it only updates when the button is clicked.

@klnrdknt

Copy link
Copy Markdown

Have there been any updates on this? E.g. for cases where there is a button in a callback together with other elements? Could the n_clicks_timestamp also be applied to dcc-core-components like Upload?

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@chriddyp@radekwlsk@rmarren1@zhangy6x@klnrdknt@bpostlethwaite
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

determine which element was clicked - #45

Merged
chriddyp merged 9 commits into
masterfrom
prev-clicks
Jun 1, 2018
Merged

determine which element was clicked#45
chriddyp merged 9 commits into
masterfrom
prev-clicks

Conversation

@chriddyp

Copy link
Copy Markdown
Member

This PR adds a n_clicks_timestamp property to all dash_html_components properties.

This can be used to determine which element was clicked on if multiple elements are Inputs in a callback.

This is just a workaround. In the future, we should enable this behaviour through something more abstract in dash-renderer and the @app.callback signature to handle this for all components and all of their properties.

Determining “which button was clicked” in a callback is the most common use case, so we’ll just support it through this n_clicks_timestamp property for now.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

This PR requires a fix in plotly/dash-renderer#54

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Usage would be:

app = dash.Dash()
app.layout = html.Div([
html.Div(id='container'),
html.Button('Click', id='button-1', n_clicks=0, n_clicks_timestamp=-1),
html.Button('Click', id='button-2', n_clicks=0, n_clicks_timestamp=-1)
])
@app.callback(
Output('container', 'children'),
[Input('button-1', 'n_clicks'),
Input('button-1', 'n_clicks_timestamp'),
Input('button-2', 'n_clicks'),
Input('button-2', 'n_clicks_timestamp')])
def update_output(button_1_clicks, button_1_timestamp,
button_2_clicks, button_2_timestamp):
if button_1_timestamp > button_2_timestamp:
# button 1 was clicked
elif button_1_timestamp > button_2_timestamp:
# button 2 was clicked
else:
# neither has been clicked

@chriddyp

Copy link
Copy Markdown
MemberAuthor

And you can try it out with:

pip install dash-html-components==0.11.0rc5
pip install dash-renderer==0.12.2rc1

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Could someone from @plotly/dash please review?

@bpostlethwaite
bpostlethwaite self-requested a review April 30, 2018 14:28

@bpostlethwaitebpostlethwaite left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well for the particular fix this is 💃

Is there an issue for the more complete solution of giving users the ability to inspect callback inputs for meta data?

I don't think this is going to be the last time we need a stopgap to work around the limitation of only getting values in a callback. It would be nice to avoid similar "needs to get done now" type stopgaps in the future.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

There isn't, but there definitely should be a greater discussion around this.

n_clicks_previous won’t work unless dash-renderer is handling - it’ll
always just be n_clicks - 1.
Instead, we could attach a timestamp to the event and use that for
comparison.
This is a stopgap until we serve this property for all components in
the framework itself.
@chriddyp
chriddyp merged commit 03ed130 into masterJun 1, 2018
@chriddyp
chriddyp deleted the prev-clicks branch June 1, 2018 00:24
@radekwlsk

Copy link
Copy Markdown

@chriddyp Is there a possibility to make n_clicks_timestamp equal -1 or 0 by default for all buttons or even all components? Now before comparing values in callback one has to check if it is None (default) and then adapt comparison based on it or set it to 0 if it is None.

The way you specified in example about explicitly setting it to -1 in the component constructor call is cumbersome and requires modifying all layouts where one wants to use that new functionality.

Simply making that property equal to 0 by default would solve it.

@rmarren1

Copy link
Copy Markdown
Contributor

@radekwlsk This will eventually be the case in plotly/dash#288.

@zhangy6x

Copy link
Copy Markdown

@chriddyp Thanks for providing this workaround. I have implemented this to determine which button was clicked in my app. But it starts to crush with memory limitation complaints after it running a while on the server. I don't know how n_clicks_timestamp works, I assume it has a continuously running timestamp even though the button was not clicked. Will this cause the memory error? Thanks!

@rmarren1

Copy link
Copy Markdown
Contributor

@zhangy6x This should not be causing the memory error you are describing. The timestamp is updated on the client side here, so it only updates when the button is clicked.

@klnrdknt

Copy link
Copy Markdown

Have there been any updates on this? E.g. for cases where there is a button in a callback together with other elements? Could the n_clicks_timestamp also be applied to dcc-core-components like Upload?

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@chriddyp@radekwlsk@rmarren1@zhangy6x@klnrdknt@bpostlethwaite
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

determine which element was clicked - #45

Merged
chriddyp merged 9 commits into
masterfrom
prev-clicks
Jun 1, 2018
Merged

determine which element was clicked#45
chriddyp merged 9 commits into
masterfrom
prev-clicks

Conversation

@chriddyp

Copy link
Copy Markdown
Member

This PR adds a n_clicks_timestamp property to all dash_html_components properties.

This can be used to determine which element was clicked on if multiple elements are Inputs in a callback.

This is just a workaround. In the future, we should enable this behaviour through something more abstract in dash-renderer and the @app.callback signature to handle this for all components and all of their properties.

Determining “which button was clicked” in a callback is the most common use case, so we’ll just support it through this n_clicks_timestamp property for now.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

This PR requires a fix in plotly/dash-renderer#54

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Usage would be:

app = dash.Dash()
app.layout = html.Div([
html.Div(id='container'),
html.Button('Click', id='button-1', n_clicks=0, n_clicks_timestamp=-1),
html.Button('Click', id='button-2', n_clicks=0, n_clicks_timestamp=-1)
])
@app.callback(
Output('container', 'children'),
[Input('button-1', 'n_clicks'),
Input('button-1', 'n_clicks_timestamp'),
Input('button-2', 'n_clicks'),
Input('button-2', 'n_clicks_timestamp')])
def update_output(button_1_clicks, button_1_timestamp,
button_2_clicks, button_2_timestamp):
if button_1_timestamp > button_2_timestamp:
# button 1 was clicked
elif button_1_timestamp > button_2_timestamp:
# button 2 was clicked
else:
# neither has been clicked

@chriddyp

Copy link
Copy Markdown
MemberAuthor

And you can try it out with:

pip install dash-html-components==0.11.0rc5
pip install dash-renderer==0.12.2rc1

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Could someone from @plotly/dash please review?

@bpostlethwaite
bpostlethwaite self-requested a review April 30, 2018 14:28

@bpostlethwaitebpostlethwaite left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well for the particular fix this is 💃

Is there an issue for the more complete solution of giving users the ability to inspect callback inputs for meta data?

I don't think this is going to be the last time we need a stopgap to work around the limitation of only getting values in a callback. It would be nice to avoid similar "needs to get done now" type stopgaps in the future.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

There isn't, but there definitely should be a greater discussion around this.

n_clicks_previous won’t work unless dash-renderer is handling - it’ll
always just be n_clicks - 1.
Instead, we could attach a timestamp to the event and use that for
comparison.
This is a stopgap until we serve this property for all components in
the framework itself.
@chriddyp
chriddyp merged commit 03ed130 into masterJun 1, 2018
@chriddyp
chriddyp deleted the prev-clicks branch June 1, 2018 00:24
@radekwlsk

Copy link
Copy Markdown

@chriddyp Is there a possibility to make n_clicks_timestamp equal -1 or 0 by default for all buttons or even all components? Now before comparing values in callback one has to check if it is None (default) and then adapt comparison based on it or set it to 0 if it is None.

The way you specified in example about explicitly setting it to -1 in the component constructor call is cumbersome and requires modifying all layouts where one wants to use that new functionality.

Simply making that property equal to 0 by default would solve it.

@rmarren1

Copy link
Copy Markdown
Contributor

@radekwlsk This will eventually be the case in plotly/dash#288.

@zhangy6x

Copy link
Copy Markdown

@chriddyp Thanks for providing this workaround. I have implemented this to determine which button was clicked in my app. But it starts to crush with memory limitation complaints after it running a while on the server. I don't know how n_clicks_timestamp works, I assume it has a continuously running timestamp even though the button was not clicked. Will this cause the memory error? Thanks!

@rmarren1

Copy link
Copy Markdown
Contributor

@zhangy6x This should not be causing the memory error you are describing. The timestamp is updated on the client side here, so it only updates when the button is clicked.

@klnrdknt

Copy link
Copy Markdown

Have there been any updates on this? E.g. for cases where there is a button in a callback together with other elements? Could the n_clicks_timestamp also be applied to dcc-core-components like Upload?

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@chriddyp@radekwlsk@rmarren1@zhangy6x@klnrdknt@bpostlethwaite
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

determine which element was clicked - #45

Merged
chriddyp merged 9 commits into
masterfrom
prev-clicks
Jun 1, 2018
Merged

determine which element was clicked#45
chriddyp merged 9 commits into
masterfrom
prev-clicks

Conversation

@chriddyp

Copy link
Copy Markdown
Member

This PR adds a n_clicks_timestamp property to all dash_html_components properties.

This can be used to determine which element was clicked on if multiple elements are Inputs in a callback.

This is just a workaround. In the future, we should enable this behaviour through something more abstract in dash-renderer and the @app.callback signature to handle this for all components and all of their properties.

Determining “which button was clicked” in a callback is the most common use case, so we’ll just support it through this n_clicks_timestamp property for now.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

This PR requires a fix in plotly/dash-renderer#54

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Usage would be:

app = dash.Dash()
app.layout = html.Div([
html.Div(id='container'),
html.Button('Click', id='button-1', n_clicks=0, n_clicks_timestamp=-1),
html.Button('Click', id='button-2', n_clicks=0, n_clicks_timestamp=-1)
])
@app.callback(
Output('container', 'children'),
[Input('button-1', 'n_clicks'),
Input('button-1', 'n_clicks_timestamp'),
Input('button-2', 'n_clicks'),
Input('button-2', 'n_clicks_timestamp')])
def update_output(button_1_clicks, button_1_timestamp,
button_2_clicks, button_2_timestamp):
if button_1_timestamp > button_2_timestamp:
# button 1 was clicked
elif button_1_timestamp > button_2_timestamp:
# button 2 was clicked
else:
# neither has been clicked

@chriddyp

Copy link
Copy Markdown
MemberAuthor

And you can try it out with:

pip install dash-html-components==0.11.0rc5
pip install dash-renderer==0.12.2rc1

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Could someone from @plotly/dash please review?

@bpostlethwaite
bpostlethwaite self-requested a review April 30, 2018 14:28

@bpostlethwaitebpostlethwaite left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well for the particular fix this is 💃

Is there an issue for the more complete solution of giving users the ability to inspect callback inputs for meta data?

I don't think this is going to be the last time we need a stopgap to work around the limitation of only getting values in a callback. It would be nice to avoid similar "needs to get done now" type stopgaps in the future.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

There isn't, but there definitely should be a greater discussion around this.

n_clicks_previous won’t work unless dash-renderer is handling - it’ll
always just be n_clicks - 1.
Instead, we could attach a timestamp to the event and use that for
comparison.
This is a stopgap until we serve this property for all components in
the framework itself.
@chriddyp
chriddyp merged commit 03ed130 into masterJun 1, 2018
@chriddyp
chriddyp deleted the prev-clicks branch June 1, 2018 00:24
@radekwlsk

Copy link
Copy Markdown

@chriddyp Is there a possibility to make n_clicks_timestamp equal -1 or 0 by default for all buttons or even all components? Now before comparing values in callback one has to check if it is None (default) and then adapt comparison based on it or set it to 0 if it is None.

The way you specified in example about explicitly setting it to -1 in the component constructor call is cumbersome and requires modifying all layouts where one wants to use that new functionality.

Simply making that property equal to 0 by default would solve it.

@rmarren1

Copy link
Copy Markdown
Contributor

@radekwlsk This will eventually be the case in plotly/dash#288.

@zhangy6x

Copy link
Copy Markdown

@chriddyp Thanks for providing this workaround. I have implemented this to determine which button was clicked in my app. But it starts to crush with memory limitation complaints after it running a while on the server. I don't know how n_clicks_timestamp works, I assume it has a continuously running timestamp even though the button was not clicked. Will this cause the memory error? Thanks!

@rmarren1

Copy link
Copy Markdown
Contributor

@zhangy6x This should not be causing the memory error you are describing. The timestamp is updated on the client side here, so it only updates when the button is clicked.

@klnrdknt

Copy link
Copy Markdown

Have there been any updates on this? E.g. for cases where there is a button in a callback together with other elements? Could the n_clicks_timestamp also be applied to dcc-core-components like Upload?

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@chriddyp@radekwlsk@rmarren1@zhangy6x@klnrdknt@bpostlethwaite
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

determine which element was clicked - #45

Merged
chriddyp merged 9 commits into
masterfrom
prev-clicks
Jun 1, 2018
Merged

determine which element was clicked#45
chriddyp merged 9 commits into
masterfrom
prev-clicks

Conversation

@chriddyp

Copy link
Copy Markdown
Member

This PR adds a n_clicks_timestamp property to all dash_html_components properties.

This can be used to determine which element was clicked on if multiple elements are Inputs in a callback.

This is just a workaround. In the future, we should enable this behaviour through something more abstract in dash-renderer and the @app.callback signature to handle this for all components and all of their properties.

Determining “which button was clicked” in a callback is the most common use case, so we’ll just support it through this n_clicks_timestamp property for now.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

This PR requires a fix in plotly/dash-renderer#54

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Usage would be:

app = dash.Dash()
app.layout = html.Div([
html.Div(id='container'),
html.Button('Click', id='button-1', n_clicks=0, n_clicks_timestamp=-1),
html.Button('Click', id='button-2', n_clicks=0, n_clicks_timestamp=-1)
])
@app.callback(
Output('container', 'children'),
[Input('button-1', 'n_clicks'),
Input('button-1', 'n_clicks_timestamp'),
Input('button-2', 'n_clicks'),
Input('button-2', 'n_clicks_timestamp')])
def update_output(button_1_clicks, button_1_timestamp,
button_2_clicks, button_2_timestamp):
if button_1_timestamp > button_2_timestamp:
# button 1 was clicked
elif button_1_timestamp > button_2_timestamp:
# button 2 was clicked
else:
# neither has been clicked

@chriddyp

Copy link
Copy Markdown
MemberAuthor

And you can try it out with:

pip install dash-html-components==0.11.0rc5
pip install dash-renderer==0.12.2rc1

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Could someone from @plotly/dash please review?

@bpostlethwaite
bpostlethwaite self-requested a review April 30, 2018 14:28

@bpostlethwaitebpostlethwaite left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well for the particular fix this is 💃

Is there an issue for the more complete solution of giving users the ability to inspect callback inputs for meta data?

I don't think this is going to be the last time we need a stopgap to work around the limitation of only getting values in a callback. It would be nice to avoid similar "needs to get done now" type stopgaps in the future.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

There isn't, but there definitely should be a greater discussion around this.

n_clicks_previous won’t work unless dash-renderer is handling - it’ll
always just be n_clicks - 1.
Instead, we could attach a timestamp to the event and use that for
comparison.
This is a stopgap until we serve this property for all components in
the framework itself.
@chriddyp
chriddyp merged commit 03ed130 into masterJun 1, 2018
@chriddyp
chriddyp deleted the prev-clicks branch June 1, 2018 00:24
@radekwlsk

Copy link
Copy Markdown

@chriddyp Is there a possibility to make n_clicks_timestamp equal -1 or 0 by default for all buttons or even all components? Now before comparing values in callback one has to check if it is None (default) and then adapt comparison based on it or set it to 0 if it is None.

The way you specified in example about explicitly setting it to -1 in the component constructor call is cumbersome and requires modifying all layouts where one wants to use that new functionality.

Simply making that property equal to 0 by default would solve it.

@rmarren1

Copy link
Copy Markdown
Contributor

@radekwlsk This will eventually be the case in plotly/dash#288.

@zhangy6x

Copy link
Copy Markdown

@chriddyp Thanks for providing this workaround. I have implemented this to determine which button was clicked in my app. But it starts to crush with memory limitation complaints after it running a while on the server. I don't know how n_clicks_timestamp works, I assume it has a continuously running timestamp even though the button was not clicked. Will this cause the memory error? Thanks!

@rmarren1

Copy link
Copy Markdown
Contributor

@zhangy6x This should not be causing the memory error you are describing. The timestamp is updated on the client side here, so it only updates when the button is clicked.

@klnrdknt

Copy link
Copy Markdown

Have there been any updates on this? E.g. for cases where there is a button in a callback together with other elements? Could the n_clicks_timestamp also be applied to dcc-core-components like Upload?

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@chriddyp@radekwlsk@rmarren1@zhangy6x@klnrdknt@bpostlethwaite
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

determine which element was clicked - #45

Merged
chriddyp merged 9 commits into
masterfrom
prev-clicks
Jun 1, 2018
Merged

determine which element was clicked#45
chriddyp merged 9 commits into
masterfrom
prev-clicks

Conversation

@chriddyp

Copy link
Copy Markdown
Member

This PR adds a n_clicks_timestamp property to all dash_html_components properties.

This can be used to determine which element was clicked on if multiple elements are Inputs in a callback.

This is just a workaround. In the future, we should enable this behaviour through something more abstract in dash-renderer and the @app.callback signature to handle this for all components and all of their properties.

Determining “which button was clicked” in a callback is the most common use case, so we’ll just support it through this n_clicks_timestamp property for now.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

This PR requires a fix in plotly/dash-renderer#54

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Usage would be:

app = dash.Dash()
app.layout = html.Div([
html.Div(id='container'),
html.Button('Click', id='button-1', n_clicks=0, n_clicks_timestamp=-1),
html.Button('Click', id='button-2', n_clicks=0, n_clicks_timestamp=-1)
])
@app.callback(
Output('container', 'children'),
[Input('button-1', 'n_clicks'),
Input('button-1', 'n_clicks_timestamp'),
Input('button-2', 'n_clicks'),
Input('button-2', 'n_clicks_timestamp')])
def update_output(button_1_clicks, button_1_timestamp,
button_2_clicks, button_2_timestamp):
if button_1_timestamp > button_2_timestamp:
# button 1 was clicked
elif button_1_timestamp > button_2_timestamp:
# button 2 was clicked
else:
# neither has been clicked

@chriddyp

Copy link
Copy Markdown
MemberAuthor

And you can try it out with:

pip install dash-html-components==0.11.0rc5
pip install dash-renderer==0.12.2rc1

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Could someone from @plotly/dash please review?

@bpostlethwaite
bpostlethwaite self-requested a review April 30, 2018 14:28

@bpostlethwaitebpostlethwaite left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well for the particular fix this is 💃

Is there an issue for the more complete solution of giving users the ability to inspect callback inputs for meta data?

I don't think this is going to be the last time we need a stopgap to work around the limitation of only getting values in a callback. It would be nice to avoid similar "needs to get done now" type stopgaps in the future.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

There isn't, but there definitely should be a greater discussion around this.

n_clicks_previous won’t work unless dash-renderer is handling - it’ll
always just be n_clicks - 1.
Instead, we could attach a timestamp to the event and use that for
comparison.
This is a stopgap until we serve this property for all components in
the framework itself.
@chriddyp
chriddyp merged commit 03ed130 into masterJun 1, 2018
@chriddyp
chriddyp deleted the prev-clicks branch June 1, 2018 00:24
@radekwlsk

Copy link
Copy Markdown

@chriddyp Is there a possibility to make n_clicks_timestamp equal -1 or 0 by default for all buttons or even all components? Now before comparing values in callback one has to check if it is None (default) and then adapt comparison based on it or set it to 0 if it is None.

The way you specified in example about explicitly setting it to -1 in the component constructor call is cumbersome and requires modifying all layouts where one wants to use that new functionality.

Simply making that property equal to 0 by default would solve it.

@rmarren1

Copy link
Copy Markdown
Contributor

@radekwlsk This will eventually be the case in plotly/dash#288.

@zhangy6x

Copy link
Copy Markdown

@chriddyp Thanks for providing this workaround. I have implemented this to determine which button was clicked in my app. But it starts to crush with memory limitation complaints after it running a while on the server. I don't know how n_clicks_timestamp works, I assume it has a continuously running timestamp even though the button was not clicked. Will this cause the memory error? Thanks!

@rmarren1

Copy link
Copy Markdown
Contributor

@zhangy6x This should not be causing the memory error you are describing. The timestamp is updated on the client side here, so it only updates when the button is clicked.

@klnrdknt

Copy link
Copy Markdown

Have there been any updates on this? E.g. for cases where there is a button in a callback together with other elements? Could the n_clicks_timestamp also be applied to dcc-core-components like Upload?

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@chriddyp@radekwlsk@rmarren1@zhangy6x@klnrdknt@bpostlethwaite
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

determine which element was clicked - #45

Merged
chriddyp merged 9 commits into
masterfrom
prev-clicks
Jun 1, 2018
Merged

determine which element was clicked#45
chriddyp merged 9 commits into
masterfrom
prev-clicks

Conversation

@chriddyp

Copy link
Copy Markdown
Member

This PR adds a n_clicks_timestamp property to all dash_html_components properties.

This can be used to determine which element was clicked on if multiple elements are Inputs in a callback.

This is just a workaround. In the future, we should enable this behaviour through something more abstract in dash-renderer and the @app.callback signature to handle this for all components and all of their properties.

Determining “which button was clicked” in a callback is the most common use case, so we’ll just support it through this n_clicks_timestamp property for now.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

This PR requires a fix in plotly/dash-renderer#54

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Usage would be:

app = dash.Dash()
app.layout = html.Div([
html.Div(id='container'),
html.Button('Click', id='button-1', n_clicks=0, n_clicks_timestamp=-1),
html.Button('Click', id='button-2', n_clicks=0, n_clicks_timestamp=-1)
])
@app.callback(
Output('container', 'children'),
[Input('button-1', 'n_clicks'),
Input('button-1', 'n_clicks_timestamp'),
Input('button-2', 'n_clicks'),
Input('button-2', 'n_clicks_timestamp')])
def update_output(button_1_clicks, button_1_timestamp,
button_2_clicks, button_2_timestamp):
if button_1_timestamp > button_2_timestamp:
# button 1 was clicked
elif button_1_timestamp > button_2_timestamp:
# button 2 was clicked
else:
# neither has been clicked

@chriddyp

Copy link
Copy Markdown
MemberAuthor

And you can try it out with:

pip install dash-html-components==0.11.0rc5
pip install dash-renderer==0.12.2rc1

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Could someone from @plotly/dash please review?

@bpostlethwaite
bpostlethwaite self-requested a review April 30, 2018 14:28

@bpostlethwaitebpostlethwaite left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well for the particular fix this is 💃

Is there an issue for the more complete solution of giving users the ability to inspect callback inputs for meta data?

I don't think this is going to be the last time we need a stopgap to work around the limitation of only getting values in a callback. It would be nice to avoid similar "needs to get done now" type stopgaps in the future.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

There isn't, but there definitely should be a greater discussion around this.

n_clicks_previous won’t work unless dash-renderer is handling - it’ll
always just be n_clicks - 1.
Instead, we could attach a timestamp to the event and use that for
comparison.
This is a stopgap until we serve this property for all components in
the framework itself.
@chriddyp
chriddyp merged commit 03ed130 into masterJun 1, 2018
@chriddyp
chriddyp deleted the prev-clicks branch June 1, 2018 00:24
@radekwlsk

Copy link
Copy Markdown

@chriddyp Is there a possibility to make n_clicks_timestamp equal -1 or 0 by default for all buttons or even all components? Now before comparing values in callback one has to check if it is None (default) and then adapt comparison based on it or set it to 0 if it is None.

The way you specified in example about explicitly setting it to -1 in the component constructor call is cumbersome and requires modifying all layouts where one wants to use that new functionality.

Simply making that property equal to 0 by default would solve it.

@rmarren1

Copy link
Copy Markdown
Contributor

@radekwlsk This will eventually be the case in plotly/dash#288.

@zhangy6x

Copy link
Copy Markdown

@chriddyp Thanks for providing this workaround. I have implemented this to determine which button was clicked in my app. But it starts to crush with memory limitation complaints after it running a while on the server. I don't know how n_clicks_timestamp works, I assume it has a continuously running timestamp even though the button was not clicked. Will this cause the memory error? Thanks!

@rmarren1

Copy link
Copy Markdown
Contributor

@zhangy6x This should not be causing the memory error you are describing. The timestamp is updated on the client side here, so it only updates when the button is clicked.

@klnrdknt

Copy link
Copy Markdown

Have there been any updates on this? E.g. for cases where there is a button in a callback together with other elements? Could the n_clicks_timestamp also be applied to dcc-core-components like Upload?

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@chriddyp@radekwlsk@rmarren1@zhangy6x@klnrdknt@bpostlethwaite
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

determine which element was clicked - #45

Merged
chriddyp merged 9 commits into
masterfrom
prev-clicks
Jun 1, 2018
Merged

determine which element was clicked#45
chriddyp merged 9 commits into
masterfrom
prev-clicks

Conversation

@chriddyp

Copy link
Copy Markdown
Member

This PR adds a n_clicks_timestamp property to all dash_html_components properties.

This can be used to determine which element was clicked on if multiple elements are Inputs in a callback.

This is just a workaround. In the future, we should enable this behaviour through something more abstract in dash-renderer and the @app.callback signature to handle this for all components and all of their properties.

Determining “which button was clicked” in a callback is the most common use case, so we’ll just support it through this n_clicks_timestamp property for now.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

This PR requires a fix in plotly/dash-renderer#54

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Usage would be:

app = dash.Dash()
app.layout = html.Div([
html.Div(id='container'),
html.Button('Click', id='button-1', n_clicks=0, n_clicks_timestamp=-1),
html.Button('Click', id='button-2', n_clicks=0, n_clicks_timestamp=-1)
])
@app.callback(
Output('container', 'children'),
[Input('button-1', 'n_clicks'),
Input('button-1', 'n_clicks_timestamp'),
Input('button-2', 'n_clicks'),
Input('button-2', 'n_clicks_timestamp')])
def update_output(button_1_clicks, button_1_timestamp,
button_2_clicks, button_2_timestamp):
if button_1_timestamp > button_2_timestamp:
# button 1 was clicked
elif button_1_timestamp > button_2_timestamp:
# button 2 was clicked
else:
# neither has been clicked

@chriddyp

Copy link
Copy Markdown
MemberAuthor

And you can try it out with:

pip install dash-html-components==0.11.0rc5
pip install dash-renderer==0.12.2rc1

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Could someone from @plotly/dash please review?

@bpostlethwaite
bpostlethwaite self-requested a review April 30, 2018 14:28

@bpostlethwaitebpostlethwaite left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well for the particular fix this is 💃

Is there an issue for the more complete solution of giving users the ability to inspect callback inputs for meta data?

I don't think this is going to be the last time we need a stopgap to work around the limitation of only getting values in a callback. It would be nice to avoid similar "needs to get done now" type stopgaps in the future.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

There isn't, but there definitely should be a greater discussion around this.

n_clicks_previous won’t work unless dash-renderer is handling - it’ll
always just be n_clicks - 1.
Instead, we could attach a timestamp to the event and use that for
comparison.
This is a stopgap until we serve this property for all components in
the framework itself.
@chriddyp
chriddyp merged commit 03ed130 into masterJun 1, 2018
@chriddyp
chriddyp deleted the prev-clicks branch June 1, 2018 00:24
@radekwlsk

Copy link
Copy Markdown

@chriddyp Is there a possibility to make n_clicks_timestamp equal -1 or 0 by default for all buttons or even all components? Now before comparing values in callback one has to check if it is None (default) and then adapt comparison based on it or set it to 0 if it is None.

The way you specified in example about explicitly setting it to -1 in the component constructor call is cumbersome and requires modifying all layouts where one wants to use that new functionality.

Simply making that property equal to 0 by default would solve it.

@rmarren1

Copy link
Copy Markdown
Contributor

@radekwlsk This will eventually be the case in plotly/dash#288.

@zhangy6x

Copy link
Copy Markdown

@chriddyp Thanks for providing this workaround. I have implemented this to determine which button was clicked in my app. But it starts to crush with memory limitation complaints after it running a while on the server. I don't know how n_clicks_timestamp works, I assume it has a continuously running timestamp even though the button was not clicked. Will this cause the memory error? Thanks!

@rmarren1

Copy link
Copy Markdown
Contributor

@zhangy6x This should not be causing the memory error you are describing. The timestamp is updated on the client side here, so it only updates when the button is clicked.

@klnrdknt

Copy link
Copy Markdown

Have there been any updates on this? E.g. for cases where there is a button in a callback together with other elements? Could the n_clicks_timestamp also be applied to dcc-core-components like Upload?

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@chriddyp@radekwlsk@rmarren1@zhangy6x@klnrdknt@bpostlethwaite