title: Bind HTML element to Javascript object and store object in array - Update object with input value from child element
body: <p>In vanilla JavaScript how can I bind an element to an object so that if a child element of the object has a value I can update the object with it? Need to be compatible with IE10+ and all other browsers.</p>
  
  <p>With a button I am dynamically adding an element (<code>createElement()</code>) containing a form input. When the element is created it also creates an object that should also be the element so I can update the object with the input value on change. </p>
  
  <p>I then store each new object in an array.</p>
  
  <p>The issue I am having is connecting the input value with the correct object. I tried looping through the array hoping to update each object in turn with the current input value of the event target but couldn't succeed. I tried registering the element (deprecated) and various other things but I cannot quite workout how to link the input to the container object (lineObject).</p>
  
  <p>I could really use some help solving this problem and understanding how to bind an element to an object in the way I need.</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>//lineNumber *** // 
  let lineNumber = document.querySelectorAll('.lineNumber');
  let numberOfLines = lineNumber.length;
  //first instance of input element
  let lineText = document.querySelector('.lineText');
  //first input value of element
  let lineTextValue = document.querySelector('input[name="lineText"]').value;
  //create initial lineObject for first line
  let lastLine = lineNumber[numberOfLines - 1];
  let lineContainer;
  
  //lineNumber object constructor
  function LineObject(lineText, writable) {
   //set properties
   this.lineText = lineText;
   this.writable = writable;
  } 
  
  //new object at new lineNumber element, set values
  let lineObject = new LineObject(lineTextValue, true);
  
  //create array containing initial line object
  let lineArray = [lineObject];
  
  //line functions
  (function lineGeneration(){
  
    //add or remove lines
    document.addEventListener('click', function(e) {
  
     //this
     let self = e.target;
  
     // has class .addLine
     if (hasClass(self, 'addLine')) {
      
      //call function to get variables
      insertLineHTML();
          
      //clone new line after the last line\
      self.parentElement.parentElement.parentElement.parentElement.parentElement.appendChild(lineObject.cloneNode(true));
  
          //lineNumber input location
          let newlineTextInput = self.parentElement.parentElement.parentElement.parentElement.nextElementSibling.querySelector('input[name="lineText"]');
      
      //input value of new element
          let lineTextValue = newlineTextInput.value;//normally "" when created unless placeholder text
      
      //new object at new lineNumber element
          lineObject = new LineObject(lineTextValue, true);
      
          //add new object to lineArray
          lineArray.push(lineObject);
      
      refreshLineNodeList();
    
     } 
  
   }); 
  
      //combine accordion / refresh
      function refreshLineNodeList(){
  
            //refresh number of elements in nodelist
            lineNumber = document.querySelectorAll('.lineNumber');
  
            //get new length
            numberOfLines = lineNumber.length; 
  
          }
  
      //line html and vars
      function insertLineHTML(){
          lineObject = document.createElement('div');
          lineObject.setAttribute('class', 'lineNumber');
          lineObject.innerHTML = ` 
              &lt;div class="accordion-title"&gt;
              &lt;h3&gt;Line 2&lt;/h3&gt;
              &lt;/div&gt;
  
              &lt;div class="input-section"&gt; 
  
              &lt;div class="input-row"&gt;
  
              &lt;div class="input-container"&gt;
              &lt;label&gt;Line 2 :&lt;/label&gt;
              &lt;input type="text" name="lineText" value="" class="lineText"&gt;
              &lt;/div&gt;
  
             
              &lt;div class="input-row"&gt;
  
              &lt;div class="button-container"&gt;
              &lt;div class="warning"&gt;&lt;/div&gt;
              &lt;button class="addLine"&gt;Add Another Line&lt;/button&gt;
  
              &lt;/div&gt;
              &lt;/div&gt;
              &lt;/div&gt;`;
          
              console.log(lineNumber);
          }
   
  })();
  
  //lineText addEventListener update object value
  document.addEventListener('keyup', function(e) {
    let self = e.target;//input field
   let lineTextValue = self.value;
   
   // has class .lineText
   if (hasClass(self, 'lineText')) {      
  
        //for each lineObject in LineArray 
         //lineArray.forEach(function(arrayObject) {
          
          //update lineObject HTMLelement.prototype
         Object.defineProperty(lineObject, 'lineText', {
     
              //update object value to event target value
           get: function() {        
                 return this.lineTextValue;//how can I get the right lineObject object from the array when I update the input  
               },
            
            set: function(lineTextValue) {
              this.lineText = lineTextValue;//how can I aet the right lineObject object in the array when I update the input
            }          
         });
          //debugging
          //console.log('objectProperty = ' + arrayObject.lineText);
          console.log('this.lineText = ' + this.lineText);  
      console.log('Object.entries(lineObject) - ' + Object.entries(lineObject));
          //console.log('lineObject.lineText = '+ lineObject.lineText);
          //console.log('lineTextValue = '+ lineTextValue);
        //});
    };
  });
  
  let button = document.getElementById('test');
  button.addEventListener( "click", testFunction );
  function testFunction(){ 
  
   button.addEventListener( "click", testFunction );
    //console.log('Object.keys(lineObject) - '+ Object.keys(lineObject));
    //console.log('Reflect.ownKeys(lineObject) - ' + Reflect.ownKeys(lineObject));
    //console.log('Object.values - ' + Object.values(lineObject));
    //console.log('lineObject = '+ lineObject.lineText);
    
    //console.log('Object.entries(lineObject) - ' + Object.entries(lineObject));
    //console.log('Object.entries(lineObjectClone) - ' + Object.entries(lineObjectClone));
    
    //console.log('lineObjectClone.lineText = ' + lineObject.lineText);
    //console.log('lineObjectClone[1].lineText = ' + lineObjectClone.lineText);
    //console.log('lineArray[0] = ' + lineArray[0].lineText);
    console.log('lineArray = ' + lineArray);
    console.log('numberOfLines = ' + numberOfLines);
    for(let i = 0; i &lt; numberOfLines; ++i ){
      console.log('lineArray[i].lineText = ' + lineArray[i].lineText)
    }
  };
  
  //does the element have the class specified?
  function hasClass(elem, className) {
        return elem.classList.contains(className);
  };
  
   </code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;section&gt;
  
    &lt;button id="test"&gt;Test&lt;/button&gt;
      
    &lt;div class="lineNumber"&gt;
    &lt;div class="accordion-title"&gt;
     &lt;h3&gt;Line&lt;/h3&gt;
     
    &lt;/div&gt;
    &lt;div class="input-section" style="display: block;"&gt; 
     &lt;div class="input-row"&gt;
  
      &lt;div class="input-container"&gt;
       &lt;label&gt;Line Text :&lt;/label&gt;
       &lt;input type="text" name="lineText" value="" class="lineText"&gt;
      &lt;/div&gt;
     &lt;/div&gt;
  
     &lt;div class="input-row"&gt;
  
      &lt;div class="button-container"&gt;
       &lt;div class="warning"&gt;&lt;/div&gt;
       &lt;button class="addLine"&gt;Add Another Line&lt;/button&gt;   
      &lt;/div&gt;
   &lt;/div&gt;
    &lt;/div&gt;
   &lt;/div&gt;
    
  &lt;/section&gt;</code></pre>
  </div>
  </div>
  </p>