0

I'd like to insert a block of HTML into the DOM when a checkbox or radio button or button is pressed. For example, when a button is pressed, then another set of the labels and inputs below are added to the form.

<form class="details">
<div>
  <label for="fname">First name:</label><br>
  <input type="text" id="fname" name="fname"><br>
  <label for="lname">Last name:</label><br>
  <input type="text" id="lname" name="lname">

  <label for="job">Job:</label><br>
  <input type="text" id="job" name="job"><br>
  <label for="id">ID:</label><br>
  <input type="text" id="id" name="id">

  <label for="shoesize">Shoe size:</label><br>
  <input type="text" id="shoesize" name="shoesize"><br>
  <label for="helmetsize">Helmet size:</label><br>
  <input type="text" id="helmetsize" name="helmetsize">
</div>
</form>

Every time a button is pressed I'd like another set of fields where someone else can add their details to the form.

I am aware of document.createElement(), but it seems like I can only create 1 element at a time using that. This form will probably grow and so would like something less verbose.

I've experimented with appendChild() e.g.

var details = document.getElementsByClassName('details')[0]

var newDetailsSection = '<div>
  <label for="fname">First name:</label><br>
  <input type="text" id="fname" name="fname"><br>
  <label for="lname">Last name:</label><br>
  <input type="text" id="lname" name="lname">

  <label for="job">Job:</label><br>
  <input type="text" id="job" name="job"><br>
  <label for="id">ID:</label><br>
  <input type="text" id="id" name="id">

  <label for="shoesize">Shoe size:</label><br>
  <input type="text" id="shoesize" name="shoesize"><br>
  <label for="helmetsize">Helmet size:</label><br>
  <input type="text" id="helmetsize" name="helmetsize">
</div>'

details.appendChild(newDetailsSection)

But I am getting an error because newDetailsSection is not of type Node - it is a string and I understand that.

I am new to web development.

Is this a use case for a JS framework that handles components? Is this what a component is?

Ambassador Kosh
  • 459
  • 5
  • 19
  • for this case try `details.innerHTML = newDetailsSection;` – Reporter Mar 11 '22 at 12:15
  • That is replacing the current HTML with the HTML in `newDetailsSection`, I'd like to append more questions to the form. – Ambassador Kosh Mar 11 '22 at 12:32
  • 1
    if you want to append html to the innerHtml of an element you can use the += operator... like details.innerHTML += newDetailsSection; Otherwise you could rely on JQuery that let's you create entire html nodes from html string or rely on vanilla js suggestions like given here: https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro – Diego D Mar 11 '22 at 12:35
  • I'm not using `innerHTML` method because [it disrupts `eventListeners`](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML). After HTML is inserted, none of the `eventListeners` work. then tried `insertAdjacentHTML` because this doesn't disrupt `eventListeners`, but the new elements inserted don't seem to work with the existing `eventListeners`. Now trying DOM functions.. – Ambassador Kosh Mar 12 '22 at 15:44

1 Answers1

1

if u want to add html string; innerHTML is your friend.

to append use details.innerHtML = details.innerHtML + newSectionHTML;

ofcourse i would recommend using document.createElement and create a function that returns element that contain label:

example:

function creatInput(name, label){
const labelElm = document.createElement('label');
const inputElm = document.createElement('input');

labelElm.setAttribute('for', name);
labelElm.innerText = label+':';

inputElm.setAttribute('name', name);
inputElm.setAttribute('id', name);
inputElm.setAttribute('placeholder', label);

labelElm.appendChild(input);

return labelElm;
}

this way you can reuse it for all your input simply call:

var details = document.querySelector(".details");

details.appendChild( createInput('fname','First name') );
details.appendChild( createInput('lname','Last name') );
/// .. etc
Zalaboza
  • 8,899
  • 16
  • 77
  • 142