Requirement:
- User will enter “Number of Containers” and “Number of Controls”
- Random input elements (numeric, checkbox, etc) will be created and equally distributed among the containers
- When user clicks on “Create” again, the input elements shown in the UI will be deleted and new set of random input elements will be populated again
Issue:
Every time I create new set of input elements, the time taken for creating increases linearly up to a point then decreases little and increases again
I use the below code to empty the container and create input elements
Emptying the container div
node.innerHTML = ""
Creating a numeric control with label
function createNumber(display){
let controlWrap = document.createElement("div");
let label = document.createElement("label")
let control = document.createElement("input")
control.type = "number";
label.append("Numeric Input");
label.append(control);
controlWrap.append(label);
controlWrap.style.display = display;
controlWrap.classList.add("ctrl");
return controlWrap; }
Find the entire code below,
//Constands
const CTRL_DISPLAY_TYPE = "block"
//Selection
const numOfContainers = document.querySelector("#numOfContainers");
const numOfControls = document.querySelector("#numOfControls");
const createContainersBtn = document.querySelector("#create");
const containerWrapper = document.querySelector(".containerWrapper");
const controlHeading = document.querySelectorAll(".ctrlHeading");
//Event Listeners
createContainersBtn.addEventListener("click",createContainers);
controlHeading.forEach(element => element.addEventListener("click"),expandControl);
//Support-functions
function createControl(newControlContainer){
let newControlWrapper = document.createElement("div")
newControlWrapper.classList.add("ctrlWrapper");
let newControl = createNumber(CTRL_DISPLAY_TYPE);
newControlWrapper.appendChild(newControl);
newControlContainer.appendChild(newControlWrapper);
}
function createNumber(display){
let controlWrap = document.createElement("div");
let label = document.createElement("label")
let control = document.createElement("input")
control.type = "number";
label.append("Numeric Input");
label.append(control);
controlWrap.append(label);
controlWrap.style.display = display;
controlWrap.classList.add("ctrl");
return controlWrap;
}
function calculateControlPerContainer(numOfContainers,numOfControls,maxLimit){
let controlsPerContainer = []
let pendingControls = numOfControls%numOfContainers
let controlPerContainerNum = Math.floor(numOfControls/numOfContainers)
for (let i=0;i<numOfContainers;i++){
if (pendingControls>0){
newControlsPerContainer=controlPerContainerNum+1;
controlsPerContainer.push(newControlsPerContainer);
--pendingControls;
}
else{
controlsPerContainer.push(controlPerContainerNum);
}
}
return controlsPerContainer
}
function expandControl(event){
const control = event.currentTarget.nextElementSibling;
if (control.style.display === "none"){
control.style.display = "block";
}
else {
control.style.display = "none"
}
}
//utility-functions
function removeChild(node){
while(node.firstChild){
node.removeChild(node.firstChild);
}
}
function clearNodeData(node){
node.innerHTML = ""
}
//main-Functions
function createContainers(event){
console.time("Deleting controls");
const controlsPerContainer = calculateControlPerContainer(parseInt(numOfContainers.value),parseInt(numOfControls.value));
clearNodeData(containerWrapper);
//removeChild(containerWrapper);
console.timeEnd("Deleting controls");
console.time("populating controls");
controlsPerContainer.forEach(num=>{
let newControlContainer = document.createElement("div")
newControlContainer.classList.add("ctrlContainer");
for(let j=0;j<num;j++){
createControl(newControlContainer);
}
containerWrapper.appendChild(newControlContainer);
})
console.timeEnd("populating controls");
}
* {
box-sizing: border-box;
}
html, body {
margin: 0;
padding: 0;
border: 0;
height:100%
}
.containerWrapper{
display:flex;
flex-direction: row;
height: 90%;
}
.ctrlContainer{
/* flex-grow:1; */
flex-shrink: 0;
border-style: solid;
border-width: 0.5px;
margin:0 2px;
flex-basis: calc(25% - 4px);
align-items: stretch;
display:flex;
flex-direction: column;
overflow: auto;
}
.ctrlWrapper{
border-style: solid;
border-width: .5px;
margin:2px
}
.ctrlHeading{
display:block;
width: 100%;
text-align: left;
border: 0;
}
.ctrl{
display:none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dynamic Controls</title>
<link rel="stylesheet" href="style/main.css">
</head>
<body>
<label for="numOfContainers">Number of Containers</label>
<input type="number" id="numOfContainers" name="numOfContainers" min="1" max="500" value="100">
<label for="numOfControls">Number of Controls</label>
<input type="number" id="numOfControls" name="numOfControls" min="1" max="1500" value="1500"><br>
<button id="create">Create</button>
<div class="containerWrapper">
<!-- <div class="ctrlContainer">
<div class="ctrlWrapper">
<button class="ctrlHeading">Checkbox</button>
<input class="ctrl" type="checkbox">
</div>
<div class="ctrlWrapper">
<button class="ctrlHeading">Checkbox</button>
<input class="ctrl" type="checkbox">
</div>
</div>
<div class="ctrlContainer">2</div>
<div class="ctrlContainer">3</div> -->
</div>
<script type="module" src="scripts/MainBackup.js"></script>
</body>
</html>
I tried analyzing using chrome developer tools and could see “append” function is taking more total time. Please let me know if I am doing something wrong in deleting or adding controls.