I am learning react and react forms and trying to create a dynamic and scalable form. I have set the state which has a type
and based on the type, the respective input type shows up (so it could be a text, textarea, radio, select, date or checkbox). I am trying to write a function such that it will dynamically set the on change based on the type
of the form input but i am stuck trying to achieve the same.
So if the type === select
, event.target.value
or type === checkbox
, event.target.checked
and so on.
Please check this working CodeSandbox.
Check out this Complete code snippet:-
import React from "react";
import "./styles.css";
class App extends React.Component {
state = {
Forms: [
{ name: "select", type: "select", options: ["a", "b", "c"] },
{ name: "Radio", type: "radio", options: ["a", "b", "c"] },
{ name: "Date", type: "date", value: "2018-07-22" },
{ name: "Text Input", type: "text", value: "text input" },
{
name: "Checkbox",
type: "checkbox",
options: ["a", "b", "c"],
value: false
},
{ name: "Textarea", type: "textarea", value: "text area" }
]
};
handleFormStateChange = (event, idx) => {
const target = event.target;
const form = [...this.state.forms];
form[idx].value = target.type === "select" ? target.value : "";
form[idx].value = target.type === "radio" ? target.value : "";
form[idx].value =
target.type === "date" ||
target.type === "text" ||
target.type === "textarea"
? target.value
: "";
form[idx].value = target.type === "checkbox" ? target.checked : "";
this.setState({
form
});
};
getField = field => {
switch (field.type) {
case "date":
case "text":
case "textarea":
return <input type={field.type} value={field.value} />;
case "select":
return (
<select name={field}>
{field.options.map(option => (
<option key={option} value={option}>
{option}
</option>
))}
;
</select>
);
case "radio":
case "checkbox":
return (
<div>
{field.options.map(option => (
<label>
{option}:
<input
key={option}
type={field.type}
name={option}
value={option}
/>
</label>
))}
</div>
);
default:
return <div>Unknown form field</div>;
}
};
renderForm = () => {
return this.state.Forms.map((field, index) => (
<label key={index}>
{field.name}
{this.getField(field)}
</label>
));
};
render() {
return <div>{this.renderForm()}</div>;
}
}
export default App;
I am still trying to learn and spend time with ReactJS so any help will be appreciated. Thank you so much. :)