3

I have to build a simple form where I have 3 labels and 3 TextInput. I want to have them on top of each other with a space between the rows.

I can't figure out the right way to do it properly.

My first attempt is to have a top View with flexDirection: 'row' then a first sub view for the labels, followed by a second sub view with the text inputs. These two views have flexDirection: "column" and justifyContent: "space between".

The views:

<View style={[InitWindowStyles.root]}>
        <View style={InitWindowStyles.textBoxAndInputBox}>
          <Text>User Name</Text>
          <Text>Password</Text>
        </View>
        <View style={InitWindowStyles.textBoxAndInputBox}>
          <TextInput
            autoCorrect={false}
            onChangeText={this.onUserNameChange}
            value={this.state.userName}
            style={{ backgroundColor: 'white', borderColor: 'black' }}
          />
          <TextInput
            autoCorrect={false}
            onChangeText={this.onPasswordChange}
            value={this.state.password}
            style={{ backgroundColor: 'white', borderColor: 'black' }}
            secureTextEntry={true}
          />
        <View>
      <View>

The Styles:

const InitWindowStyles = StyleSheet.create({

    root: {
        flex: 1,
        flexDirection: "row"
      },
    textBoxAndInputBox: {
        flex: 1, 
        flexDirection: "column",
        justifyContent: "space-between",

      }
})

The result is not that bad but not perfect.

enter image description here

The advantage that I see is that the first column is automatically sized to the largest label (not shown in the picture above), and the second column takes the available size. And it works in both portrait and landscape mode...

What is the right way to do it ?

Should I have a top view with flexDirection:"column" and sub views for each pair of label and text ?

In an Android Layout, I would have used a GridView to achieve what I want.

1 Answers1

3

If i understood correctly, you are trying to create a table structure with 3 rows and 2 columns?

This can be achieved by having a top view with flexDirection set to 'column' and child views for each row that has flexDirection set to 'row':

<View style={InitWindowStyles.root}>
  <View style={InitWindowStyles.rowContainer}>
    <Text style={InitWindowStyles.text}>User Name</Text>
    <TextInput
      autoCorrect={false}
      onChangeText={this.onUserNameChange}
      value={this.state.userName}
      style={InitWindowStyles.textInput}
    />
  </View>
  <View style={InitWindowStyles.rowContainer}>
    <Text style={InitWindowStyles.text}>Password</Text>
    <TextInput
      autoCorrect={false}
      onChangeText={this.onPasswordChange}
      value={this.state.password}
      style={InitWindowStyles.textInput}
      secureTextEntry={true}
    />
  </View>
  <View style={InitWindowStyles.rowContainer}>
    <Text style={InitWindowStyles.text}>Label 3</Text>
    <TextInput
      style={InitWindowStyles.textInput}
    />
  </View>
</View>

And the StyleSheet

const InitWindowStyles = StyleSheet.create({
  root: {
    flex: 1,
    flexDirection: "column",
  },
  rowContainer: {
    flex: 1, 
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center"
  },
  text: {
    flex: 1
  },
  textInput: {
    flex: 1,
    backgroundColor: 'white', 
    borderColor: 'black',
  }
})
Niels Ladekarl
  • 349
  • 1
  • 9
  • The result is ugly because the text input boxes are not sized correctly, they are sized upon their content, which is not what I want –  Dec 13 '18 at 13:17
  • That is because you need to style the TextInput. How do you want it to behave? – Niels Ladekarl Dec 13 '18 at 19:15
  • @OlivierMATROT I've updated the answer with an example of how you could style the Text and the TextInput. If you wish to change the size of either simply change the flex value. – Niels Ladekarl Dec 13 '18 at 19:31