myTest532 myTest532
myTest532 myTest532

Reputation: 2381

React Native open Modal with input option and update cardItem text field

I'm trying to create an edit field using a modal. I have a list of fields inside a cardItem, when I click on one of these items, a modal should popup with an input value to be edited. I'm using native base.

Component:

...
import {
  Container, Header, Content, Card, Input,
  CardItem, Text, Right, Icon, Row,
  Left, Body, Title, Button, Label }
from 'native-base';
...
constructor(props) {
    super(props);
    this.state = {
      tenantData: {},
      visibleModal: false,
      modalField: '',
      modalLabel: '',
    };
}

renderButton = (text, onPress) => (
    <TouchableOpacity onPress={onPress}>
      <View style={styles.modalButton}>
        <Text>{text}</Text>
      </View>
    </TouchableOpacity>
  );

  renderModalContent() {
    <View style={styles.modalContent}>
      <Label>{this.state.modalLabel}</Label>
      <Input defaultValue={this.state.modalField} />
      {this.renderButton('Update', () => this.setState({
        visibleModal: null,
        modalField: '',
        modalLabel: '',
      }))}
    </View>
  }
...
render() {
  const {
      FirstName, LastName, Email, Phone, Unit, MiddleName
    } = this.state.tenantData;
  return (
    <Container>
    ...
    <Modal
        isVisible={this.state.visibleModal === true}
        animationIn={'slideInLeft'}
        animationOut={'slideOutRight'}
    >
        {this.renderModalContent()}
    </Modal>
    ...
    <Card>
        <TouchableOpacity
            onPress={() => this.setState({
                visibleModal: true,
                modalField: 'FirstName',
                modalLabel: { FirstName },
              })}
         >
             <CardItem>
                <Left>
                  <FontAwesome5 name="user-edit" />
                  <Text>First Name</Text>
                </Left>
                <Right>
                  <Row>
                    <Text style={styles.valueText}>{FirstName}   </Text>
                    <Icon name="arrow-forward" />
                  </Row>
                </Right>
              </CardItem>
        </TouchableOpacity>
       ... BELOW FEW MORE TouchableOpacity for other items ...

Will it work for react native? Right now, the modal opens and freeze the screen (nothing shows in the modal). Also, after editing the data in the modal input, how can I change the value of the {FirstName}?

Snack link: https://snack.expo.io/rJbAI_Cxr

Upvotes: 3

Views: 7023

Answers (1)

G Clark
G Clark

Reputation: 887

There were a number of issues with your snack. In NativeBase you need to include a Text tag to name your Button. There was no Input tag to accept input. I've never used react-native-modal so I switched to Modal component from react-native.

Below you will see the 3 parts of your code that I changed:
(1) import Modal from 'react-native';
(2) renderModalContent() function
(3) Modal component


    ...
    import {
      Container, Header, Content, Card, Input,
      CardItem, Text, Right, Icon, Row,
      Left, Body, Title, Button, Label, Form, Item }
    from 'native-base';
    ...
    import { Modal } from 'react-native';  // CHANGE_HERE

    class TenantDetails extends Component {
      constructor(props) {
        super(props);
        this.state = {
          tenantData: {
          FirstName: 'Jonh', LastName: 'Doe', Email: '[email protected]', Phone: 'xxx-xxx-xxxx',
          Unit: '101', MiddleName: '',
          },
          visibleModal: false,
          modalField: '',
          modalLabel: '',
        };
      } 

      renderModalContent() {  //CHANGE_HERE
        return (
        <View style={{ flex: 1 }}>
          <Form>
            <Text>Hello!</Text>
            <Item fixedLabel>
              <Label>First Name</Label>
              <Input 
                value={this.state.tenantData.FirstName}
                onChangeText={(text) => { 
                  const myTenantData = {...this.state.tenantData, FirstName: text};
                  this.setState({tenantData: myTenantData})}}
              />
            </Item>
            <Button
              onPress={() => this.setState({
                visibleModal: false
              })}
            >
            <Text>Hide Modal</Text>
            </Button>
          </Form>
        </View>
        )
      }

      render() {
        const {
          FirstName, LastName, Email, Phone, Unit, MiddleName
        } = this.state.tenantData;
        return (
          <Container>
            <Header>
              <Left>
                <Button
                  transparent
                >
                  <Icon name='arrow-back' />
                </Button>
              </Left>
              <Body>
                <Title>{FirstName} {LastName}</Title>
              </Body>
              <Right />
            </Header>
            <Content>

    ...  // CHANGE_HERE

              <Modal
                  transparent={false}
                  visible={this.state.visibleModal}
                  animationType="slide"
              >
                  {this.renderModalContent()}
              </Modal>
              <Card>
                <View style={styles.containerTextHeader}>
                  <Text style={styles.infoTextHeader}>Tenant Details</Text>
                </View>
                <TouchableOpacity
                  onPress={() => this.setState({
                    visibleModal: true,
                    modalField: 'FirstName',
                    modalLabel: { FirstName },
                  })}
                >
                  <CardItem>
                    <Left>
                      <FontAwesome5 name="user-edit" />
                      <Text>First Name</Text>
                    </Left>
                    <Right>
                      <Row>
                        <Text style={styles.valueText}>{FirstName}   </Text>
                        <Icon name="arrow-forward" />
                      </Row>
                    </Right>
                  </CardItem>
                </TouchableOpacity>
                <TouchableOpacity onPress={() => Alert.alert('OK')} >
                  <CardItem>
                    <Left>
                      <FontAwesome5 name="user-edit" />
                      <Text>Middle Name</Text>
                    </Left>
                    <Right>
                      <Row>
                        <Text style={styles.valueText}>{MiddleName}   </Text>
                        <Icon name="arrow-forward" />
                      </Row>
                    </Right>
                  </CardItem>
                </TouchableOpacity>
                <TouchableOpacity onPress={() => Alert.alert('OK')} >
                  <CardItem>
                    <Left>
                      <FontAwesome5 name="user-edit" />
                      <Text>Last Name</Text>
                    </Left>
                    <Right>
                      <Row>
                        <Text style={styles.valueText}>{LastName}   </Text>
                        <Icon name="arrow-forward" />
                      </Row>
                    </Right>
                  </CardItem>
                </TouchableOpacity>
                <TouchableOpacity onPress={() => Alert.alert('OK')} >
                  <CardItem>
                    <Left>
                      <FontAwesome name="paper-plane" />
                      <Text>Email</Text>
                    </Left>
                    <Right>
                      <Row>
                        <Text style={styles.valueText}>{Email}   </Text>
                        <Icon name="arrow-forward" />
                      </Row>
                    </Right>
                  </CardItem>
                </TouchableOpacity>
                <TouchableOpacity onPress={() => Alert.alert('OK')} >
                  <CardItem>
                    <Left>
                      <FontAwesome name="phone" />
                      <Text>Phone</Text>
                    </Left>
                    <Right>
                      <Row>
                        <Text style={styles.valueText}>{Phone}   </Text>
                        <Icon name="arrow-forward" />
                      </Row>
                    </Right>
                  </CardItem>
                </TouchableOpacity>
              </Card>
            </Content>
          </Container>
        );
      }
    }

    ...

Upvotes: 1

Related Questions