UNPKG

react-native-iran-region-picker

Version:
300 lines (273 loc) 9.56 kB
import React, {PropTypes} from 'react'; import { View, Text, Modal, Dimensions, Picker, StyleSheet, TouchableOpacity, Platform } from 'react-native'; import BaseComponent from './BaseComponent'; import webRegionAPI from './webRegionAPI'; const windowWidth = Dimensions.get('window').width; const windowHeight = Dimensions.get('window').height; const isIos = Platform.OS === 'ios'; export default class IranRegionWheelPicker extends BaseComponent { constructor(props) { super(props); this._bind( 'open', 'close', '_handleProvinceChange', '_handleCityChange', '_handleAreaChange', '_handleSubmit', '_handleCancel', ); this.state = { isVisible: this.props.isVisible, provinces: [], cities: [], areas: [], selectedProvince: this.props.selectedProvince, selectedCity: this.props.selectedCity, selectedArea: this.props.selectedArea, transparent: true, }; } _filterAllProvinces() { return this._regionAllData.map((item) => { return item.name; }); } _filterCitys(province) { const provinceData = this._regionAllData.find(item => item.name === province); return provinceData.city.map(item => item.name); } _filterAreas(province, city) { const provinceData = this._regionAllData.find(item => item.name === province); const cityData = provinceData.city.find(item => item.name === city); return cityData.area; } componentDidMount() { webRegionAPI().then((area) => { // console.log('area', area); this._regionAllData = area; const provinces = this._filterAllProvinces(); // console.log('provinces', provinces); const cities = this._filterCitys(this.state.selectedProvince); const areas = this._filterAreas(this.state.selectedProvince, this.state.selectedCity); this.setState({ provinces, cities, areas }); }); } componentWillReceiveProps(props) { if (props.isVisible !== this.props.isVisible) { if (props.isVisible) { this.open(); } else { this.close(); } } } close() { this.setState({isVisible: false}); } open() { this.setState({isVisible: true}); } _handleProvinceChange(province) { const cities = this._filterCitys(province); const areas = this._filterAreas(province, cities[0]); this.setState({ selectedProvince: province, selectedCity: cities[0], selectedArea: areas ? areas[0] : [], cities, areas }); } _handleCityChange(city) { const areas = this._filterAreas(this.state.selectedProvince, city); this.setState({ selectedCity: city, selectedArea: areas ? areas[0] : [], areas }); } _handleAreaChange(area) { this.setState({ selectedArea: area, }); } _handleCancel() { if (this.props.onCancel) { this.props.onCancel(); } this.close(); } _handleSubmit() { if (this.props.onSubmit) { this.props.onSubmit({ province: this.state.selectedProvince, city: this.state.selectedCity, area: this.state.selectedArea }); } this.close(); } renderPicker() { return ( <View style={ styles.overlayStyle }> <View style={[styles.pickerContainer, isIos ? {} : {marginTop: windowHeight - 80 - this.props.androidPickerHeight}] }> <View style={ [styles.navWrap, this.props.isRTl ? {flexDirection: 'row-reverse'} : {}]}> <TouchableOpacity style={ [styles.navBtn, {backgroundColor: navBtnColor, borderColor: navBtnColor}] } activeOpacity={ 0.85 } onPress={ this._handleSubmit }> <Text style={[styles.text, {color: navBtnColor}] }> تایید</Text> </TouchableOpacity> <TouchableOpacity style={ [styles.navBtn, {borderColor: navBtnColor}] } activeOpacity={ 0.85 } onPress={ this._handleCancel }> <Text style={[styles.text, {color: navBtnColor}] }> لغو</Text> </TouchableOpacity> </View> <View style={ [styles.pickerWrap, this.props.isRTl ? {flexDirection: 'row-reverse'} : {}]}> <Picker style={styles.pickerItem } onValueChange={ this._handleProvinceChange } selectedValue={ this.state.selectedProvince }> {this.state.provinces.map((province, index) => { return ( <Picker.Item value={ province } label={ province } key={ index } /> ); })} </Picker> <Picker style={ styles.pickerItem } onValueChange={ this._handleCityChange } selectedValue={ this.state.selectedCity }> {this.state.cities.map((city, index) => { return ( <Picker.Item value={ city } label={ city } key={ index }/> ); })} </Picker> {this.state.areas ? this.props.isShowArea && <Picker style={ styles.pickerItem } onValueChange={ this._handleAreaChange } selectedValue={ this.state.selectedArea }> {this.state.areas.map((area, index) => { return ( <Picker.Item value={ area } label={ area } key={ index } /> ); })} </Picker> : <View style={ styles.pickerItem }></View>} </View> </View> </View> ); const {navBtnColor} = this.props; } render() { const modal = ( <Modal transparent={ this.state.transparent } visible={ this.state.isVisible } onRequestClose={ this.close } animationType={ this.props.animationType }> {this.renderPicker()} </Modal> ); return ( <View> { modal } <TouchableOpacity onPress={this.open}>{ this.props.children }</TouchableOpacity> </View> ); } } IranRegionWheelPicker.propTypes = { isRTl: PropTypes.bool, isVisible: PropTypes.bool, isShowArea: PropTypes.bool, selectedProvince: PropTypes.string, selectedCity: PropTypes.string, selectedArea: PropTypes.string, navBtnColor: PropTypes.string, animationType: PropTypes.string, transparent: PropTypes.bool, onSubmit: PropTypes.func, onCancel: PropTypes.func, androidPickerHeight: PropTypes.number, }; IranRegionWheelPicker.defaultProps = { isRTl: true, isVisible: false, isShowArea: true, selectedProvince: 'تهران', selectedCity: 'تهران', selectedArea: 'تجریش', navBtnColor: 'blue', animationType: 'slide', transparent: true, onSubmit: () => { }, onCancel: () => { }, androidPickerHeight: 50 }; const styles = StyleSheet.create({ overlayStyle: { flex: 1, width: windowWidth, height: windowHeight, left: 0, position: 'absolute', backgroundColor: 'rgba(0, 0, 0, 0.5)', }, pickerContainer: { flex: 1, marginTop: windowHeight * 3 / 5, backgroundColor: '#FFF' }, navWrap: { paddingHorizontal: 15, paddingVertical: 8, justifyContent: 'space-between', alignItems: 'center', flexDirection: 'row', borderBottomWidth: 1, borderTopWidth: 1, borderColor: '#ddd', backgroundColor: '#eee' }, navBtn: { paddingVertical: 5, paddingHorizontal: 20, borderWidth: 1, borderRadius: 3, backgroundColor: '#eee', borderColor: '#dddddd' }, text: { fontSize: 18, }, pickerWrap: { flexDirection: 'row' }, pickerItem: { flex: 1 } });