I know there are a lot of answers to dynamically adding/removing inputs, but I haven’t seen anything about shifting the IDs. I want to dynamically add/remove inputs with Javascript. The inputs must all have unique IDs, and if the input is removed, all the IDs must shift in place to a 1,2,3 format.
For instance, if I have:
1 = Bread
2 = Milk
3 = Cheese
And I want to remove Milk and add Apples, I should get:
1 = Bread
2 = Cheese
3 = Apples
I have tried a couple approaches, but I’m still stuck. Unfortunately, the ids are getting duplicated, and they aren’t shifting as I’d hoped. This is what I’m getting:
1 = Bread
3 = Cheese
3 = Apples
The first approach I tried was just id++ and id–, but obviously that doesn’t work because it doesn’t take into account existing ids. The next approach was putting everything into an array, then making id = index, but I seem to be having the same problem, and I’m not quite sure where to go from here.
let id = 0;
let groceryList = document.getElementById("groceryList");
var groceryItems = [];
/*Make it easier to add lots of attrs*/
function setAttributes(el, attrs){
for(var key in attrs) {
el.setAttribute(key, attrs[key]);
}
}
function addItem(){
let itemId = "item" + id;
/*Create Fieldset*/
var groceryItem = document.createElement("fieldset");
groceryItem.id = itemId;
/*Create Label*/
var inputLabel = document.createElement("label");
var labelText = document.createTextNode("Item " + id);
inputLabel.appendChild(labelText);
inputLabel.setAttribute("for", "text" + itemId);
groceryItem.appendChild(inputLabel);
/*Create Text Input*/
var textInput = document.createElement("input");
textInput.setAttribute("type", "text");
textInput.style = "display:block";
textInput.id = "text" + itemId;
groceryItem.append(textInput);
/*Create Number Label*/
var numberLabel = document.createElement("label");
var numberlabelText = document.createTextNode("Amount");
numberLabel.appendChild(numberlabelText);
numberLabel.setAttribute("for", "num" + itemId);
groceryItem.appendChild(numberLabel);
/*Create Number Input*/
var numInput = document.createElement("input");
setAttributes(numInput, {"type": "number", "min": "0", "max": "100", "value": "1"});
numInput.style = "display:block";
numInput.id = "num" + itemId;
groceryItem.append(numInput);
/*Remove Grocery Item Button*/
var removeItem = document.createElement("button");
var removeItemText = document.createTextNode("Remove " + itemId);
removeItem.appendChild(removeItemText);
removeItem.id = "remove" + itemId;
removeItem.setAttribute("type","button");
removeItem.setAttribute("onclick","remove(this.parentElement)");
groceryItem.append(removeItem);
/*Add all to form*/
groceryItems.push(groceryItem.innerHTML);
updateIDs();
let lastInArr = groceryItems.slice(-1);
var addField = document.createElement('fieldset');
addField.innerHTML = lastInArr;
groceryList.append(addField);
}
/*?????????????*/
/*Trouble Areas*/
/*?????????????*/
function remove(el){
groceryItems.splice(el,1);
groceryList.removeChild(el);
updateIDs();
}
function updateIDs(){
id=0;
for(let i = 0; i < groceryItems.length; i++){
id = i+1;
}
console.log(groceryItems);
}
Here’s my codepen.
I apologize if my code is atrocious.
NOTE This example is a simplified version of a larger goal, where I would need IDs (or some type of unique identifier) to pair labels with inputs, link inputs with range sliders, get values, display combined values, etc. From what I’ve been reading, a lot of solutions stray away from the ID approach, but I would still need to use (easily accessible) unique identifiers for the project.
Also, I would prefer pure js, but I can use jQuery if need be.
2
Answers
I would suggest that if you’re associating items to specific IDs, those IDs should remain attached to those items. Once you start reassigning IDs it gets a bit difficult to keep track of. If this where a scenario where you were reading records from a database and each record has a unique ID, if you deleted one of those records, the remaining records should not be reassigned their ID. Otherwise, you’ll run into a situation where you’re not able to find the record you were looking for, or, I suppose a situation that you’re currently involved in.
If you want to keep things ordered visually, using a simple counter like how you’re doing is fine but I would stay away from reassigning IDs to particular items.
You need to change your remove function you need to get element to update their id
Here is the javascript code