如何处理这些多个表单?

huangapple go评论72阅读模式
英文:

how to handle these multiple forms?

问题

需求有点棘手。不知道该如何解释,但我会尝试。

我的网页上有20个表单,但只有一个提交按钮,它将批量提交所有表单。但不需要填写所有的表单。用户可以填写任意数量的表单,但无论他们填写哪个表单,都必须填写完整。这意味着每个表单上的所有输入都是必填的。

因此,我需要编写一个逻辑,如果在某个表单中填写了任何输入,则会使该表单中的所有输入都变为必填。我知道我可以使用onChange函数并编写一个逻辑,使一个表单中的所有input都变为必填。但我还需要在所有input字段再次被清空时移除required。我认为从输入中移除required是这里的主要复杂性。因为在添加required时,我可以简单地检查是否有任何输入字段有值(使用onChange在每个input上)。但如果我做同样的事情来移除required,我不能确定是一个输入字段被清空还是该表单中的所有输入都被清空。简而言之,我需要同步每个表单上的所有输入。

[注意1:我在React环境中,因此我可以使用state等所有功能]

[注意2:我已经为表单创建了一个React组件,并重复了20次。因此,您可以将其视为一个表单]

[注意3:这是我的一个客户项目,所以我不能更改需求]

英文:

the requirement is a bit tricky. dunno how to explain it but I'll try.

so I've 20 forms on my web page. and there's only one submit button that'll bulk-submit all the forms. but filling out all forms isn't required. the user will fill up as many forms as they like. but whichever form they fill up, must be fully filled. means all inputs are required on each form.

so I need to write a logic that'll make all the inputs required in a form if any of the input is filled there. I know I can use the onChange function and write a logic to make all the input required in one form. but I also need to remove the required from the inputs, if all the input field is again cleared. and I think removing the required from the inputs is the main complexity here. Because while adding required i can simply check if any of the inputs have value in it (using onChange on every input). but if I do the same for removing required, I can't be assured if one input field is cleared or all the inputs are cleared from that form. so in simpler words, I need to sync all the inputs on each form.

[NOTE-1: I'm in a React environment, so I've all the facilities of states and stuff]

