MapField.js 9.9 KB
import React,{PropTypes} from 'react';
import ReactDOM from 'react-dom'; 
import cx from 'classnames';
import s from './CustomForm.scss';
import {Row,Col,Button} from 'react-bootstrap'; 
import DropdownPicker from '../DropdownPicker';
import NumberField from './NumberField';


class MapField extends React.Component {
    constructor(props) {
        super(props);   
        this.state={
            editCircleRang:false, 
            loc_name:null,
            loc_nation:'中华人民共和国',
            loc_province:null,
            loc_city:null,
            loc_longitude:null,
            loc_latitude:null,
            loc_float_range:100,
            options:[]
        } 
        this.localeChange=this.localeChange.bind(this);
        this.setLngAndLat=this.setLngAndLat.bind(this);
        this.openFloatRange=this.openFloatRange.bind(this);
        this.closeFloatRange=this.closeFloatRange.bind(this);
        this.changeLocal=this.changeLocal.bind(this);
        this.setValues=this.setValues.bind(this);
        this.updateLocal=this.updateLocal.bind(this);
        this.backLocation=this.backLocation.bind(this);
    }
    static propTypes = {    
        displayName:PropTypes.string, 
        fields:PropTypes.object,
        validateState:PropTypes.string,
        inlineFlag:PropTypes.bool,
        placeholder:PropTypes.string 
    }  
    static defaultProps={
        inlineFlag:true,
        multiselect:false 
    }
    validationState(field){
        if(field.error&&field.touched){
            return 'error';
        }else if(field.touched)
            return ''; 
    }
    setValues(values,lnglat){
        const {fields:{city,float_range,latitude,longitude,name,nation,province}}=this.props;
        this.setState({ 
            loc_name:values.formattedAddress, 
            loc_province:values.addressComponent.province,
            loc_city:values.addressComponent.city,
            loc_longitude:lnglat.lng,
            loc_latitude:lnglat.lat,
        });
        name.onChange(values.formattedAddress);
        nation.onChange(this.state.loc_nation);
        province.onChange(values.addressComponent.province);
        city.onChange(values.addressComponent.city);
        longitude.onChange(lnglat.lng);
        latitude.onChange(lnglat.lat);
        float_range.onChange(this.state.loc_float_range);
    }
    changeLocal(e){
        const {fields:{name}}=this.props;
        this.setState({
            loc_name:e.target.value
        })
        name.onChange(e.target.value);
    }
    closeFloatRange(){
        this.setState({
            editCircleRang:false
        })
        this.editCircle.close();
    }
    openFloatRange(){ 
        this.setState({
            editCircleRang:true
        })
        this.editCircle.open();
    } 
    updateLocal(e,target){
        const {fields:{float_range,latitude,longitude}}=this.props; 
        const center=e.target.getCenter();
        const radius=e.target.getRadius();
        this.setState({
            loc_longitude:center.lng,
            loc_latitude:center.lat,
            loc_float_range:radius
        });
        longitude.onChange(center.lng);
        latitude.onChange(center.lat);
        float_range.onChange(radius);
    }
    setLngAndLat(e){
        const {editCircleRang,loc_name,loc_float_range}=this.state,self=this; 
        const lnglat={lng:e.lnglat.getLng(),lat:e.lnglat.getLat()}
        if(editCircleRang)
            return;
        if(this.circle){
            this.mapContainer.remove(this.circle);
        }
        this.circle = new AMap.Circle({
            center: new AMap.LngLat(e.lnglat.getLng(),e.lnglat.getLat()),// 圆心位置
            radius: loc_float_range, //半径
            strokeColor: "#F33", //线颜色
            strokeOpacity: 1, //线透明度
            strokeWeight: 1, //线粗细度
            fillColor: "#ee2200", //填充颜色
            fillOpacity: 0.15//填充透明度
        });
        this.circle.setMap(this.mapContainer);  
        AMap.plugin('AMap.CircleEditor',function(){//回调函数 
            self.editCircle=new AMap.CircleEditor(self.mapContainer,self.circle); 
            self.editCircle.on('end',self.updateLocal);
        });
        const lnglatXY=[e.lnglat.getLng(),e.lnglat.getLat()]; 
        this.geocoder.getAddress(lnglatXY,function(status,result){
            if (status === 'complete' && result.info === 'OK') { 
                if(!loc_name){ 
                    self.placeSearch.setCity(result.regeocode.addressComponent.adcode);
                    self.placeSearch.search(result.regeocode.formattedAddress); 
                }
                self.setValues(result.regeocode,lnglat);
            }
        });  
    }
    localeChange(e){
        const {fields:{name}}=this.props;
        this.placeSearch.setCity(e.poi.adcode);
        this.placeSearch.search(e.poi.name); 
        this.setState({
            loc_name:e.poi.name
        }) 
        name.onChange(e.target.value);
    }
    backLocation(){
        const {fields:{float_range,latitude,longitude,name}}=this.props,self=this;
        if(!longitude.value||!latitude.value){
            return
        }
        if(this.circle){
            this.mapContainer.remove(this.circle);
        }
        this.circle = new AMap.Circle({
            center: new AMap.LngLat(longitude.value,latitude.value),// 圆心位置
            radius: float_range.value, //半径
            strokeColor: "#F33", //线颜色
            strokeOpacity: 1, //线透明度
            strokeWeight: 1, //线粗细度
            fillColor: "#ee2200", //填充颜色
            fillOpacity: 0.15//填充透明度
        });
        this.circle.setMap(this.mapContainer);  
        AMap.plugin('AMap.CircleEditor',function(){//回调函数 
            self.editCircle=new AMap.CircleEditor(self.mapContainer,self.circle); 
            self.editCircle.on('end',self.updateLocal);
        });
        this.setState({ 
            loc_name:name.value
        });
        this.mapContainer.setZoom(14);
        this.mapContainer.setCenter([longitude.value,latitude.value]);
    }
    componentWillReceiveProps(nextProps){ 
        if(!this.state.loc_name){
            this.backLocation();
        }
    }
    componentDidMount(){    
        const width='100%',height=300,padding=0,self=this;
        $(this.refs['mapContainer']).append(`<div id='map_container_wrap' style='width:${width-padding*2}px;height:${height-padding*2}px'></div>`); 
        this.mapContainer=new AMap.Map('map_container_wrap',{
            resizeEnable: true 
        });
        const autoOptions={
            input:'mapSearchInput'
        };
        AMap.plugin('AMap.Autocomplete',function(){//回调函数 
            const auto= new AMap.Autocomplete(autoOptions);
            AMap.event.addListener(auto, "select", self.localeChange);
        });
        AMap.plugin('AMap.PlaceSearch',function(){//回调函数 
            self.placeSearch=new AMap.PlaceSearch({
                map:self.mapContainer
            });  
        });  
        AMap.plugin('AMap.Geocoder',function(){//回调函数 
            self.geocoder=new AMap.Geocoder({
                radius: 1000,
                extensions: "all"
            }); 
            self.backLocation();
        });  
        AMap.plugin('AMap.ToolBar',function(){//回调函数 
            self.toolBar=new AMap.ToolBar({
                visible: true
            });
            self.mapContainer.addControl(self.toolBar);
        });  
        this.mapContainer.on('click',self.setLngAndLat)
    } 
    componentWillUnmount() {  
        this.mapContainer.destroy();
    }
    render(){  
        const {displayName,placeholder,inlineFlag,fields:{name,nation,province,city,longitude,latitude,float_range}}=this.props,self=this;   
        const {editCircleRang,options,loc_name,loc_nation,loc_province,loc_city,loc_longitude,loc_latitude,loc_float_range}=this.state;
        let validateState=this.validationState(name);
        return( 
            <div> 
                    <Row>
                        <Col md={5}>
                            <div className={cx(s.field_wrap,'form-group',{
                                'has-success':validateState=='success',
                                'has-warning':validateState=='warning',
                                'has-error':validateState=='error',
                                'row':inlineFlag,
                                'form-horizontal':inlineFlag
                            })}> 
                                <label className={cx('control-label',{
                                    'col-sm-3':inlineFlag
                                })}>工作地点</label>
                                <div className={cx(s.input_wrap,{
                                    'col-sm-9':inlineFlag
                                })} > 
                                    <input onChange={this.changeLocal} placeholder='点击输入' value={loc_name} className={cx(s.map_serach_input,'form-control')} id='mapSearchInput' ref='mapSearchInput' type="text"/>
                                    <span className={cx(s.input_help,'help-block')}><small>{name.touched?name.error:''}</small></span>
                                </div>
                            </div>   
                        </Col>
                        <Col md={5}>
                            <NumberField customWidth={5} inlineFlag={true} readOnly={true} defaultValue={loc_float_range} displayName='当前可打卡范围'  field={float_range} units='米' ></NumberField>
                        </Col>
                        <Col md={2}>
                            {!editCircleRang&&<Button bsStyle="success" onClick={this.openFloatRange}>调整可打卡范围</Button>}
                            {editCircleRang&&<Button bsStyle="success" onClick={this.closeFloatRange}>确认</Button>}
                        </Col>
                    </Row>
                    <div  ref='mapContainer'>
                    </div> 
            </div>
        )
    }
}



export default MapField;