i have a scenario where based on a number(tenure) i want to render tenure times an input field of date type. how to get values of all inputs when they change?[these are the number of inputs based on tenure]
CodePudding user response:
Presented below is one possible way to achieve the desired objective.
Code Snippet
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
});
};
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>
</div>)}
</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" />
Explanation
Inline comments added to the snippet above.
CodePudding user response:
You can add an input element for tenure, then add input field for taking dates dynamically. For each date input you can bind 'change' event on which you can collect values of all dates. Finally add those dynamically created inputs in div with id 'container'
For e.g
<!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>