'getElementByID.onchange not working after i update html with = innerHTML

My starting html looks like this:

<label> Names: </label><br>
<input type="text" class="form-control name" placeholder="name1" id="name1" name ="name1"><br>

and i have a variable that captures the html:

var html =   "<label> Names: </label><br><input type=\"text\" class=\"form-control name\" placeholder=\"name1\" id=\"name1\" name =\"name1\"><br>"

Then I have an onchange operator that performs a couple functions when the first row has text in it. the .onchange is picked up fine the first time and the subsequent functions are run. I end up with an additional row:

for (n = 1; n < inputLength+1 ; ++n) {
    var test2 = document.getElementById(dude+n);
    test2.onchange = forFunction
    }

  function forFunction() {
    for (m = 1; m < inputLength+1 ; ++m) {
      var test = document.getElementById(dude+m)
      if (test.value != "") {
        var txt = "<input type=\"text\" class=\"form-control name\" placeholder="+dude+(m+1)+" id="+dude+(m+1)+" name="+dude+(m+1)+"><br>";
        document.getElementById('group_names').innerHTML = updateHTML(txt);
        //function updateHTML(txt)
      }
    }
  }

  var html =   "<label> Names: </label><br><input type=\"text\" class=\"form-control name\" placeholder=\"name1\" id=\"name1\" name =\"name1\"><br>"
  function updateHTML(txt) {
    html = html + txt;
    return html;
  }

The issue is that after all that completes i end up with two input rows as desired: name1 and name2. However, when i enter text in those fields for a second time, the .onchange is not picked up. but the elements are there in the html when i inspect and view the html.

Also, when i

console.log(inputFormDiv.getElementsByTagName('input').length);

the length of the inputs increases from 1 to 2 after i first run functions (upon the first time i change the value in my input field) so that is getting recognized correctly, just not the .onchange.

thoughts?



Solution 1:[1]

The onchange will only work if added to the attribute on the html and the user clicks out of a textbox e.g:

<input onchange="forFunction()" type="text" class="form-control name" placeholder="name1" id="name1" name ="name1">

To add the onchange event in JavaScript code. Add the change event to the addEventListener e.g:

var test2 = document.getElementById(dude+n);
test2.addEventListener('change', forFunction, false)

However if you want the event to fire whilst the user is types a key then use the keypress event. e.g:

 var test2 = document.getElementById(dude+n);
 test2.addEventListener('keypress', forFunction, false

A basic example: https://jsfiddle.net/xrL6y012/1/

Solution 2:[2]

Instead of .innerHTML = html + text do .insertAdjacentHTML('beforeend', text), that way you keep the original html (and events binding).

Edit: https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML

Solution 3:[3]

I had the same problem, it seems like modifying the HTML will never work, regardless of how you do it (.innerHTML or .insertAdjacentHTML()).

The only way that worked for me is to append a child instead of editing the HTML, like so:

const span = document.createElement('span');
span.innerHTML = 'text and <b> html stuff </b>';
initialElement.appendChild(span);

And if you actually need to insert just pure text, then this works:

initialElement.append('just text');

Hope that helps.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 arieljuod
Solution 3