-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAutoCompleteInput.jsx
171 lines (144 loc) · 4.13 KB
/
AutoCompleteInput.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/**
* Customized Form item Input
* Could use with `rc-form` and `ant-from`
*/
import React from 'react';
import PropTypes from 'prop-types';
// import { Input } from 'antd';
// import { geneBMapPoint } from './utils';
const descMap = {
start: '请输入起点',
waypoint: '请输入途径点位置',
end: '请输入终点',
};
export default class AutoCompleteInput extends React.Component {
static propTypes = {
type: PropTypes.oneOf(['start', 'end', 'waypoint']).isRequired,
className: PropTypes.string,
style: PropTypes.object,
autoComplete: PropTypes.bool,
map: PropTypes.object.isRequired,
name: PropTypes.string,
onAutoComplete: PropTypes.func,
onSearchFail: PropTypes.func,
}
static defaultProps = {
// type: 'waypoint',
className: '',
style: {},
name: 'auto-complete-input',
autoComplete: true,
onAutoComplete: () => {},
onSearchFail: addr => alert(`${addr || '地图'}无法解析到结果!`),
}
state = {
value: {
lng: 0,
lat: 0,
address: '',
},
}
marker = null;
componentWillMount() {
this.geo = new window.BMap.Geocoder();
}
componentDidMount() {
const self = this;
const { type, autoComplete, onAutoComplete, onSearchFail } = this.props;
// TODOs: 增加非 `BMap.Autocomplete` 的支持,
// 根据debounce后的用户的输入address 去获取 Point
if (autoComplete) {
// this.setPointMarker();
this.autoCompleteInput = new window.BMap.Autocomplete({
input: this.refs.input,
location: this.props.map
});
this.autoCompleteInput.addEventListener('onconfirm', (event) => {
// the newest map reference
let { province, city, district, business, street, streetNumber } = event.item.value;
let address = province + city + district + business + street + streetNumber;
this.geo.getPoint(address, (point) => {
const { map } = this.props;
if (!point) {
return onSearchFail(address);
}
// clear previous marker
if (self.marker) {
map.removeOverlay(self.marker);
}
const marker = new window.BMap.Marker(point);
map.centerAndZoom(point, 12);
map.addOverlay(marker);
self.marker = marker;
point = {
...point,
address,
type,
};
this.onChange(point);
onAutoComplete && onAutoComplete(point);
});
});
}
}
componentWillReceiveProps(nextProps) {
// Should be a controlled component.
if ('value' in nextProps) {
const value = nextProps.value;
if (value) {
this.setState({ value });
}
}
}
componentDidUpdate(props) {
const { value, map } = props;
if (Object.keys(map).lenght && value && value.lat && value.lng && !this.marker) {
const point = new window.BMap.Point(value.lng, value.lat);
const marker = new window.BMap.Marker(point);
map.centerAndZoom(point, 12);
map.addOverlay(marker);
this.marker = marker;
}
}
componentWillUnmount = () => {
if (this.marker) {
this.props.map.removeOverlay(this.marker);
}
this.marker = null;
this.geo = null;
}
onChange = (value) => {
/* console.log('onChange====================================');
console.trace(value);
console.log('onChange===================================='); */
if (!value.address) {
value.lat = 0;
value.lng = 0;
// clear previous marker
if (this.marker) {
this.props.map.removeOverlay(this.marker);
}
}
this.setState({
value,
}, () => {
this.props.onChange(value);
});
}
render() {
const { style, name, type, map, className } = this.props;
const { value } = this.state;
return (
<input
className={className}
ref="input"
name={name}
onChange={e => this.onChange({ address: e.target.value })}
disabled={!map}
style={style}
value={value && typeof value === 'object' ? value.address : ''}
placeholder={descMap[type]}
/>
);
}
}