2016-03-31 09:40:55 +08:00
|
|
|
---
|
|
|
|
order: 9
|
|
|
|
title: 搜索框
|
|
|
|
---
|
2016-02-24 15:11:50 +08:00
|
|
|
|
2016-02-24 19:55:23 +08:00
|
|
|
带有搜索按钮的自动补全输入框。
|
2016-02-24 15:11:50 +08:00
|
|
|
|
|
|
|
````jsx
|
|
|
|
import { Input, Select, Button, Icon } from 'antd';
|
|
|
|
import jsonp from 'jsonp';
|
|
|
|
import querystring from 'querystring';
|
2016-02-24 19:55:23 +08:00
|
|
|
import classNames from 'classnames';
|
2016-02-24 15:11:50 +08:00
|
|
|
const Option = Select.Option;
|
|
|
|
|
|
|
|
let timeout;
|
|
|
|
let currentValue;
|
|
|
|
|
|
|
|
function fetch(value, callback) {
|
|
|
|
if (timeout) {
|
|
|
|
clearTimeout(timeout);
|
|
|
|
timeout = null;
|
|
|
|
}
|
|
|
|
currentValue = value;
|
|
|
|
|
|
|
|
function fake() {
|
|
|
|
const str = querystring.encode({
|
|
|
|
code: 'utf-8',
|
|
|
|
q: value,
|
|
|
|
});
|
|
|
|
jsonp(`http://suggest.taobao.com/sug?${str}`, (err, d) => {
|
|
|
|
if (currentValue === value) {
|
|
|
|
const result = d.result;
|
|
|
|
const data = [];
|
|
|
|
result.forEach((r) => {
|
|
|
|
data.push({
|
|
|
|
value: r[0],
|
|
|
|
text: r[0],
|
|
|
|
});
|
|
|
|
});
|
|
|
|
callback(data);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
timeout = setTimeout(fake, 300);
|
|
|
|
}
|
|
|
|
|
|
|
|
const SearchInput = React.createClass({
|
|
|
|
getInitialState() {
|
|
|
|
return {
|
|
|
|
data: [],
|
2016-02-24 19:55:23 +08:00
|
|
|
value: '',
|
|
|
|
focus: false,
|
2016-02-24 15:11:50 +08:00
|
|
|
};
|
|
|
|
},
|
|
|
|
handleChange(value) {
|
2016-02-24 19:55:23 +08:00
|
|
|
this.setState({ value });
|
|
|
|
fetch(value, (data) => this.setState({ data }));
|
|
|
|
},
|
|
|
|
handleSubmit() {
|
|
|
|
console.log('输入框内容是: ', this.state.value);
|
|
|
|
},
|
|
|
|
handleFocusBlur(e) {
|
|
|
|
this.setState({
|
|
|
|
focus: e.target === document.activeElement,
|
2016-02-24 15:11:50 +08:00
|
|
|
});
|
|
|
|
},
|
|
|
|
render() {
|
2016-02-24 19:55:23 +08:00
|
|
|
const btnCls = classNames({
|
|
|
|
'ant-search-btn': true,
|
|
|
|
'ant-search-btn-noempty': !!this.state.value.trim(),
|
|
|
|
});
|
|
|
|
const searchCls = classNames({
|
|
|
|
'ant-search-input': true,
|
|
|
|
'ant-search-input-focus': this.state.focus,
|
2016-02-24 15:11:50 +08:00
|
|
|
});
|
2016-03-04 21:42:38 +08:00
|
|
|
const options = this.state.data.map(d => <Option key={d.value}>{d.text}</Option>);
|
2016-02-24 15:11:50 +08:00
|
|
|
return (
|
2016-02-24 19:55:23 +08:00
|
|
|
<Input.Group className={searchCls} style={this.props.style}>
|
2016-02-24 15:11:50 +08:00
|
|
|
<Select
|
|
|
|
combobox
|
2016-02-24 19:55:23 +08:00
|
|
|
value={this.state.value}
|
2016-04-27 18:07:48 +08:00
|
|
|
placeholder={this.props.placeholder}
|
2016-02-24 15:11:50 +08:00
|
|
|
notFoundContent=""
|
|
|
|
defaultActiveFirstOption={false}
|
|
|
|
showArrow={false}
|
|
|
|
filterOption={false}
|
|
|
|
onChange={this.handleChange}
|
|
|
|
onFocus={this.handleFocusBlur}
|
|
|
|
onBlur={this.handleFocusBlur}>
|
2016-03-04 21:42:38 +08:00
|
|
|
{options}
|
2016-02-24 15:11:50 +08:00
|
|
|
</Select>
|
|
|
|
<div className="ant-input-group-wrap">
|
2016-02-24 19:55:23 +08:00
|
|
|
<Button className={btnCls} onClick={this.handleSubmit}>
|
2016-02-24 15:11:50 +08:00
|
|
|
<Icon type="search" />
|
|
|
|
</Button>
|
|
|
|
</div>
|
|
|
|
</Input.Group>
|
|
|
|
);
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
ReactDOM.render(
|
|
|
|
<SearchInput placeholder="input search text" style={{ width: 200 }} />
|
|
|
|
, mountNode);
|
|
|
|
````
|