0

I am working on a react project where I have a text input which will take input values n number of times.The screen looks like this:

image1

After clicking Next , the value will get submitted in the next page, and we can come back to enter more values in the text box in the page shown in the screenshot below. For each value that I have entered in the , there will be a corresponding radio button value. So, I have created an array in the state which will have the values of the textbox .

this.state = { 
    buildingNames: [],
    selectedOptions: ''
}

The selectedOptions state takes the radio button value. So, currently whenever a new value is added in the texbox I am pushing it to the buildingNames state.But I am not able to get how to get the corresponding radioButton value for each buildingName and push it as an array of objects. Currently, I am pushing the value of the text box into the array like:

const tempState = [...this.state.buildingNames];
tempState.push(inputData.value);
this.setState({buildingNames: tempState });

where inputData.value is the value entered in the text box.

So my final array should be like :

buildingDetails:[
  {
    buildingName:'abc'
    radioButtonValue:'1'
  },
  {
    buildingName:'def'
    radioButtonValue:'2'
  },
  {
    buildingName:'ghi'
    radioButtonValue:'3'
  },
  // so on
] 

I am not able to understand how to get the value of the radio button for the corresponding building. So, how do I proceed.Can anyone please guide me?

1 Answer 1

1

Approach 1

You can make buildingDetails an object (which will have buildingName and radioButtonValue keys), and add another state pageNo. pageNo can be used as an index to save data in buildingDetails. So buildingDetails[0].buildingName will store the input value of buildingName of first page. So on and so forth.

Here is an example, I have added comments where necessary:

class Reservation extends React.Component {
  numberOfPages = 10 // total number of pages

  constructor(props) {
    super(props)
    this.state = {
      pageNo: 0, // which page we are currently on, 0 based
      buildingDetails: {}, // this is an object which should be indexed with `pageNo`
    }
  }

  handleInputChange = event => {
    const target = event.target
    const value = target.type === 'checkbox' ? target.checked : target.value
    const name = target.name

    // save the data to the corresponding `pageNo` index of buildingDetails
    this.setState(prevState => ({
      buildingDetails: {
        ...prevState.buildingDetails,
        [prevState.pageNo]: {
          ...prevState.buildingDetails[prevState.pageNo],
          [name]: value,
        },
      },
    }))
  }

  handlePrevClick = e => {
    // TODO: implement your own logic so that it never goes past page 0
    e.preventDefault()
    this.setState(prevState => ({
      pageNo: prevState.pageNo - 1,
    }))
  }
  handleNextClick = e => {
    // TODO: implement your own logic so that it never goes beyond last page
    e.preventDefault()
    this.setState(prevState => ({
      pageNo: prevState.pageNo + 1,
    }))
  }

  render() {
    return (
      <form>
        <label>
          Building Name:
          <input
            name="buildingName"
            value={
              this.state.buildingDetails[this.state.pageNo]
                ? this.state.buildingDetails[this.state.pageNo].buildingName
                : ''
            }
            onChange={this.handleInputChange}
          />
        </label>
        <br />
        <div>
          Dummy Gender:
          <input
            type="radio"
            name="radioButtonValue"
            value="male"
            checked={
              this.state.buildingDetails[this.state.pageNo]
                ? this.state.buildingDetails[this.state.pageNo]
                    .radioButtonValue === 'male'
                : false
            }
            onChange={this.handleInputChange}
          />{' '}
          Male
          <input
            type="radio"
            name="radioButtonValue"
            value="female"
            checked={
              this.state.buildingDetails[this.state.pageNo]
                ? this.state.buildingDetails[this.state.pageNo]
                    .radioButtonValue === 'female'
                : false
            }
            onChange={this.handleInputChange}
          />{' '}
          Female
          <br />
        </div>

        <button onClick={this.handlePrevClick}>Prev</button>
        <button onClick={this.handleNextClick}>Next</button>
        <br />
        <code>{JSON.stringify(this.state)}</code>
      </form>
    )
  }
}

function App() {
  return (
    <div className="App">
      <Reservation />
    </div>
  )
}

const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Approach 2

buildDetails will an Array and you fill it initially with placeholder objects. Use pageNo to index the array, almost same approach as before. Here you will map the current array to a new one, but modify the object indexed at pageNo:

class Reservation extends React.Component {
  numberOfPages = 10; // total number of pages

  constructor(props) {
    super(props);
    this.state = {
      pageNo: 0, // which page we are currently on, 0 based
      buildingDetails: new Array(this.numberOfPages).fill({
        buildingName: "",
        radioButtonValue: ""
      }) // this is an array which should be indexed with `pageNo`
    };
  }

  handleInputChange = event => {
    const target = event.target;
    const value = target.type === "checkbox" ? target.checked : target.value;
    const name = target.name;

    // save the data to the corresponding `pageNo` index of buildingDetails
    this.setState(prevState => ({
      buildingDetails: prevState.buildingDetails.map((detail, index) => {
        if (index !== prevState.pageNo) {
          // This isn't the item we care about - keep it as-is
          return detail;
        }

        // Otherwise, this is the one we want - return an updated value
        return {
          ...detail,
          [name]: value
        };
      })
    }));
  };

  handlePrevClick = e => {
    // TODO: implement your own logic so that it never goes past page 0
    e.preventDefault();
    if (this.state.pageNo === 0) return;
    this.setState(prevState => ({
      pageNo: prevState.pageNo - 1
    }));
  };
  handleNextClick = e => {
    // TODO: implement your own logic so that it never goes beyond last page
    e.preventDefault();
    if (this.state.pageNo === this.numberOfPages - 1) return;
    this.setState(prevState => ({
      pageNo: prevState.pageNo + 1
    }));
  };

  render() {
    return (
      <form>
        <label>
          Building Name:
          <input
            name="buildingName"
            value={this.state.buildingDetails[this.state.pageNo].buildingName}
            onChange={this.handleInputChange}
          />
        </label>
        <br />
        <div>
          Dummy Gender:
          <input
            type="radio"
            name="radioButtonValue"
            value="male"
            checked={
              this.state.buildingDetails[this.state.pageNo].radioButtonValue ===
              "male"
            }
            onChange={this.handleInputChange}
          />{" "}
          Male
          <input
            type="radio"
            name="radioButtonValue"
            value="female"
            checked={
              this.state.buildingDetails[this.state.pageNo].radioButtonValue ===
              "female"
            }
            onChange={this.handleInputChange}
          />{" "}
          Female
          <br />
        </div>

        <button onClick={this.handlePrevClick}>Prev</button>
        <button onClick={this.handleNextClick}>Next</button>
        <br />
        <code>{JSON.stringify(this.state)}</code>
      </form>
    );
  }
}

function App() {
  return (
    <div className="App">
      <Reservation />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Hope it helps.

Sign up to request clarification or add additional context in comments.

1 Comment

Sorry for the late response. Will try it out. Thanks a lot for your help :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.