I have a program that adds input boxes when you click a button. A new ID in HTML for that box is created when it is added. The inputs are then inserted into a string that displays at the bottom. Inputs MUST have a length of 11 characters. I simplified this code from what I am actually working on, but here is the problem:
Issue: When I add boxes and input values, it displays a string. Cool. However, when I remove a box (and make sure function getResponse() runs after), my string still displays the removed input's value. I want those values/elements to not exist after I remove the child in JavaScript. Even if I only set value to null, it still thinks the element exists and messes up my string.
What I have tried
Setting input.value to null when running the function to remove child. This is in my code below. I have also tried setting input.id to null. Doesn't work, and I'm not even sure if this is allowed in syntax in this spot. I don't think it is, apparently. Even so, only setting the value to null instead of removing the element altogether will cause issues in my string when removing the child.
Having a single button to remove the last input added instead of selective. This would work, the trouble is I'm not entirely sure how to go about it with the way my code is set up. This would be desperation, though, because I want to user to be able to selectively choose which input they remove. But if it's the only way, I could use some advice.
Removing the element as you normally do by following removing the element[count]. This wouldn't work the way I want it to since if you add 5 inputs, and the user removes the second, it will actually remove the 5th in value.
Lastly I've tried input.removeChild(li) but get an error "node to be removed is not a child of this node"
var count = 0;
let colorNumX = [];
window.createinput = function() {
var field_area = document.getElementById('fields')
var li = document.createElement("li");
var input = document.createElement("input");
input.id = 'field' count;
input.name = 'field' count;
input.type = "text";
li.appendChild(input);
field_area.appendChild(li);
//create the removal link
var removalLink = document.createElement('a');
removalLink.className = "remove";
removalLink.onclick = function() {
input.value = null;
field_area.removeChild(li);
count--;
}
removalLink.appendChild(document.createTextNode(' X Remove'));
li.appendChild(removalLink);
count ;
}
document.querySelector("#createInput").click();
document.getElementById("field0").value = "1234567890X";
function getResponse() {
var panel_date1 = document.getElementById("panelDate1").value;
for (i = 0; i <= count - 1; i ) {
colorNumX[i] = document.getElementById("field" i).value;
}
var colorString1 = colorNumX.join(', ');
if (colorString1.length > 22) {
var FPlen1 = colorString1.length;
var FPnewString1 = colorString1.substring(0, FPlen1 - 11) "and " colorString1.substring(FPlen1 - 11);
var FPbestString1 = FPnewString1.slice(0, -17) FPnewString1.slice(-17);
} else {
var FPbestString1 = colorString1;
}
var comment = "Per the number(s) " FPbestString1 " dated " panel_date1 ", this item description is redacted";
document.getElementById("commentHere").innerHTML = comment;
}
.flex-container {
display: flex;
background-color: DodgerBlue;
}
.flex-container>div {
background-color: #f1f1f1;
margin: 10px;
padding: 20px;
position: relative;
}
.close {
position: absolute;
right: 5px;
top: -15px;
opacity: 0.5;
}
.close:hover {
opacity: 1;
cursor: pointer;
color: darkred;
}
#createInput:hover {
color: navy;
opacity: 0.8;
cursor: pointer;
}
.remove {
opacity: 0.5;
}
.remove:hover {
color: darkred;
opacity: 1;
cursor: pointer;
}
<button id="addPanelDate" onclick="AddPanelClicked()">Add Panel Date</button>
<div >
<div style="display: inline-block">
<input id="panelDate1" onchange="getResponse()">Panel Date</input>
<ul onchange="getResponse()" id="fields">
</ul>
<a id="createInput" onclick="createinput()">Add Panel Number</a>
</div>
</div>
<p id="commentHere"></p>
CodePudding user response:
This answer produces what I am trying to do, after some scouring:
https://stackoverflow.com/a/14815741/14464184
console.log the matrix to see what I mean
Creates a matrix that can be worked, values removed or added, and this code actually works more efficiently. Any thoughts, feel free to add.
CodePudding user response:
New: Consider that right now in your code you are losing the reference to the specific fields you generate. Because there is no state recorded in any meaningful sense, you can't parse out which field to target based on the nested function. It's valid HTML to have unique IDs for your fields but when you go to delete them you are losing their distinct ID. Have you considered writing a separate delete function and just adding a helper method with an argument that identifies that input? Doing something like this:
removalLink.addEventListener('click', function(){
deleteInput("name" count);
});
function deleteInput(str) {
// do stuff to delete item now that you know what it is.
}
Old: Seems like it could be an issue of scope. Have you tried changing the var declarations to let when you declare the items? I'm just not confident that you're targeting what you think you are when the remove function is called.
let field_area = document.getElementById('fields')
let li = document.createElement("li");
let input = document.createElement("input");