UNPKG

react-geoidentify-country-selector

Version:
216 lines (207 loc) 9.21 kB
/** * Created by roman on 19.10.17. */ import React from 'react'; import PropTypes from 'prop-types'; import YaGeocoder from '../../functions/ya-geocoder'; import { COUNTRIES } from '../../constants/Countries'; import './styles/bootstrap.min.css'; import './styles/flags.css'; import './styles/CountrySelector.css'; class CountrySelector extends React.Component { constructor(props) { super(props); this.hide = this.hide.bind(this); this.show = this.show.bind(this); let defaultCountry = {}; if (this.props.defaultCountry) { defaultCountry = COUNTRIES.find(item => { return item.countryName === this.props.defaultCountry }); } else if (this.props.defaultISOALPHA2Code) { defaultCountry = COUNTRIES.find(item => { return item.ISOALPHA2Code === this.props.defaultISOALPHA2Code }); } else if (this.props.defaultISOALPHA3Code) { defaultCountry = COUNTRIES.find(item => { return item.ISOALPHA3Code === this.props.defaultISOALPHA3Code }); } else if (this.props.defaultISONumericalCode) { defaultCountry = COUNTRIES.find(item => { return item.ISONumericalCode === this.props.defaultISONumericalCode }); } this.state = { defaultPropsCountry: defaultCountry, currentCountry: Object.keys(defaultCountry).length ? defaultCountry.countryName : 'United States of America', ISOALPHA2Code: Object.keys(defaultCountry).length ? defaultCountry.ISOALPHA2Code : 'US', ISOALPHA3Code: Object.keys(defaultCountry).length ? defaultCountry.ISOALPHA3Code : 'USA', ISONumericalCode: Object.keys(defaultCountry).length ? defaultCountry.ISONumericalCode : 840, displayedCountries: COUNTRIES, isListVisible: false, isFirst: true }; } componentWillUpdate(nextProps, nextState) { if (this.state.currentCountry !== nextState.currentCountry && this.state.ISOALPHA2Code !== nextState.ISOALPHA2Code && this.state.ISOALPHA3Code !== nextState.ISOALPHA3Code && this.state.ISONumericalCode !== nextState.ISONumericalCode) { this.props.getSelectedCountry( { countryName: nextState.currentCountry, ISOALPHA2Code: nextState.ISOALPHA2Code, ISOALPHA3Code: nextState.ISOALPHA3Code, ISONumericalCode: nextState.ISONumericalCode } ); } } componentDidMount() { if (typeof window !== 'undefined') { this.props.getSelectedCountry( { countryName: this.state.defaultPropsCountry.countryName, ISOALPHA2Code: this.state.defaultPropsCountry.ISOALPHA2Code, ISOALPHA3Code: this.state.defaultPropsCountry.ISOALPHA3Code, ISONumericalCode: this.state.defaultPropsCountry.ISONumericalCode } ); const yaGeocoder = new YaGeocoder(); navigator.geolocation.getCurrentPosition((position) => { if (position) { yaGeocoder.resolve(`${position.coords.longitude},${position.coords.latitude}`, (err, collection) => { if (err) throw err; const currentCountry = COUNTRIES.find(item => { return item.ISOALPHA2Code === collection[0].country_code }); this.setState({ ...this.state, currentCountry: currentCountry.countryName, ISOALPHA2Code: currentCountry.ISOALPHA2Code, ISOALPHA3Code: currentCountry.ISOALPHA3Code, ISONumericalCode: currentCountry.ISONumericalCode }); this.props.getSelectedCountry( { countryName: currentCountry.countryName, ISOALPHA2Code: currentCountry.ISOALPHA2Code, ISOALPHA3Code: currentCountry.ISOALPHA3Code, ISONumericalCode: currentCountry.ISONumericalCode } ); }); } }); } } handleSelectCountry(countryName, ISOALPHA2Code, ISOALPHA3Code, ISONumericalCode) { this.setState({ ...this.state, currentCountry: countryName, ISOALPHA2Code, ISOALPHA3Code, ISONumericalCode, }); } handleChangeCountry(e) { const query = e.target.value.toLowerCase().trim(); const displayedCountries = COUNTRIES.filter(function(item) { return item.countryName.toLowerCase().search(query) >= 0; }); this.setState({ displayedCountries }); } focusInput(component) { if (component) { component.focus(); } } show(e) { this.setState({ ...this.state, isListVisible: true }); if (typeof window !== 'undefined' && e.target.tagName.toUpperCase() !== 'INPUT') { document.addEventListener("click", this.hide); } } hide(e) { if (typeof window !== 'undefined' && e.target.tagName.toUpperCase() !== 'INPUT') { this.setState({ ...this.state, isListVisible: false }); document.removeEventListener("click", this.hide); } } render() { return ( <div className="form-group"> <div className="dropdown"> <div className="btn dropdown-toggle c-select" onClick={this.show}> <span> <img className={this.state.ISOALPHA2Code ? `flag ${this.state.ISOALPHA2Code.toLowerCase()} fnone c-dropdown-flag` : 'c-dropdown-flag'} />{this.state.currentCountry} </span> </div> <div className="dropdown-menu c-dropdown-menu" style={this.state.isListVisible ? {display: 'block'} : {display: 'none'}} > <input className="c-dropdown-input" type="text" ref={component => this.focusInput(component)} onInput={this.handleChangeCountry.bind(this)} /> <div className="c-dropdown-menu-overflow"> <ul className="c-dropdown-ul"> { this.state.displayedCountries.map((item, index) => { const flag = item.ISOALPHA2Code.toLowerCase(); return ( <li tabIndex={index} className="dropdown-item c-dropdown-item" key={item.ISOALPHA2Code} onClick={(countryName, ISOALPHA2Code, ISOALPHA3Code, ISONumericalCode) => this.handleSelectCountry( item.countryName, item.ISOALPHA2Code, item.ISOALPHA3Code, item.ISONumericalCode ) } > <a data-option={`${item.ISOALPHA2Code}`}> <img className={`flag ${flag} fnone c-dropdown-flag`} /> {item.countryName} </a> </li> ) }) } </ul> </div> </div> </div> </div> ) } } CountrySelector.propTypes = { defaultCountry: PropTypes.string, defaultISOALPHA2Code: PropTypes.string, defaultISOALPHA3Code: PropTypes.string, defaultISONumericalCode: PropTypes.number, getSelectedCountry: PropTypes.func }; export default CountrySelector;