0

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

tngrj
  • 141
  • 3
  • 14
  • I made you a snippet. Please add relevant CSS and script to make it a [mcve] - where are you calling the functions? – mplungjan Jul 18 '19 at 17:33
  • It's called when the user clicks a button and triggers an on-click function which is this code ```function closeForm() { let input = document.getElementById('task').value; document.getElementById('task').value = ''; addToList(input); }``` – tngrj Jul 18 '19 at 17:41
  • The HTML code that I added was to simulate what I wanted the javascript code to create (without the div) – tngrj Jul 18 '19 at 17:43
  • Please update question with relevant code and html – mplungjan Jul 18 '19 at 18:12
  • added the necessary code, no css needed. Its giving some error though – tngrj Jul 19 '19 at 15:31

1 Answers1

0

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
}
Medet Tleukabiluly
  • 11,662
  • 3
  • 34
  • 69
  • Hi thanks for your answer. I tried it out but the i tag is not inside the span tag which makes it show up as the same image as above. I'm also trying to understand your code as when I tried to log the children it gave me an undefined value which I am not sure why. – tngrj Jul 19 '19 at 15:35