我想向用户显示一段文本,然后要求用户选择部分文本。然后将分析此文本,并在另一个组件中显示输出。如何在Dash中实现这一目标?这个问题类似于已经解决的问题(Can Shiny recognise text selection with mouse (highlighted text)?),可以解决Shiny中的问题。
答案 0 :(得分:0)
我们可以通过在 Javascript 中添加事件监听器来检测文本是否被选中。
在我写这篇文章的时候,我们在 Dash 组件和 Javascript 之间可能的通信方面受到限制。 Clientside callbacks 允许我们在回调中执行 Javascript 代码。我们在这里不能真正使用它们,因为没有真正合适的 Input
可以用来检测文本何时突出显示。
我们可以使用 React 创建一个自定义 Dash 组件来监听 selectionchange
event:
选择 API 的 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 创建自定义 Dash 组件的更多信息,请参阅 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
安装它。