我尝试使用React Virtualized Select https://github.com/bvaughn/react-virtualized-select进行下拉,我的反应组件代码在这里
var React = require('react');
var ReactDOM = require('react-dom');
var SearchActions = require('../actions/SearchActions');
var AppStore = require('../stores/AppStore');
var AppActions = require('../actions/AppActions');
var Utils = require('../utils/Utils');
var SearchAccountSelector = require('./SearchAccountSelector');
var queryString = require('query-string');
var SearchHint = require('./SearchHint');
var VirtualizedSelect = require('react-virtualized-select').default;
module.exports = React.createClass({
componentName: 'Search',
getDefaultProps() {
return {};
},
getInitialState() {
return {
error: false,
authenticated: false,
visible: true,
data: null,
showAccountSelection: false,
selected: null,
search: '',
optionPartnerList: []
};
},
componentDidMount () {
var qS = queryString.parse(location.search);
if (qS && qS.search) {
this.setState({search: qS.search, visible: true});
}
this._unsubscribe = AppStore.listen(Utils.createRefluxComponentDispatcher(this));
},
componentDidUpdate: function () {
if (this.refs.inputSearch) {
this.refs.inputSearch.focus();
this.refs.inputSearch.select()
}
},
componentWillUnmount () {
this._unsubscribe();
},
[AppStore.events.onSecurityCheck] () {
console.log('onSecurityCheck', arguments);
this.setState(function (prev, cur) {
var st = {
authenticated: AppStore.authenticated
};
if (!AppStore.authenticated) {
st.async = false;
}
return st;
});
},
[AppStore.events.onAccountSearch] (data) {
var accountsNum = data.errorMessage ? 0 : this.numberOfAccountsFound(data);
var state = {
async: false,
data: data.errorMessage ? {} : data,
showAccountSelection: false,
selected: null,
error: null
};
console.log('[' + accountsNum + '] accounts found when search completed', data);
if (accountsNum == 0) {
state.error = data.errorMessage ? data.errorMessage : 'No accounts found';
} else if (accountsNum == 1) {
// if there is single account found selecting it and closing search panel
state.selected = this.getFirstKey(data);
state.visible = false;
AppActions.selectAccount(state.selected);// auto select account if there is no ambiguites
SearchActions.cDVR({query: state.selected});
} else {
// if multiple account found lets user select a correct one
state.showAccountSelection = true;
}
this.setState(state);
},
[AppStore.events.onSelectAccount]() {
if (AppStore.isValidUserProfile()) {
this.setState({
visible: false
});
}
},
[AppStore.events.onLogin]() {
//Handling properly case when session is timed out so user will return to previos screen
if (!this.state.selected) {
this.setState({
visible: true
});
}
},
[AppStore.events.onLogout](event) {
if(!event || !event.byTimeout){
this.setState({ data: null,
showAccountSelection: false,
selected: null,
search: ''
});
}
},
[AppStore.events.onResized](windowSize){
this.setState({width: windowSize.innerWidth, height: innerHeight})
},
numberOfAccountsFound(data) {
var size = 0, key;
if (!data) {
return size;
}
for (key in data) {
if (data.hasOwnProperty(key)) size++;
}
return size;
},
getFirstKey(data){
for (let key in data) {
if (data.hasOwnProperty(key)) return key;
}
},
handleClick(event) {
event.preventDefault();
this.refs.searchHint.removePopover();
console.log('clicked event', event);
this.setState({
data: null,
async: true,
error: null
}
);
var query = this.refs.inputSearch.value.trim();
this.setState({search: query});
if (query) {
//extract receiver Id from Recording Id, by extracting string between V&L or A&L
AppActions.resetFieldsForNewSearch();
var receiverIdPattern = new RegExp('(V|A)(.*?)L');
var parsedReceiverId = receiverIdPattern.exec(query);
if (parsedReceiverId != null && parsedReceiverId[2] != null) {
let receiverId = parsedReceiverId[2];
AppActions.setSearchQuery(query);
//use receiverId to perform search
query = receiverId;
} else {
AppActions.clearRecIdSearch();
}
SearchActions.cDVR({query: query});
AppStore.selectedPartner = '';
SearchActions.search({query: query});
Utils.updateQueryString('search', query);
} else {
this.setState({async: false, error: 'Invalid Input'});
}
},
openNav(){
this.setState({visible: true});
AppActions.hideBodyScrollBar();
},
closeNav(){
this.refs.searchHint.refs.popover.close();
this.setState({visible: false});
AppActions.showBodyScrollBar();
},
searchIcon(){
if (this.state.authenticated) {
return (<span id="search" onClick={this.openNav}><i className="fa fa-search search-icon pointer" style={{fontSize: '1.4em'}}/></span>);
}
},
getOptions(partnerList) {
let options = partnerList.map( x => ({value :x,label: x}));
return options;
},
errorRender() {
let style = this.state.error ? {visibility: 'visible'} : {visibility: 'hidden'};
return (
<div style={style} className="alert alert-danger" role="alert">
<i className="fa fa-exclamation-triangle"></i> {this.state.error}
</div>);
},
toggleOverlayStyle(state){
this.setState({overlayOverflowY : state});
},
[AppStore.events.onResized](windowSize) {
let state = AppStore.innerHeight < 900 && this.refs.searchHint && this.refs.searchHint.state.showSearchHint ? 'auto' : 'hidden';
this.toggleOverlayStyle(state);
},
[AppStore.events.onPartnersAllowedUpdated](partnerList) {
this.optionPartnerList = this.getOptions(partnerList);
},
render: function () {
var self= this;
if (!this.state.authenticated) {
return null;
}
let componentDisabled = this.state.async ? true : false;
let buttonIcon;
let closeButton = AppStore.selectedAccount ?
<a href="#" className="closebtn" onClick={this.closeNav}>×</a> :
(<a key="-1" className="logout-link dropdown-item t-font" onClick={AppActions.logout} href="#">
<i className="fa fa-sign-out m-r-10"></i>Logout</a>);
let overlayStyle = {width: this.state.visible ? '100%' : '0px', display: this.state.visible ? 'block' : 'none', 'overflowX': 'hidden', 'overflowY': this.state.overlayOverflowY};
if (this.state.visible) {
AppActions.hideBodyScrollBar();
} else {
AppActions.showBodyScrollBar();
}
if (!this.state.async) {
buttonIcon = <i className="fa fa-search"></i>
} else {
buttonIcon = <i className="fa fa-cog fix fa-spin"></i>
}
//TODO: refactor this make it css driven using flex box
let style = {top: '37%'};
if (this.state.data && Object.keys(this.state.data).length > 1) {
style = {top: '10%'};
}
return (
<div style={{float:'left'}} className="search-div">
{this.searchIcon()}
<div className="overlay" style={overlayStyle}>
{closeButton}
<div className="global-search center-content-wrapper" style={style}>
<form id="searchFormComponent" ref={function(){$('#searchFormComponent').show('fast')}}
className="global-search" onSubmit={this.handleClick} style={{height: '500px'}}>
{this.errorRender()}
<div className="f-row f-center">
<VirtualizedSelect
options={self.optionPartnerList}
onChange={(selectValue) => this.setState({ selectValue })}
value={this.state.selectValue}
/>
<button id="searchbutton" className="btn btn-lg btn-primary btn-block t-font f-1"
disabled={componentDisabled}
onClick={this.handleClick}
style={{ paddingLeft: '4px',paddingRight: '4px', fontSize:'1.1em',marginLeft:'500px'}}>
{buttonIcon}
</button>
</div>
<SearchAccountSelector data={this.state.search == ''? {}: this.state.data}/>
</form>
</div>
</div>
</div>
);
}
});
这就是我在package.json中包含的方式
"react": "^15.6.2",
"react-dimensions": "^1.3.0",
"react-dom": "^15.6.2",
"react-virtualized-select": "3.1.0",
"react-idle-timer": "^1.2.12",
我还按照https://github.com/bvaughn/react-virtualized-select#simple-example
列出了以下css我已将css包含在我的main.jsp
中但面临的问题是,在显示“#34;未找到结果”时,下拉列表未正确加载。
答案 0 :(得分:1)
react-virtualized-select
正在使用react-select
来呈现select元素。因此,请尝试更改.Select-menu-outer
宽度。设置width=100%
。
请确保已加载react-select.css
。