Replacing Elements in an Array

Currently, I am working on a JSON/HTML generator project aimed at displaying JSON data along with the associated HTML elements for users once they input the required data into the input fields. Despite identifying the issue, I am struggling to come up with a solution. The problem stems from the fact that when attempting to generate the JSON, the values from the initial level_2_objName set are being stored and transferred to the subsequent set of level_2_objName because the ID name of that specific input is reset to level_2_objName + j. For a closer look at the console output, you can visit this link: https://i.sstatic.net/5WJdL.png. Any thoughts or suggestions on how to rectify this? I believe the fix should be implemented within the for loop inside the parseData() function.

var categoryAmount = document.getElementById('category_amount');
var generateBtn = document.getElementById('generate_btn');
var parseBtn = document.getElementById('parse_btn');
var generatedInputs = document.getElementById('generated_inputs');
var generatedJson = document.getElementById('generated_json');
var parsedContainer = document.getElementById('container_parsed-html');
var totalCategoryAmount = parseInt(categoryAmount.value);

// Arrays and objects created to store JSON data
var AllLevelsArray = [];
var level_1_name_array = [];

// Function to create input elements
function createInputs() {
var listContainer = document.createElement('div');
listContainer.className = 'list_container';

var level_1_label = document.createElement('h3');
level_1_label.textContent = 'Name of level-1 category #' + (i + 1);

var level_1_name = document.createElement('input');
level_1_name.className = 'form-control ' + 'level_1-name' + [i] + ' level_1';
level_1_name.setAttribute('placeholder', 'Level-1 name');

var level_2_list_label = document.createElement('h3');
level_2_list_label.textContent = 'How many level 2 categories for #' + (i + 1);

var level_2_list_amount = document.createElement('input');
level_2_list_amount.className = 'form-control ' + 'level_2_list_amount' + [i] + ' level_2';
level_2_list_amount.setAttribute('placeholder', 'How many level 2 categories?');
level_2_list_amount.setAttribute('id', 'level_2_list_amount' + [i])

var level_2_gen_btn = document.createElement('button');
level_2_gen_btn.className = 'btn btn-default level_2-btn';
level_2_gen_btn.textContent = 'Generate level 2';

listContainer.appendChild(level_1_label);
listContainer.appendChild(level_1_name);
listContainer.appendChild(level_2_list_label);
listContainer.appendChild(level_2_list_amount);
listContainer.appendChild(level_2_gen_btn);
generatedInputs.appendChild(listContainer);

level_1_name_array.push(level_1_name);

level_2_gen_btn.addEventListener('click', function() {

for(i = 0; i < level_2_list_amount.value; i++) {
var level_2_label = document.createElement('h4');
level_2_label.textContent = 'Info for level 2 category #' + (i + 1);

var level_2_name = document.createElement('input');
level_2_name.className = 'form-control';
level_2_name.setAttribute('id', 'level_2_name' + [i]);
level_2_name.setAttribute('placeholder', 'level 2 name');

var level_2_url = document.createElement('input');
level_2_url.className = 'form-control';
level_2_url.setAttribute('id', 'level_2_url' + [i]);
level_2_url.setAttribute('placeholder', 'level 2 url');

// var level_3 = document.createElement('input');

listContainer.appendChild(level_2_label);
listContainer.appendChild(level_2_name);
listContainer.appendChild(level_2_url);
}

this.setAttribute('disabled', 'true');
}, false)
}

function appendInputs() {
totalCategoryAmount = parseInt(categoryAmount.value)
console.log(totalCategoryAmount);

generateBtn.setAttribute('disabled', 'true');

for(i = 0; i < totalCategoryAmount; i++) {
createInputs();
}
}

