Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to close modal and return value from flatlist when click on item in react native?

I am creating country codes class. In which, I return list of country codes. I want to close modal that contains of list codes and also return the clicked item value of flat list that display list of modals. I want return country code from modal screen to current js file. Here is my Codes modal Class:-

import React, { Component } from 'react';
import { StyleSheet, View, 
Text,Modal,FlatList,TouchableWithoutFeedback} from 'react-native';
import { showMessage } from '../utils/GeneralFunctions';
import { Icon } from 'react-native-elements';
import TextInputBox from '../components/TextInputBox';
import {color} from '../values/color';
import {TextViewNonClickable} from '../components/TextView';

const countryCodes = require('../jsonData/codesCountry.json');

export default class Codes extends Component {

constructor(props) {
    super(props);
    this.state = {
        countryCodes : countryCodes,
        modalVisible : false,
        searchedText : '',
        loading : false,
        selectedCountry : '',
    };

    this.arrayHolder = [];
}    

componentWillMount = () => {
    if(this.state.modalVisible == false){
        this.setState({countryCodes : countryCodes})
    }
    this.arrayHolder = countryCodes;
};

//show countries modal
static showCountryModal = (modalVisibility) => {
    showMessage("sunny");
    if(modalVisibility == true){
        this.setState({modalVisible:false})
   }else{
       this.setState({modalVisible:true})
   }
}

//set Modal Visibility
static setModalVisibility(visibility){
    showMessage("Set Modal Visibility : "+visibility);
    this.setState({modalVisible:visibility});
}

//search country
searchText = (text) => {
    const newData = this.arrayHolder.filter(item => {
        const itemData = `${item.name.toUpperCase()} 
${item.code.toUpperCase()} ${item.dial_code.toUpperCase()}`;
        const textData = text.toUpperCase();
        return itemData.indexOf(textData) > -1;      
    });
    if(text != null){
        this.setState({
            countryCodes : newData,
        });
    }else if(text == " "){
        this.setState({
            countryCodes : countryCodes,
        });
    }
};

//setting selected country
selectedCountry = (item) => {
    this.props.modalVisible = false;
    this.setState({selectedCountry : item.dial_code})
    showMessage("Code : " + item.dial_code)        
}

_renderItem = ({item}) => {
    return (
        <TouchableWithoutFeedback onPress={() => 
this.selectedCountry(item)}>
            <View style=                       
   {{height:48,flexDirection:'row',
 justifyContent:'center',alignItems:'center',
padding:16,borderBottomWidth:1,
borderBottomColor:color.pageBackground}}>
                <TextViewNonClickable
                    textViewText={item.name+"("+item.code+")"}
                    textStyle=    
{{fontSize:16,fontWeight:'bold',flex:0.85,
color:color.colorBlack}}
                />
                <TextViewNonClickable
                    textViewText={item.dial_code}
                    textStyle=
{{fontSize:16,fontWeight:'bold',flex:0.15,
color:color.colorBlack}}
                />
            </View>
        </TouchableWithoutFeedback>
    )
}

render() { 

  //  const {modalVisible} = this.props;

    return (
            <Modal
                animationType='slide'
                transparent={false}
                visible={this.state.modalVisible}
                onRequestClose={() => this.setState({
    countryCodes : countryCodes})}    
            >
                <View>
                    <View style={{flexDirection:'row',height:48,
    justifyContent:"center",alignItems:'center',
    borderBottomWidth:1,paddingStart:16,paddingRight:16}}>
                        <Icon 
                            name='search' type='material-icons'
     size={24} color='black'
                        />
                        <TextInputBox
                            textInputStyle=
  {{borderColor:color.colorTransparent,
    color:color.colorHintText,flex:1}}
                            placeHolderText='Search here...'
                            onChangeText={text => 
        this.searchText(text)}  
                        />
                    </View>

                   <View>
                        <FlatList
                            data={this.state.countryCodes}
                            renderItem={this._renderItem}
                            keyExtractor={(item,index) => 
        item+index}
                            showsVerticalScrollIndicator={false}
                        />
                   </View>
                </View>                    
            </Modal>
        );
    }

}

const styles = StyleSheet.create({
    container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    },
});

