我想向用户显示一段文本,然后要求用户选择文本的一部分。然后将对此文本进行分析,并在另一个组件中显示输出。我如何在Dash中实现这一点?这个问题类似于这个已经回答过的问题(Can Shiny recognise text selection with mouse (highlighted text)?),它在Shiny中解决了这个问题。
发布于 2021-07-05 04:28:09
我们可以通过在Javascript中添加事件侦听器来检测文本是否被选中。
在我写这篇文章的时候,我们在Dash组件和Javascript之间可能的通信方面是有限的。Clientside callbacks允许我们在回调中执行Javascript代码。我们不能在这里真正使用它们,因为没有一个合适的Input可以用来检测文本何时高亮显示。
相反,我们可以使用React创建一个自定义的Dash组件来侦听selectionchange event
当文档上的当前文本选择发生更改时,会触发Selection接口的selectionchange事件。
我已经创建了下面的自定义组件,它允许我们检测文本何时被选中,并将其持久化到一个属性中,以便在Dash回调中使用:
import React, {Component, useEffect, useState} from 'react';
import PropTypes from 'prop-types';
const SelectableWrapper = ({parentId, setProps, children}) => {
useEffect(() => {
const target = document.getElementById(parentId);
function handleSelected(e) {
setProps({selectedValue: document.getSelection().toString()});
}
document.addEventListener('selectionchange', handleSelected);
return () => {
document.removeEventListener('selectionchange', handleSelected);
};
}, []);
return children;
};
/**
* Contains a wrapper component which attaches an event that listens
* for selection of elements in the document
*/
export default class DashSelectable extends Component {
render() {
const {id, setProps, children} = this.props;
return (
<div id={id}>
<SelectableWrapper parentId={id} setProps={setProps}>
{children}
</SelectableWrapper>
</div>
);
}
}
DashSelectable.defaultProps = {};
DashSelectable.propTypes = {
/**
* The ID used to identify this component in Dash callbacks.
*/
id: PropTypes.string,
/**
* Dash-assigned callback that should be called to report property changes
* to Dash, to make them available for callbacks.
*/
setProps: PropTypes.func,
/**
* Child components
*/
children: PropTypes.node,
/**
* Selected value
*/
selectedValue: PropTypes.string,
};有关使用React创建自定义仪表盘组件的详细信息,请参阅this answer和文档here。
演示如何在Dash应用程序中使用此自定义组件:
import dash
from dash.dependencies import Input, Output
import dash_html_components as html
from dash_selectable import DashSelectable
app = dash.Dash(__name__)
app.layout = html.Div(
[
DashSelectable(
id="dash-selectable",
children=[html.P("Select this text"), html.P(id="output")],
)
]
)
@app.callback(Output("output", "children"), [Input("dash-selectable", "selectedValue")])
def display_output(value):
text = ""
if value:
text = value
return "You have selected: {}".format(text)
if __name__ == "__main__":
app.run_server(debug=True)selectedValue属性保存文档中当前选定内容的值。
每次选择更改时,都会执行此回调。
我已经把这个代码放在Github here和pypi here上了。
如果你想使用我的包,你可以用pip install dash-selectable安装它。
https://stackoverflow.com/questions/51043742
复制相似问题