function parseData() {
for(var i = 0; i < totalCategoryAmount; i++) {
var level_1_object = {};
var level_2_list = [];

var level_2_list_amount = document.getElementById('level_2_list_amount' + i);
console.log(level_2_list_amount.value);

level_1_object['level-1'] = level_1_name_array[i].value;

for(var j = 0; j < level_2_list_amount.value; j++) {
var level_2_objects = {};
var level_2_objName = document.getElementById('level_2_name' + j);
console.log(level_2_objName);
console.log(level_2_objName.value);

level_2_objects['L2-name'] = level_2_objName.value;
level_2_list.push(level_2_objects);
level_1_object['level-2-list'] = level_2_list;
}

AllLevelsArray.push(level_1_object);
}
console.log(AllLevelsArray);

generated_json.textContent = JSON.stringify(AllLevelsArray, null, 4);
}

generateBtn.addEventListener('click', appendInputs, false);
parseBtn.addEventListener('click', parseData, false);
<div class="container header">
<div class="row">
<div class="col-xs-12">
<img class="logo" src="img/nav-logo.png">
<h1>Nav Generator</h1>
</div>
</div>

<div class="row">
<div class="col-xs-6">
<h2>How it works</h2>
<ol>
<li>Enter the number of level-1 categories you will need</li>
<li>Enter the number of respective you will need for level-2 and/or level-3 categories</li>
</ol>
</div>
<div class="row">
<div class="col-xs-6 generate_container">
<form class="form-group">
<label>How many Level-1 Categories do you need?</label>
<input type="text" class="form-control" id="category_amount" placeholder="Category Amount">
<button type="button" class="btn btn-default" id="generate_btn">Generate</button>
<button type="button" class="btn btn-primary" id="parse_btn">Parse HTML</button>
</form>
</div>
</div>
</div>
</div>

<div class="container-fluid">
<div class="row">
<div class="col-xs-7" id="generated_inputs">

</div>
<div class="col-xs-5" id="generated_json">

</div>
</div>
</div>

<div class="container-fluid">
<div class="row">
<div class="col-xs-12" id="container_parsed-html">

</div>
</div>
</div>

Answer №1

The issue lies in the selection of the level 2 input fields. They are being selected based on their id:

var level_2_objName = document.getElementById('level_2_name' + j);

For each level-1, j starts at zero. It is important to note that an id must be unique throughout the entire document. Creating multiple elements with the same id goes against HTML standards. While most browsers will still accept it, selecting an id will always return the first element with that id.

Resolution There is no need to rely on ids for this issue. Instead, use css classes or the name attribute. Css classes can be used multiple times within a document, allowing you to select elements based on their class. Similarly, the name attribute allows for the use of array notation: nameOfElement[]. Avoid numbering your ids consecutively, as this is poor coding practice and often indicates a design flaw.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Magnific Popup is causing a glitch in my Ajax cart slider, preventing my code from functioning properly

Currently, I have implemented an Ajax cart slider that slides from right to left whenever an item is added to the cart. Customers are given the option to add a product with an image to their cart and can view the image directly from the cart by clicking on ...

Using asynchronous JavaScript (AJAX) to request a file to be processed on the client-side

I have a query that I need help with: My goal is to retrieve a file from the server after it has undergone input-dependent processing through an AJAX request (such as using jQuery). However, I don't want to directly offer this file for download in th ...

Adding Roles Using Discord.js - A Simple Guide

I'm currently working on a Discord bot using Discord.js, and I am trying to implement a feature where users can use a command to assign themselves a role. However, despite my best efforts, I am unable to get this functionality to work. In my bot' ...

Interactive table with Draggable feature supported by Bootstrap Vue

After tirelessly searching for a solution to drag and drop rows on a Bootstrap Vue table, I finally stumbled upon a functional version here: Codepen I attempted to integrate this code into my own table: Template: <b-table v-sortable="sortableOptions ...

Ways to retrieve information and functions from defineExpose in Vue

