react-nativenative-basereact-android

create multiple picker(dropdown) in flat list and handle selected state react native


I want to create form in flat list containing picker(Dropdown) for title. suppose there are 3 people the list-view will create form containers and each will have basic info like name, last name and title with picker. I able to create form using flat list. I am not able to handle selected value of multiple picker.

This is what i did but not updating a state where am I going wrong

const data = [
  {name: 'one'},
  {name: 'two'},
];
const newTitles = [];

export default class BusBookingPage extends Component {

  constructor(props) {
    super(props);
    this.state = {
      titleArray:[],
    };
  }

  componentDidMount(){
    newTitles = this.state.titleArray.slice() 
    for (var i = 0; i < data.length; i++) {
      newTitles[i]='Mr';
    }
    this.setState({titleArray: newTitles})
  }

  onValueChange(index: string,value: number) {
    var my_array = this.state.titleArray.slice() 
    for (var i = 0; i < data.length; i++) {
      if(index==i){ my_array.splice(i, 1, value)}
    }
    this.setState({titleArray: my_array}) 
  }


  renderItem = ({ item, index }) => {
    const itemsArray = this.state.titleArray;
    var title;
    if(index==0){
      title = "Primary Passenger";
    }else{
      title = "Co-Passenger " + index;
    } 
    return (
      <View>
        <Card style={styles.ContainerCardStyle}>
          <View style={styles.CardContainer}>
            <CardItem>
              <View style={{flex:1}}>
                <View style={{flexDirection: 'row',flex:1}}>
                  <Text style={styles.CardTitleText}>{title}</Text>
                  <View style={{backgroundColor: '#f2f2f2'}}>
                    <Text style={[styles.CardTitleText]}>Name - {item.name}</Text>
                  </View>
                </View>
                <View style={{flexDirection: 'row',flex:1, marginTop: 5,marginBottom: 1}}>
                  <Picker
                    key={index}
                    mode="dropdown"
                    iosHeader="Select your Title"
                    iosIcon={ 
                      <Icon 
                        name ="arrow-drop-down-circle"
                        style = {{ color: "#007aff", fontSize: 25 }} />
                    }
                    style={{ width: undefined }}
                    selectedValue={"Miss"}
                    // onValueChange={(itemValue, itemIndex) => this.onClickDropdown(itemValue, itemIndex, item)}>
                    onValueChange={this.onValueChange.bind(this,index)}>

                    <Picker.Item label="Select Title" value="" />
                    <Picker.Item label="Mr" value="Mr" />
                    <Picker.Item label="Mrs" value="Mrs" />
                    <Picker.Item label="Miss" value="Miss" />
                  </Picker>
                </View>
                <Item 
                  floatingLabel 
                  style={styles.InputBoxStyle}>
                  <Label>First Name</Label>
                  <Input />
                </Item>
                <Item 
                  floatingLabel 
                  style={styles.InputBoxStyle}>
                  <Label>Last Name</Label>
                  <Input/>
                </Item>
              </View>
            </CardItem> 
          </View>
        </Card>
    </View>
    );
  };

  render() {
    return (
      <FlatList
        data={data}
        renderItem={this.renderItem}
        keyExtractor={(item, index) => item.name}
      />
    );
  }
}

Edit 1: i have used this (this.state.titleArray[index]) at place of selectedValue={"Miss"} but not working


Solution

  • Pass extraData attribute and assign your state in the FlatList. And in Picker assign your state to selectedValue. Please check the below code.

     const data = [
              {name: 'one'},
              {name: 'two'},
            ];
           let pickers = [];
           const newTitles = [];
           const Titles_array = [];
           export default class BusBookingPage extends Component {
    
           constructor(props) {
           super(props);
            this.state = {
            titleArray:[],
          };
    
          }
    
          componentDidMount(){
           newTitles = this.state.titleArray.slice() //copy the array
           var newState = this.state.shareholders.slice()
           var newgender = this.state.genderArray.slice()
           for (var i = 0; i < data.length; i++) {
           newTitles[i]='Mr';
           newgender.splice(i, 1, false);
           pickers.splice(i, 1, 'Mr');
           newState[i]= {titles:'Select Title'};
           Titles_array[i]= '';
          }
          this.setState({titleArray: newTitles}) //set the new state
         }
    
         handlePickerSelection(value,index){
          let markers = [ ...this.state.titleArray ];
          for (var j = 0; j < markers.length; j++) {
          if(j===index){
           markers[index] = value;
           }else{
          markers[j] = markers[j];
         }
        }
        this.setState({titleArray: markers });
       }
    
    
       renderItem = ({ item, index }) => {
       const itemsArray = this.state.titleArray;
       var title;
       if(index==0){
        title = "Primary Passenger";
       }else{
        title = "Co-Passenger " + index;
       }
       return (
        <View>
            <Card style={styles.ContainerCardStyle}>
                <View style={styles.CardContainer}>
                  <CardItem>
                    <View style={{flex:1}}>
                      <View style={{flexDirection: 'row',flex:1}}>
                        <Text style={styles.CardTitleText}>{title}</Text>
                        <View style={{backgroundColor: '#f2f2f2'}}>
                          <Text style={[styles.CardTitleText]}>Seat - {item.Seat}</Text>
                        </View>
    
                      </View>
    
                       <View style={{flexDirection: 'row',flex:1,marginTop: 5,marginBottom: 1}}>
                           <Picker
                            key={index}
                            iosHeader="Select your Title"
                            iosIcon={<Icon name="arrow-drop-down-circle" style={{ color: "#007aff", fontSize: 25 }} />}
                            style={{ width: undefined }}
                            selectedValue={this.state.titleArray[index]}
                            onValueChange={(v:string) => this.handlePickerSelection(v,index)}>
    
    
                            <Picker.Item label="Select Title" value="s" />
                            <Picker.Item label="Mr" value="Mr" />
                            <Picker.Item label="Mrs" value="Mrs" />
                            <Picker.Item label="Miss" value="Miss" />
                          </Picker>
                        </View>
    
                      <Item 
                        floatingLabel 
                        style={styles.InputBoxStyle}
                        >
                        <Label>First Name</Label>
                        <Input
                          ref={"Fname"+index}
                          onChangeText={(text)=> this.onChanged(text,"Fname"+index)} />
                      </Item>
                     <Item 
                        floatingLabel 
                        style={styles.InputBoxStyle}>
                        <Label>Last Name</Label>
                        <Input 
                          ref={"Lname"+index}
                          onChangeText={(text)=> this.onChanged(text,"Lname"+index)}
    
                          />
                      </Item>
                    </View>
                  </CardItem> 
                  <CardItem> 
    
    
                  </CardItem> 
                </View>
            </Card>
        </View>
      );
      };
      render() {
      return (
      <Container style={{backgroundColor: '#EEEEEE',}}>
          <Content>
          <FlatList
            extraData={this.state.titleArray}
            data={data}
            renderItem={this.renderItem}
            keyExtractor={(item, index) => item.Seat}
          />
    
          </Content>
      </Container>
     );
    }
    }