Home > Blockchain >  How to Handle multiple radio button inputs with one onChange function handler
How to Handle multiple radio button inputs with one onChange function handler

Time:10-30

i have a scenario where based on a number(say numberOfFlags) i want to render numberOfFlags times an radio button group.Each group has two radio buttons approve and reject as per screenenter image description hereshot attached how to get values of all inputs when they change? An lastly i have to store result of all radio buttons (approve/reject) in an array and send to API

CodePudding user response:

You need to use two parameters on onChange function. One is for current index and another is for Approve/Reject. Like below code snippet

onchange = handleOnChage(index, isApproveClicked)

CodePudding user response:

You can achive this in many different ways, but I would probably simple create a state with an array of values in the parent component and pass it to each and every item to toggle its own state depending action.

App.js

export function App() {
  const [list, setList] = useState([false, false, false]);
  const updateItem = (value, index) => {
    let copyList = [...list];
    copyList[index] = !value;
    setList(copyList);
  };
  console.log(list)
  return (
    <div className="App">
      {list && (
        <>
          {list.map((value, index) => (
            <Item values={[value, index]} updateItem={updateItem} key={index "_check"} />
          ))}
        </>
      )}
    </div>
  );
}

Item.js

export default function Item({ values, updateItem }) {
  return (
    <>
      <input
        onChange={() => updateItem(values[0], values[1])}
        type="checkbox"
        checked={values[0] ? "checked" : ""}
      />
    </>
  );
}

CodePudding user response:

Presented below is one possible way to achieve the desired objective.

Code Snippet

const {useState} = React;
const Thingy = ({...props}) => {
  // num-of-flags is obtained from props
  const { numOfFlags: nf} = props || {};
  // if it is null or not above 0, return "invalid" message to parent
  if (!(nf && nf > 0)) return "invalid num-of-flags";
  // state variable to store approve/reject status
  const [statusObj, setStatusObj] = useState({});
  // JSX to render the UI & handle events
  return (
    <div>
      {([...Array(nf).keys()].map(grpIdx => (
        <div className="grpBox">
          Group num {grpIdx 1} <br/>
          <input type='radio' name={grpIdx} id={grpIdx} value={'approve'}
           onChange={() => setStatusObj({
            ...statusObj, [grpIdx]: 'approve',
           })}
          />
          <label for={grpIdx}>Approve</label>{" "}
          <input type='radio' name={grpIdx} id={grpIdx} value={'reject'}
           onChange={() => setStatusObj({
            ...statusObj, [grpIdx]: 'reject',
           })}
          />
          <label for={grpIdx}>Reject</label>
        </div>
      )))}<br/>
      <button
        onClick={() => {
          // make API call here
          // for verification, displaying an alert-message showing the status
          const displayMsg = [...Array(nf).keys()].map(
            gi => "Group num "   ( gi 1)   " : "   (gi in statusObj ? statusObj[gi] : '__')
          ).join(', ');
          alert(`Approve-Reject status is: ${JSON.stringify(displayMsg)}`);
        }}
      >
        Submit
      </button>
    </div>
  );
};

ReactDOM.render(
  <div>
    <div className="demoTitle">DEMO</div>
    <Thingy numOfFlags={5} />
  </div>,
  document.getElementById("rd")
);
.demoTitle {
  margin-bottom: 5px;
  font-size: 20px;
  text-decoration: underline;
}
.grpBox {
  margin: 5px; padding: 10px;
  border: 2px solid purple;
  width: max-content;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="rd" />

Explanation

Inline comments added to the snippet above.

PS: If you'd like to add value to stackoverflow community,

  • Related