`I am attempting to call a method from a child component within the parent component in Vue using the composition API. I have defined the method inside defineExpose, but I am unable to access it in the parent component. Hero.vue (ChildComponent) <templ ...

Retrieving live information from an API in order to populate a specific route

Utilizing the contents of two crucial files to extract data from separate APIs, here is my simplified example: poloniex.js const Poloniex = require('poloniex-api-node') const poloniex = new Poloniex() async function obtainExchangeData() { po ...

Prevent the opening of tabs in selenium using Node.js

Currently, I am using the selenium webdriver for node.js and loading an extension. The loading of the extension goes smoothly; however, when I run my project, it directs to the desired page but immediately the extension opens a new tab with a message (Than ...

Angular displaying undefined for service

I have created a service for uploading images to a server, and I am encountering an issue when calling this service from my controller. The error message indicates that the function 'uploadFileToUrl' is undefined. Below is the code for my servic ...

I am looking to modify various attributes linked to Rails

My Desire for Reality I am looking to update multiple related values in Rails by sending an update request from JavaScript. While creating data was seamless, I encountered difficulties when attempting to update it. #Code JavaScript* export const actions ...

JQuery Keyup event is not functioning as expected

For my blog navigation, I have set up an event where pressing the 'J' key takes me to the previous post and the 'K' key takes me to the next post. However, I am facing an issue where the event works initially but stops working after the ...

What are the benefits of installing both libraries A (react-router) and B (react-router-dom) together, especially when library B relies on library A for functionality

I am currently exploring the necessity of explicitly specifying all dependencies in the packages.json file. For instance, when I want to utilize the react-router library. According to the official documentation: npm install react-router@6 react-router-d ...

Learn how to transfer and retrieve data in a different jade template using Node.js without relying on session management or query strings

I am currently facing an issue where I need to redirect and send data from one view to another in a single step using Jade templates. The code snippet below shows my attempt: customer.js var express = require('express'); var router = express.Ro ...

Identify when a click occurs outside of a text input

Whenever text is typed into the textarea, the window changes color. The goal is to have the color revert back when clicking outside the textarea. <textarea class="chat-input" id="textarea" rows="2" cols="50" ...

Validating group radio buttons that have been checked

I possess: <div class="group"> <input type="radio" name="myradio" value="1">a <input type="radio" name="myradio" value="2">b </div> <div class="group"> <input type="radio" name="two" value="3">a <input ty ...

Hide the #loading element when the <input> field is devoid of content

Sample - jsfiddle.net/75CqW/ Upon clicking the Submit button, the loading div is displayed even when the input field is empty. I attempted to add "required" to the input field to prevent the loading div from showing when it's empty, but it's st ...

Ability to access functions from required modules that are defined within the calling module

Is there a way to call a function within a required module that is defined in the main program without copying or creating separate files? Main.js: var http = require('http'); var aFunc = function() {return 1;} var bFunc = require('./bFunc ...

What is the best method for converting a string picture URL into an image and showcasing it in an image tag?

I have a URL for an image that looks like this: C:\inetpub\MaujApp\OMSAPI\ManualReceivingImages\WhatsApp Image 2021-03-24 at 12.07.41 PM.jpeg My goal is to convert the original image and display it to the user using jQuery. I woul ...

Iterate through and make changes to the JSON output

After making an API request to Google Sheets, I was presented with the following response: Array ( [0] => Array ( [Title] => Hours [January] => 1 [February] => 2 [March] => 3 ...

using the newquestion variable later in the function

In the Vue.js code snippet below, there is a variable named newQuestion that is passed to the function getAnswer like this: this.getAnswer(newQuestion). Further down in the methods section, particularly at this line getAnswer: _.debounce(, I would like to ...

How to run 'npm' scripts externally in package.json on Windows?

In the world of development, running arbitrary commands using npm run is a common practice. This involves adding a scripts hash to your package.json: "scripts": { "build-js": "browserify browser/main.js | uglifyjs -mc > static/bundle.js" } To exec ...