[NOTE-2: I've made a react component for the form and looped over it 20 times. so you can think that as one form]

[NOTE-3: This is one of my client's projects. so I can't have changes to the requirements]

答案1

得分: 2

以下是您要翻译的内容:

This is a pretty "business specific" problem, but I would tackle it along these lines. You may need to make adjustments to fit your exact requirements, but the general gist is there.

The key is to treat the "required" flag for each input as "derived" or calculated state. You said "but I also need to remove the required from the inputs" - I don't think that's entirely true, or doesn't fit the react model. You just need to check if other fields are populated in the current form in the current render.

const { useState } = React;
const { render } = ReactDOM;

const forms = [
  {
    inputs: ["field1", "field2"]
  },
  {
    inputs: ["field3", "field4"]
  }
];

function MegaForm() {
  const [values, setValues] = useState(() => {
    const values = {};
    forms.forEach((form) => {
      form.inputs.forEach((input) => {
        values[input] = "";
      });
    });

    return values;
  });

  const submit = () => {
    console.log(values);
  };

  const isRequired = (formIndex) => {
    return forms[formIndex].inputs.find(
      (inputName) => values[inputName] !== ""
    );
  };

  return (
    <div>
      {forms.map((form, i) => (
        <form key={i}>
          <h2>Form {i}</h2>
          {form.inputs.map((input, j) => (
            <div key={j}>
              <label>
                {input}
                <input
                  value={values[input]}
                  onChange={(e) =>
                    setValues({ ...values, [input]: e.target.value })
                  }
                  required={isRequired(i)}
                />
                {isRequired(i) ? "*" : ""}
              </label>
            </div>
          ))}
        </form>
      ))}
      <br />
      <br />
      <button type="button" onClick={submit}>
        Submit
      </button>
    </div>
  );
}

render(<MegaForm />, document.getElementById("app"));

CodePen: https://codepen.io/chrisk7777/pen/RwYWWqV?editors=0010

英文:

This is a pretty "business specific" problem, but I would tackle it along these lines. You may need to make adjustments to fit your exact requirements, but the general gist is there.

The key is to treat the "required" flag for each input as "derived" or calculated state. You said "but I also need to remove the required from the inputs" - I don't think that's entirely true, or doesn't fit the react model. You just need to check if other fields are populated in the current form in the current render.

const { useState } = React;
const { render } = ReactDOM;
const forms = [
{
inputs: [&quot;field1&quot;, &quot;field2&quot;]
},
{
inputs: [&quot;field3&quot;, &quot;field4&quot;]
}
];
function MegaForm() {
const [values, setValues] = useState(() =&gt; {
const values = {};
forms.forEach((form) =&gt; {
form.inputs.forEach((input) =&gt; {
values[input] = &quot;&quot;;
});
});
return values;
});
const submit = () =&gt; {
console.log(values);
};
const isRequired = (formIndex) =&gt; {
return forms[formIndex].inputs.find(
(inputName) =&gt; values[inputName] !== &quot;&quot;
);
};
return (
&lt;div&gt;
{forms.map((form, i) =&gt; (
&lt;form key={i}&gt;
&lt;h2&gt;Form {i}&lt;/h2&gt;
{form.inputs.map((input, j) =&gt; (
&lt;div key={j}&gt;
&lt;label&gt;
{input}
&lt;input
value={values[input]}
onChange={(e) =&gt;
setValues({ ...values, [input]: e.target.value })
}
required={isRequired(i)}
/&gt;
{isRequired(i) ? &quot;*&quot; : &quot;&quot;}
&lt;/label&gt;
&lt;/div&gt;
))}
&lt;/form&gt;
))}
&lt;br /&gt;
&lt;br /&gt;
&lt;button type=&quot;button&quot; onClick={submit}&gt;
Submit
&lt;/button&gt;
&lt;/div&gt;
);
}
render(&lt;MegaForm /&gt;, document.getElementById(&quot;app&quot;));

CodePen: https://codepen.io/chrisk7777/pen/RwYWWqV?editors=0010

答案2

得分: 0

以下是您要翻译的代码部分:

如果您的所有表单都具有相同的字段可以使用以下解决方案

export function FormsContainer() {
  const [formData, setFormData] = React.useState({});

  function onChangeGenerator(i: number) {
    return (e) => {
      setFormData((data) => ({
        ...data,
        [i]: {
          ...data[i],
          [e.target.name]: e.target.value,
        },
      }));
    };
  }

  function fieldHasValue(value) {
    return value !== null && value !== undefined && value !== '';
  }

  function formHasValidFields(i) {
    return (
      formData[i] &&
      Object.keys(formData[i]).some((key) => fieldHasValue(formData[i][key]))
    );
  }

  function submit() {
    const result = Object.keys(formData).reduce((acc, i) => {
      if (formHasValidFields(i)) {
        acc.push(formData[i]);
      }

      return acc;
    }, []);

    console.log(result);
  }

  return (
    <form
      onSubmit={(e) => {
        e.preventDefault();
        submit();
      }}
    >
      {[0, 1, 2, 3, 4, 5].map((i) => (
        <SingleForm
          key={i}
          onChange={onChangeGenerator(i)}
          required={formHasValidFields(i)}
        />
      )}
      <br />
      <br />
      <button type="submit">Submit</button>
    </form>
  );
}


function SingleForm({
  required,
  onChange,
}: {
  required: boolean;
  onChange: (e) => void;
}) {
  return (
    <React.Fragment>
      <hr />
      <input name="prop1" onChange={onChange} required={required} />
      <input name="prop2" onChange={onChange} required={required} />
    </React.Fragment>
  );
}

希望这对您有所帮助。

英文:

If you have all the forms with the same fields you could go with a solution like this:

export function FormsContainer() {
const [formData, setFormData] = React.useState({});
function onChangeGenerator(i: number) {
return (e) =&gt; {
setFormData((data) =&gt; ({
...data,
[i]: {
...data[i],
[e.target.name]: e.target.value,
},
}));
};
}
function fieldHasValue(value) {
return value !== null &amp;&amp; value !== undefined &amp;&amp; value !== &#39;&#39;;
}
function formHasValidFields(i) {
return (
formData[i] &amp;&amp;
Object.keys(formData[i]).some((key) =&gt; fieldHasValue(formData[i][key]))
);
}
function submit() {
const result = Object.keys(formData).reduce((acc, i) =&gt; {
if (formHasValidFields(i)) {
acc.push(formData[i]);
}
return acc;
}, []);
console.log(result);
}
return (
&lt;form
onSubmit={(e) =&gt; {
e.preventDefault();
submit();
}}
&gt;
{[0, 1, 2, 3, 4, 5].map((i) =&gt; (
&lt;SingleForm
key={i}
onChange={onChangeGenerator(i)}
required={formHasValidFields(i)}
/&gt;
))}
&lt;br /&gt;
&lt;br /&gt;
&lt;button type=&quot;submit&quot;&gt;Submit&lt;/button&gt;
&lt;/form&gt;
);
}
function SingleForm({
required,
onChange,
}: {
required: boolean;
onChange: (e) =&gt; void;
}) {
return (
&lt;React.Fragment&gt;
&lt;hr /&gt;
&lt;input name=&quot;prop1&quot; onChange={onChange} required={required} /&gt;
&lt;input name=&quot;prop2&quot; onChange={onChange} required={required} /&gt;
&lt;/React.Fragment&gt;
);
}

StackBlitz: https://stackblitz.com/edit/react-ts-utrgbj

huangapple
  • 本文由 发表于 2023年2月18日 18:56:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75492842.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定