So I made a button that creates an input placeholder every time it is clicked (limited to 4). The problem is, I am using post method, and doing .value in my code returns a TypeError, but not the default placeholders (eg: m1k1). The IDs are created, and they're similar to the default with the exception of a number that is generated in a for loop.
When I type in values in just the default placeholders, everything is fine.
Two elements
let m1k1 = document.querySelector('#mon1wk1')
let m1k2 = document.querySelector('#mon1wk2')
eventListener
let num = 1
function addWeek(e) {
e.preventDefault()
num
let mkInput = document.createElement('input')
let forma = document.querySelector('#forma')
mkInput.placeholder = " "
mkInput.id = 'mon1wk' num
mkInput.type = 'text'
forma.append(mkInput)
if (num === 4) {
addwk1.disabled = true;
Where values get stored into an object
pushMonths.firstMonth.Week1 = m1k1.value,
pushMonths.firstMonth.Week2 = m1k2.value,
Any help is appreciated
CodePudding user response:
In the OP code the num
equals 1, so when the id is assigned to a new <input>
when the user clicks the <button>
, the first <input>
is assigned id="mon1wk1"
and the second <input>
is assigned id="mon1wk2"
. So now there's 2 pairs of <input>
sharing the same id
which is invalid plus the duplicates cannot be found by id
since the browser quits searching as soon as it finds the first id
, which explains why the static <input>
s always worked.
In the example below, the object follows the following pattern:
Figure I
const obj = {
mw: [2, 1], // [2nd month, 1st week]
mon1: { // Each mon* object can have up to 4 wk* properties
wk1: mon1wk1.value,
⇓⇓⇓
wk4: mon1wk4.value
},
mon2: {
wk1: mon2wk1.value
}
};
Details are commented in example
// Reference <form>
const frm = document.forms.forma;
/**
* @param {object} obj - Used to keep data
* @param {array} obj.mw - Keeps count of current
* month at mw[0] and week at mw[1]
* @param {object} obj.mon* - Month holds 4 weeks
* @param {any} obj.wk* - Week holds associated
* <input> value
*/
const obj = {
mw: [1, 2],
mon1: {
wk1: 5,
wk2: 4
}
};
let m = obj.mw[0];
let w = obj.mw[1];
// Bind submit event to <form>
frm.onsubmit = addWeek;
function addWeek(e) {
// Stop <form> from killing page
e.preventDefault();
// Build new <input>
let mk = document.createElement('input');
mk.type = 'text';
frm.append(mk);
/*
Incerment 'w'
If 'w' is greater than 4...
...add a new 'mon*' object and assign it a new
'w'
*//*
Otherwise assign a new property to current 'mon*'
Assign id to new <input> with this pattern:
`mon${m}wk${w}`
*/
w;
if (w > 4) {
m;
w = 1;
obj['mon' m] = {
['wk' w]: 0
};
obj.mw[0] = m;
obj.mw[1] = 1;
} else {
obj['mon' m]['wk' w] = 0;
obj.mw[1] = 1;
}
mk.id = 'mon' m 'wk' w;
console.log(obj);
}
// Bind input event to <form>
frm.oninput = saveData;
/*
When a user inputs a value into an <input>, assign
the value to the associated property of obj.
The value is coerced into a number: mk.value
Remove the ' ' if you want string instead.
*/
function saveData(e) {
const mk = e.target;
let id = mk.id;
obj[id.slice(0, 4)][id.slice(4)] = mk.value;
console.log(obj);
}
form {
display: flex;
}
button,
input {
display: inline-block;
}
<form id='forma'>
<button id='addWk'>Add Week</button><br><hr>
<input id='mon1wk1' value='5'>
<input id='mon1wk2' value='4'>
</form>