Ad

Is There A Way To Dynamically Create Nested Divs Onclick?

- 1 answer

I'm attempting to create a page where the user is able to customize the form to their needs by adding in extra divs or nested divs (as many layers deep as they'd like). Within each div I'd like to have text input and a button which adds another div on the same level and a button that nests a div within it. Both divs should again have a text input and a button which does the same thing.

However I've gotten a bit stuck. When I attempt to create a nested div I always end up adding it at the very bottom instead of inside its parent.

<html>
    <script type="text/javascript">
        var counter = 1;
        function addNode() {
            var newDiv = document.createElement('div');
            counter++;
            newDiv.innerHTML = "Entry " + counter + " <br><input type='text' name='myInputs'>";
            document.getElementById("dynamicInput").appendChild(newDiv);
            var newButton = document.createElement('button');
            newButton.type = "button";
            newButton.onclick = addSub;

            document.getElementById("dynamicInput").appendChild(newButton);
        }
        function addSub() {
            var newDiv = document.createElement('div');
            counter++;
            newDiv.innerHTML = "Entry " + counter + " <br><input type='text' name='myInputs' style='margin:10px'>";
            document.getElementById("subInput").appendChild(newDiv);
        }
    </script>
    <form class="form" method="POST">
        <div id="dynamicInput" name="dynamicInput" multiple="multiple">
            Entry 1<br><input type="text" name="myInputs">
            <div id="subInput" name="subInput" multiple="multiple">
                <input type="button" value="add nested" onClick="addSub();">
            </div>
        </div>
        <input type="button" value="Add another text input" onClick="addNode();" >
        <input type="submit" value = "answer" multiple="multiple"/>

    </form>
</html>
Ad

Answer

Here is a complete solution for you keep in mind that if you need to bind extra events on your produced inputs and buttons you ll have to do it inside the functions addNode or addSub as i did for the click event on the buttons.

Working example : https://jsfiddle.net/r70wqav7/

var counter = 1;
function addNode(element) {
	counter++;
  var new_entry="Entry "+counter+"<br><input type='text' name='myInputs'><br>";
  element.insertAdjacentHTML("beforebegin",new_entry);
}
function addSub(element) {
	counter++;
	var new_sub_entry="<div class='block'>"
  								+"Entry "+counter+"<br><input type='text' name='myInputs'><br>"
                  +"<div class='buttons'>"
                  +"<input class='add_sub_button' type='button' value='add nested'>"
                  +"<input class='add_button' type='button' value='Add another text input' >"
                  +"</div>"
                  +"</div><br />"
                  +"</div>";
  element.insertAdjacentHTML("beforebegin",new_sub_entry); 
  var blocks=element.parentNode.getElementsByClassName("block");
  blocks[blocks.length-1].getElementsByClassName("add_sub_button")[0].addEventListener("click",function(){
  	addSub(this.parentNode);
  });
  blocks[blocks.length-1].getElementsByClassName("add_button")[0].addEventListener("click",function(){
  	addNode(this.parentNode);
  });
}

var buttons=document.getElementsByClassName("add_button");
for(i=0;i<buttons.length;i++){
	buttons[i].addEventListener("click",function(){
  		addNode(this.parentNode);
  });
}
var nested_buttons=document.getElementsByClassName("add_sub_button");
for(i=0;i<buttons.length;i++){
	nested_buttons[i].addEventListener("click",function(){
  		addSub(this.parentNode);
  });
}
div.block{
  padding:5px;
  border:2px solid #000;
}
<form class="form" method="POST">
  <div class="block">
        Entry 1<br><input type="text" name="myInputs"><br>
        <div class="buttons">
          <input class="add_sub_button" type="button" value="add nested">
          <input class="add_button" type="button" value="Add another text input" >
        </div>
  </div><br />
        <input type="submit" value = "answer" multiple="multiple"/>
</form>

EDITED : There was an error binding the click event on nested items updated to work properly

Ad
source: stackoverflow.com
Ad