javascripthtmlappendchildbulmadocumentfragment

Creating multiple elements using javascript with some element in created element


I'm trying to use javascript to create a set of elements over and over again once the user enters a text where it would display the text with a button with an image in it to the side of it but I could not find a way to do it efficiently.

The current method I was going to create would require each element to have a id tag to it so that I could call appendChild to join the elements together.

I also need to have a create element be appended into another create element which adds to the issues

This is what I'm trying to achieve in the html code (the div would not be needed to be created as it is in the html code already)

function addToList(input) {
  console.log(x);
  let task = document.createElement('p');
  task.id = x;
  task.appendChild(document.createTextNode(input));
  document.getElementById('listOfTasks').appendChild(task);
  addCheckBox(x);
  x++;
}

function addCheckBox(id) {
  let checkBox = document.createElement('a');
  checkBox.className = 'button is-rounded is-small';
  checkBox.id = 'checkBox';
  document.getElementById(id).appendChild(checkBox);

  let a = document.createElement('span');
  a.className = 'icon is-small';
  a.id = 'apple';
  document.getElementById(id).appendChild(a);

  let b = document.createElement('i');
  b.className = 'fas fa-check';
  document.getElementById(id).appendChild(b);
}
<link rel="stylesheet"   href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.min.css"/>
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
    
<div class="container">
    <div id="listOfTasks"></div>
</div>
        
<section class="section">
    <div class="container">
        <div class="field box form-popup" id="addTask">
        	<div class="control">
        		<div class="field is-grouped">
        			<label class="label"><b>Task to add</b></label>
        				    </div>
        					    <input
        							type="text"
        							class="input"
        							placeholder="Enter Task"
        							id="task"
        							required
        						/>
        					</div>
        				<button
        					type="button submit"
        					class="button is-success"
        					id="submit"
        					onclick="closeForm()"
        					>
        						Add
        	</button>
        </div>
    </div>
</section>

The current output is shown as

Would be grateful if anyone knows a better method to do this


Solution

  • Make a function that reduces boilerplate code when creating element

    function create(name, props, children) {
      let elem = document.createElement(name); // create it
      const parent = props.parent              // we use parent prop elsewhere
      let keys = Object.keys(props)            // collect keys
      keys = keys.filter(function(key) {       // remove parent prop from keys
        return key !== 'parent'
      })
      keys.forEach(function(key) {             // assign props to element
        elem.setAttribute(key, props[key])
      })
      if (children && children.length) {       // add children to element
        children.forEach(function(child) {
          elem.appendChild(child)
        })
      }
      if (parent) {                            // attach to parent
        document.getElementById(id).appendChild(elem);
      }
      return elem                              // return it, to customize further
    }
    

    And then

    function addCheckBox(id) {
      create('a', {
        id: 'checkBox',                          // simple prop
        parent: id,                              // parent prop
        class: 'button is-rounded is-small'  // simple prop
      })
      var span = create('span', {
        parent: id,
        id: 'apple',
        class: 'icon is-small'
      }, [create('i', {                      // demo of children
        class: 'fa fa-check'
      }])
      span.setAttribute('data-something', 1) // demo of customizing
    }