Bismo Funyuns
Bismo Funyuns

Reputation: 73

CSS formatting doesn't apply to new tags created by Javascript

I wrote a bunch of JS code to add click listeners to the HTML buttons. I have some CSS that applies to the existing HTML. But the CSS doesn't appear to apply to the HTML generated by the JavaScript.

Link to JSfiddle

As you can see, line 1 has all the proper spacing. But any of the generated lines by clicking any of the three buttons lose the spacing.

Here's the CSS:

.form-block {
  padding: 5px;
  margin: 5px;
  border: 1px solid #000;

  span {
    padding-right: 15px;
  }
}

Thanks for the help in advance! :)

Upvotes: 1

Views: 51

Answers (1)

Michael Coker
Michael Coker

Reputation: 53709

What you see are actual spaces between the elements in your original HTML/row, and then a lack of spaces between the elements in your JS generated elements.

I would either remove the spaces between the elements in your HTML, and use a left/right margin value to create that space instead, or add a space or carriage return/new line between the elements when you add them in your JS.

I removed the spaces (by inserting HTML comments) in your original HTML, and added margin-right: 1em to the input and buttons in your element row.

/*This function interprets the line position. 
//input is a lpos string which is in the form of x.x.x.x
//splits it by the '.'
//returns the array with position
*/
function lposToAr(lpos) {
  var ar = lpos.split('.');
  for (var i = 0; i < ar.length; i++) {
    ar[i] = parseInt(ar[i], 10);
  }
  return ar;
}

//This function turns the position array back into a string
function lposToStr(posAr) {
  return posAr.join('.');
}

//This function creates a new line after clicking the NL button.
function NL(lpos, e) {
  e.preventDefault();
  var cLine = document.getElementsByClassName('line')[0].cloneNode(true);
  var cNL = document.getElementsByClassName('new-line')[0].cloneNode(true);
  var cNN = document.getElementsByClassName('new-nested')[0].cloneNode(true);
  var cI = document.getElementsByClassName('input')[0].cloneNode(true);
  cI.value = '';
  var cNI = document.getElementsByClassName('new-input')[0].cloneNode(true);

  //figure out which position
  var posAr = lposToAr(lpos);
  var clickNode = document.getElementsByTagName('form')[0];
  for (var i = 0; i < posAr.length; i++) {
    clickNode = clickNode.children;
    var skipCount = 0;
    for (var j = 0; j < clickNode.length - 1; j++) {
      if (clickNode[j].tagName != 'DIV') {
        skipCount++;
      }
    }
    clickNode = clickNode[posAr[i] + skipCount - 1];
  }

  //set the last element of the posAr the total number of same level <div>+1
  var siblingDivCount = 0;
  for (var i = 0; i < clickNode.parentNode.children.length; i++) {
    if (clickNode.parentNode.children[i].tagName == 'DIV') {
      siblingDivCount++;
    }
  }
  var newPosAr = posAr;
  newPosAr[newPosAr.length - 1] = siblingDivCount + 1;

  //Update the cloned items with the new line info
  var newPosStr = lposToStr(newPosAr);
  cLine.innerHTML = newPosStr;
  cNL.addEventListener('click', function(event) {
    NL(newPosStr, event);
  });
  cNN.addEventListener('click', function(event) {
    NN(newPosStr, event);
  });
  //cI doesn't need to change, unless there's a bug
  cNI.addEventListener('click', function(event) {
    NI(newPosStr, event);
  });

  //Make the new Div
  var newDiv = document.createElement('div');
  newDiv.setAttribute('class', 'form-block');
  newDiv.appendChild(cLine);
  newDiv.appendChild(cNL);
  newDiv.appendChild(cNN);
  newDiv.appendChild(cI);
  newDiv.appendChild(cNI);

  //Add the new Div
  clickNode.parentNode.appendChild(newDiv);
}

