【问题标题】:Handle multiple inputs with one onChange function handler使用一个 onChange 函数处理程序处理多个输入
【发布时间】:2022-11-10 00:03:24
【问题描述】:

我有一个场景,基于一个数字(任期)我想呈现任期时间日期类型的输入字段。 当所有输入发生变化时如何获取它们的值?[这些是基于任期的输入数量]

【问题讨论】:

  • 您有任何代码来显示您尝试过的内容吗?您可以查看 formik.org 以获取 reactjs 中的表单。

标签: javascript reactjs


【解决方案1】:

下面介绍的是实现预期目标的一种可能方式。

代码片段

const {useState, useEffect} = React;
const Thingy = ({...props}) => {
  // state to hold tenure (number) input from user
  const [tenure, setTenure] = useState(null);
  // state to hold tenure-dates (array of varying size)
  const [tnDates, setTnDates] = useState(null);

  // update tenure when user input changes
  const handleTenureChange = ev => setTenure(ev.target.value);
  
  // when 'tenure' gets updated, update the tenure-dates array
  useEffect(() => setTnDates(
    (tenure && tenure > 0)
      ? ( [...Array(+tenure).keys()].map(
        id => ({id, tenureDate: ''})
      )) : null
  ), [tenure]);
  
  // when user inputs a particular date, accept the input 
  // and update the specific element in the array
  const handleDateChange = ev => {
    const idx = ev.target.id;       // to access specific array element
    const val = ev.target.value;    // to access the date-value selected by user
    setTnDates(prev => {            // "prev" is the current array
      const nd = [...prev];         // shallow-copy "prev" into "nd" (new-data) array
      nd[idx].tenureDate = val;     // update the "tenureDate" at position "idx"
      return nd;                    // return the updated "nd" array to store into state
    });
  };
  
  // clear all fields
  const clearAllFields = () => setTenure(0);

  return (
    <div>
      <label>Tenure: </label>
      <input type='number' value={tenure}
        onChange={handleTenureChange}
      />
      {tenure && tenure > 0 ? (<div style={{ margin: '10px 0' }}>
        Select dates
        <div
          style={{
            display: 'flex', flexDirection: 'column',
            width: '45%', marginTop: '10px'
          }}
        >{tnDates &&
          Array.isArray(tnDates) &&
          tnDates.length > 0 &&
          tnDates.map(
            ({id, tenureDate}) => (
              <input
                style={{ margin: '5px 0'}}
                key={id} id={id} type="date"
                value={tenureDate}
                onChange={handleDateChange}
              />
            )
        )}</div>
        <div style={{ marginTop: '10px' }}>
          Place buttons for futher processing here...
        </div>
        {tenure && tenure > 0 && tnDates && Array.isArray(tnDates) && (
          <div style={{ margin: '5px 0'}}>
            <button onClick={clearAllFields}>Clear All Fields</button>
          </div>
        )}
      </div>) : null}
    </div>
  );
};

ReactDOM.render(
  <div>
    <h3>DEMO</h3>
    <Thingy />
  </div>,
  document.getElementById("rd")
);
<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" />

解释

内联 cmets 添加到上面的 sn -p 中。

编辑(10 月 29 日):

对单选按钮做同样的事情。请帮助

const {useState, useEffect} = React;
const Thingy = ({...props}) => {
  // state to hold tenure (number) input from user
  const [tenure, setTenure] = useState(null);
  const [selectedRadio, setSelectedRadio] = useState(-1);

  // update tenure when user input changes
  const handleTenureChange = ev => setTenure(ev.target.value);
  
  // clear selection
  const selectNone = () => setSelectedRadio(-1);
  
  // clear all fields
  const clearAllFields = () => (setSelectedRadio(-1), setTenure(0));

  return (
    <div>
      <label>Tenure: </label>
      <input type='number' value={tenure}
        onChange={handleTenureChange}
      />
      {tenure && tenure > 0 ? (<div style={{ margin: '10px 0' }}>
        Radio Button Options
        <div
          style={{
            display: 'flex', flexDirection: 'column',
            width: '45%', marginTop: '10px'
          }}
        >{tenure && tenure > 0 &&
          [...Array(+tenure).keys()].map(
            id => (
            <div>
              <input
                style={{ margin: '5px 0'}}
                key={id} id={id} type="radio"
                name={'groupName'} value={id}
                checked={id === selectedRadio}
                onChange={() => setSelectedRadio(id)}
              />
              <label for={id}>Radio Option Label {id+1}</label>
            </div>
            )
        )}<br/><br/>{
          (selectedRadio >= 0) && 
          `Selection Option is: Radio Option Label ${+selectedRadio+1}`
        }
        </div>
        
        <div style={{ marginTop: '10px' }}>
          Place buttons for futher processing here...
        </div><br/>
        {tenure && tenure > 0 && (
          <div style={{ margin: '5px 0'}}>
            <button onClick={selectNone}>Clear Selection</button>{" "}
            <button onClick={clearAllFields}>Clear All Fields</button>
          </div>
        )}
      </div>) : null}
    </div>
  );
};

ReactDOM.render(
  <div>
    <h3>DEMO</h3>
    <Thingy />
  </div>,
  document.getElementById("rd")
);
<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" />

【讨论】:

  • 如何在单击一次按钮时清除所有字段
  • 添加按钮以在任期高于 0 时清除所有字段。单击一次,任期将设置为零,并清除所有日期。
  • 嗨,我不能对单选按钮做同样的事情。请帮助
  • @RohitRai,您可能想发布一个新问题,其中包含确切的细节以及您已经完成的当前进度。它将帮助其他成员也进行审查和支持。
【解决方案2】:

您可以为任期添加输入元素,然后添加输入字段以动态获取日期。对于每个日期输入,您可以绑定“更改”事件,您可以在该事件上收集所有日期的值。最后将这些动态创建的输入添加到 id 为“容器”的 div 中

例如

<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <input type="number" onchange="tenureChange(this.value)" />
    <div id="container"></div>

    <script type="text/javascript">
      function tenureChange(value) {
        let n = value || 0;
        n = parseInt(n);

        let inputsArray = [];
        for (let i = 0; i < n; i++) {
          const input = document.createElement("input");
          input.type = "date";
          input.classList.add("date-input");
          input.addEventListener("change", () => {
            const inputs = document.querySelectorAll(".date-input");
            inputs.forEach((input) => console.log(input.value));
          });
          inputsArray.push(input);
        }
        document.getElementById("container").replaceChildren(...inputsArray);
      }
    </script>
  </body>
</html>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-28
    • 1970-01-01
    • 2015-05-19
    • 1970-01-01
    • 1970-01-01
    • 2019-05-31
    • 2021-09-09
    相关资源
    最近更新 更多