admin管理员组文章数量:1406060
I need to trigger a callback if the value of a dcc.Dropdown component in dash is modified by the user. Essentially, I am looking to avoid the cases where the value component of a prop is modified by a different callback (anything other than the user).
It seems that dash does not have any method for distinguishing whether a user/something else modified a prop. As such, I have been attempting to use event listeners to detect when the dcc.Dropdown is changed due to a click or keydown event.
document.addEventListener('DOMContentLoaded', function() {
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.addedNodes.length) {
const dropdown = document.getElementById('my-dropdown');
if (dropdown) {
dropdown.addEventListener('click', function(event) {
if (event.target && event.target.matches("div.VirtualizedSelectOption")) {
console.log(event.target.innerText);
}
});
observer.disconnect(); }
}
});
});
observer.observe(document.body, { childList: true, subtree: true });
});
This does detect selections of a value from the dcc.Dropdown, but does not detect if the user removes the value.
The reason I am looking for a solution to this is I need to modify the values in this list dependent on future selected values. For example if there ends up being a duplicate entry added I need to remove the value in the dcc.Dropdown as it is no longer a valid entry. This cannot be done statically (eg. disabling options which lead to duplicates) as the options change frequently.
I need to trigger a callback if the value of a dcc.Dropdown component in dash is modified by the user. Essentially, I am looking to avoid the cases where the value component of a prop is modified by a different callback (anything other than the user).
It seems that dash does not have any method for distinguishing whether a user/something else modified a prop. As such, I have been attempting to use event listeners to detect when the dcc.Dropdown is changed due to a click or keydown event.
document.addEventListener('DOMContentLoaded', function() {
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.addedNodes.length) {
const dropdown = document.getElementById('my-dropdown');
if (dropdown) {
dropdown.addEventListener('click', function(event) {
if (event.target && event.target.matches("div.VirtualizedSelectOption")) {
console.log(event.target.innerText);
}
});
observer.disconnect(); }
}
});
});
observer.observe(document.body, { childList: true, subtree: true });
});
This does detect selections of a value from the dcc.Dropdown, but does not detect if the user removes the value.
The reason I am looking for a solution to this is I need to modify the values in this list dependent on future selected values. For example if there ends up being a duplicate entry added I need to remove the value in the dcc.Dropdown as it is no longer a valid entry. This cannot be done statically (eg. disabling options which lead to duplicates) as the options change frequently.
Share Improve this question asked Mar 6 at 19:08 benmcgloinbenmcgloin 456 bronze badges1 Answer
Reset to default 3 +100Issue: But does not detect if the user removes the value.
This is likely because when the user removes the value (by clicking on the Remove ('x') icon), the event propagation is stopped. So the click
event on the dropdown is not getting triggered.
Solution: Instead of click
event, use the mousedown
event. You also need to use the keydown
event, because the user can clear the selected value by pressing the Backspace key.
Example: I've only included the part of your code where you need to make the changes.
...
// Check for both addedNodes and removedNodes
if (mutation.addedNodes.length || mutation.removedNodes.length) {
const dropdown = document.getElementById('my-dropdown');
if (dropdown) {
['mousedown', 'keydown'].forEach((eventType) => {
dropdown.addEventListener(eventType, function(event) {
...
});
})
...
}
}
...
Update: You can also achieve what you want using without mutation observers. The idea is simple: when the user modifies the dropdown it must be preceded by either mousedown
or keydown
event. So in the event listeners compare the previous and current dropdown values and if there are added/removed values then trigger your callback.
Code:
const dropdown = document.getElementById("demo-dropdown");
let selectedValues = [...document.getElementsByClassName('Select-value')];
let selectedValuesLength = selectedValues.length;
['mousedown', 'keydown'].forEach((eventType) => {
dropdown.addEventListener(eventType, (event) => {
setTimeout(() => {
if (document.getElementsByClassName('Select-value').length !== selectedValuesLength) {
console.log('value changed...')
let newSelectedValues = [...document.getElementsByClassName('Select-value')];
let addedNodes, removedNodes;
addedNodes = [...newSelectedValues].filter(node => {
return ! [...selectedValues].some(node2 => {
return node.textContent === node2.textContent;
})
})
removedNodes = [...selectedValues].filter(node => {
return ! [...newSelectedValues].some(node2 => {
return node.textContent === node2.textContent;
});
})
console.log(addedNodes)
console.log(removedNodes)
if (addedNodes.length || removedNodes.length) {
// Trigger your callback here
}
selectedValues = [...document.getElementsByClassName('Select-value')];
selectedValuesLength = document.getElementsByClassName('Select-value').length;
}
}, 500)
})
})
本文标签: javascriptPlotly DashTriggering a callback on user modification of a propStack Overflow
版权声明:本文标题:javascript - Plotly Dash - Triggering a callback on user modification of a prop - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744955072a2634307.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论