function NN(lpos, e) {
  e.preventDefault();
  var cLine = document.getElementsByClassName('line')[0].cloneNode(true);
  var cNL = document.getElementsByClassName('new-line')[0].cloneNode(true);
  var cNN = document.getElementsByClassName('new-nested')[0].cloneNode(true);
  var cI = document.getElementsByClassName('input')[0].cloneNode(true);
  cI.value = '';
  var cNI = document.getElementsByClassName('new-input')[0].cloneNode(true);

  var posAr = lposToAr(lpos);
  var clickNode = document.getElementsByTagName('form')[0];
  for (var i = 0; i < posAr.length; i++) {
    clickNode = clickNode.children;
    var skipCount = 0;
    for (var j = 0; j < clickNode.length - 1; j++) {
      if (clickNode[j].tagName != 'DIV') {
        skipCount++;
      }
    }
    clickNode = clickNode[posAr[i] + skipCount - 1];
  }
  var childDivCount = 0;
  for (var k = 0; k < clickNode.children.length; k++) {
    if (clickNode.children[k].tagName == 'DIV') {
      childDivCount++;
    }
  }

  posAr.push(childDivCount + 1);

  //Update the cloned items with the new line info
  var newPosStr = lposToStr(posAr);
  cLine.innerHTML = newPosStr;
  cNL.addEventListener('click', function(event) {
    NL(newPosStr, event);
  });
  cNN.addEventListener('click', function(event) {
    NN(newPosStr, event);
  });
  //cI doesn't need to change, unless there's a bug
  cNI.addEventListener('click', function(event) {
    NI(newPosStr, event);
  });

  //Make the new Div
  var newDiv = document.createElement('div');
  newDiv.className = 'form-block';
  newDiv.appendChild(cLine);
  newDiv.appendChild(cNL);
  newDiv.appendChild(cNN);
  newDiv.appendChild(cI);
  newDiv.appendChild(cNI);

  //Add the new Div
  clickNode.appendChild(newDiv);
}

function NI(lpos, event) {
  event.preventDefault();
  //copy text box
  var cI = document.getElementsByClassName('input')[0].cloneNode(true);
  cI.value = '';
  //find the node that has been clicked
  var posAr = lposToAr(lpos);
  var clickNode = document.getElementsByTagName('form')[0];
  for (var i = 0; i < posAr.length; i++) {
    clickNode = clickNode.children;
    var skipCount = 0;
    for (var j = 0; j < clickNode.length - 1; j++) {
      if (clickNode[j].tagName != 'DIV') {
        skipCount++;
      }
    }
    clickNode = clickNode[posAr[i] + skipCount - 1];
  }
  //add the new textbox
  clickNode.insertBefore(cI, clickNode.getElementsByClassName('new-input')[0]);
}

document.getElementsByClassName('new-line')[0].addEventListener('click', function(event) {
  NL(document.getElementsByClassName('line')[0].innerHTML, event);
});
document.getElementsByClassName('new-nested')[0].addEventListener('click', function(event) {
  NN(document.getElementsByClassName('line')[0].innerHTML, event);
});
document.getElementsByClassName('new-input')[0].addEventListener('click', function(event) {
  NI(document.getElementsByClassName('line')[0].innerHTML, event);
});
/**
* Add styling to the form to make it look appealing
*/

.form-block {
  padding: 5px;
  margin: 5px;
  border: 1px solid #000;
}

span {
  padding-right: 15px;
}

.form-block button, .form-block input {
  margin-right: 1em;
}
<!--
DO NOT CHANGE THE CONTENTS OF THIS BLOCK
-->

<form class='myform'>
  <div class='form-block'>
    <span class='line'>1</span><!--
    --><button class='new-line'>New Line</button><!--
    --><button class='new-nested'>New Nested Line</button><!--
    --><input class='input' type='text' placeholder='Enter Value...'><!--
    --><button class='new-input'>Add input</button>
  </div>
</form>

Upvotes: 2

Related Questions