Here is my codesClass.js class

import React, { Component } from 'react';
import {StyleSheet,View,ImageBackground} from 'react-native';
import { HeaderView } from '../components/Headers';
import { Actions } from 'react-native-router-flux';
import { appString } from '../values/appStrings';
import { color } from '../values/color';
import TextInputBox from '../components/TextInputBox';
import TextViewClickable from '../components/TextView';
import Button from '../components/Buttons';
import {showToast, showMessage} from '../utils/GeneralFunctions'
import { dimension } from '../values/dimensions';
import Codes from '../dialogs/Codes';

export default class SignUpScreen extends Component {

constructor(props) {
    super(props);
    this.state = {
        countryCode : '',
        phone : '',
        modalVisible:false,
    };
}

openOrCloseCountryCodes = () => {
    if(this.state.modalVisible == false){
        // this.setState({modalVisible:true});
        Codes.setModalVisibility(true);
    }else{
        // this.setState({modalVisible:false});
        Codes.setModalVisibility(false);
    }
    // Codes.showCountryModal(true);
}


render() {
    return ( 
    <View>
    <View style={{flexDirection:'row',marginTop:20}}>
          <TextViewClickable
              textViewText={this.state.countryCode != '' ? 
    this.state.countryCode : '+91'}
              touchableButtonStyle={styles.touchableButtonStyle}
              textStyle={styles.textStyle}
                    onPress={() => 
            {this.openOrCloseCountryCodes();}}
                />
            <TextInputBox
                placeHolderText={appString.placeholderPhoneNumber}
                onChangeTextSet={(text) => {this.setState({
        phone : text})}}
                textInputStyle={{flex : 1,marginLeft : 4}}
                />
            </View>
        <Codes modalVisible={this.state.modalVisible} 
                closeModal={() => this.openOrCloseCountryCodes()}/>
        </View>

            );
        }

    }

    const styles = StyleSheet.create({

parentView : {
    flex: 1,
    alignItems: 'center',  
},
touchableButtonStyle: {
    marginRight : 4,
    borderRadius: dimension.textInputBorderRadius,
    borderWidth: dimension.textInputBorderWidth,
    borderColor: color.textInputBorderColor,
    justifyContent : 'center',
    alignItems:'center',
    paddingLeft: 16,
    paddingRight: 16,
},
textStyle : {
    fontSize: dimension.regularFontSize,  
    color : color.colorHintText,
        }
    });
like image 340
Savinder Singh Avatar asked Sep 03 '25 15:09

Savinder Singh


2 Answers

In your case I assume the closing and opening of Modal is working.

In the below function you set the selected country code to a certain state along with it close the modal and pass the value to class Codes create another function same as showCountryModal and set it to a state there.

In class signUpScreen paste the below changes

Code below :

selectedCountry = (item) => {
  this.openOrCloseCountryCodes();
  Codes. setSelectedCountryCode(item.dial_code);
  this.setState({selectedCountry : item.dial_code})
  showMessage("Code : " + item.dial_code)        
}

In class Codes paste the below changes

Code below :

// initialise `state` `countryCode`
        constructor(props) {
        super(props);
        this.state = {
            countryCodes : countryCodes,
            modalVisible : false,
            searchedText : '',
            loading : false,
            selectedCountry : '',
            countryCode: ""
        };

        this.arrayHolder = [];
    }    

    //set selected country
    static setSelectedCountryCode = (countryCode) => {
            this.setState({countryCode: countryCode})
     }

Also include onRequestClose so that backbuttonclick of android gets handled on onRequestClose call the function to close the modal

You should study the concept of props and the static method idea not that great to control modal visibility use props instead.

like image 122
Amal p Avatar answered Sep 05 '25 06:09

Amal p


onRequestClose on Modal should be:

onRequestClose={() => this.props.closeModal(this.state.selectedCountry)}   

and SignUpScreen, handle callback value:

<Codes 
     modalVisible={this.state.modalVisible} 
     closeModal={(selectedCountry) => {
         this.openOrCloseCountryCodes()

         // do something with selectedCountry
         console.log(selectedCountry)
     }}
/>
like image 40
Kenzk447 Avatar answered Sep 05 '25 05:09

Kenzk447