我正在将材料表用于 React 与远程数据,并添加了一个自定义 TextField 以便能够控制何时启动搜索查询,例如在按下 Enter 之后。发送新的搜索词时,我query.search
用新的搜索词替换。我还意识到在新搜索后没有重新设置页码,现在将其重新设置为:
if (query.search !== searchTextValue) {
query.page = 0
}
当使用新的搜索词时,是否有另一种方法来重新设置 Query 对象?
完整代码如下
class PublicationsMatTable extends React.Component {
constructor(props) {
super(props)
this.state = ({
value: '',
searchValue: '',
});
this.handleChange = this.handleChange.bind(this);
this.getUserFriendlyStatusLabels = this.getUserFriendlyStatusLabels.bind(this);
}
tableRef = React.createRef();
// Get text input value
handleChange(event) {
this.setState({ value: event.target.value });
}
clearSearchInput = () => {
// clear value
this.setState({
value: '',
searchValue: '',
})
// refresh table
if (this.tableRef.current) {
this.tableRef.current.onQueryChange();
}
}
/**
* Set user friendly status label
*/
getUserFriendlyStatusLabels(rowData) {
if (rowData === 'UNDER_SUBMISSION' || rowData === 'UNDER_SUMMARY_STATS_SUBMISSION'
|| rowData === 'PUBLISHED_WITH_SS') {
return 'CLOSED'
}
if (rowData === 'ELIGIBLE') {
return 'OPEN FOR SUBMISSION'
}
if (rowData === 'PUBLISHED') {
return 'OPEN FOR SUMMARY STATISTICS SUBMISSION'
}
}
render() {
const { classes } = this.props;
const noResultsMessage = <span className={classes.noResultsTextStyle}>My custom message</span>;
let { searchValue } = this.state;
let searchTextValue = searchValue.trim();
return (
<Container className={classes.publicationContainer}>
<Grid container
direction="row"
justify="center"
alignItems="center">
<Grid item>
<CssTextField
id="outlined-bare"
name="searchInput"
value={this.state.value}
className={classes.textField}
variant="outlined"
placeholder="Search by PubMedID or Author"
helperText="Enter an Author name, e.g. Yao, or PMID, e.g. 25533513"
onChange={this.handleChange}
onKeyPress={(event) => {
if (event.key === 'Enter') {
event.preventDefault();
this.setState({ value: event.target.value, searchValue: event.target.value });
this.tableRef.current && this.tableRef.current.onQueryChange();
}
}}
/>
<button label="Clear" onClick={this.clearSearchInput}> Clear </button>
</Grid>
</Grid>
{searchTextValue && (
<MaterialTable
tableRef={this.tableRef}
icons={tableIcons}
columns={[
{
title: 'PubMedID', field: 'pmid',
render: rowData => (<Link to={{
pathname: `${process.env.PUBLIC_URL}/publication/${rowData.pmid}`,
state: { pmid: rowData.pmid }
}}
style={{ textDecoration: 'none' }}>{rowData.pmid}</Link>)
},
{ title: 'First author', field: 'firstAuthor', },
{ title: 'Publication', field: 'title' },
{ title: 'Journal', field: 'journal' },
{
title: 'Status', field: 'status',
render: rowData => (this.getUserFriendlyStatusLabels(rowData.status))
},
]}
data={query =>
new Promise((resolve, reject) => {
// Re-set search page for new query
if (query.search !== searchTextValue) {
query.page = 0
}
// Replace search text value in Query object with input from TextField
query.search = searchTextValue;
let url = GET_PUBLICATIONS_URL
// Handle search by PubMedID
let onlyNumbers = /^\d+$/;
if (query.search) {
if (onlyNumbers.test(query.search)) {
url += '/' + query.search + '?pmid=true'
fetch(url)
.then(response => response.json())
.then(result => {
resolve({
data: [result],
page: 0,
totalCount: 1,
})
}).catch(error => {
})
}
// Handle search by Author
else {
url += '?author=' + query.search
url += '&size=' + query.pageSize
url += '&page=' + (query.page)
console.log("** URL: ", url);
// Handle sorting search by Author results
// if (query.orderBy) {
// let sortOrder = query.orderDirection;
// url += '&sort=' + query.orderBy.field + ',' + sortOrder
// }
// else {
// Sort search by Author results asc by default
// Note: Sorting is supported for only 1 column
// url += '&sort=firstAuthor,asc'
// TODO: Check if sorting is still supported
// url = url
// }
fetch(url)
.then(response => response.json())
.then(result => {
resolve({
data: result._embedded.publications,
page: result.page.number,
totalCount: result.page.totalElements,
})
}).catch(error => {
})
}
}
// Display all results
else {
url += '?size=' + query.pageSize
url += '&page=' + (query.page)
// Handle sorting all results
if (query.orderBy) {
let sortOrder = query.orderDirection;
url += '&sort=' + query.orderBy.field + ',' + sortOrder
}
fetch(url)
.then(response => response.json())
.then(result => {
resolve({
data: result._embedded.publications,
page: result.page.number,
totalCount: result.page.totalElements,
})
}).catch(error => {
})
}
setTimeout(() => {
resolve({
data: [],
page: 0,
totalCount: 0,
});
}, 3000);
})
}
options={{
pageSize: 10,
pageSizeOptions: [10, 20, 50],
debounceInterval: 250,
toolbar: false,
}}
localization={{
body: {
emptyDataSourceMessage: noResultsMessage
}
}}
/>
)}
</Container>
)
}
}