javascriptinputbindingselectors-api

querySelectorAll is only selecting the 1st element from the last


I'm trying to clone AngularJS with my code. What I want is the inputs of ng-models should be binded with their respective ng-bind.

Here is my html code.

<body data-ng-app="">
<input ng-model="input">
<p ng-bind="input">1st p element</p>
<p ng-bind="input">2nd p element</p>
<script src="script.js"></script>
</body>

Here is the javascript file (script.js)

'use strict';
/*jshint esversion: 6*/
/*Copyrights HEMANTH ABHIRAM SOMARAJU*/
var i = ['app', 'model', 'bind'].map(l => 'ng-' + l),

    i2 = i.map(l => 'data-' + l);

const fa = (a, b) => a.getAttribute(i[b]) || a.getAttribute(i2[b]),

    fb = (a, b = '', c = document) => c.querySelectorAll(b !== '' ? `*[${i[a]}='${b}'],*[${i2[a]}='${b}']` : `*[${i[a]}],*[${i2[a]}]`);

fb(0).forEach(a => {

    fb(1).forEach(b => {

        fb(2, fa(b, 1), a).forEach(c => b.oninput = () => c.innerText = b.value)

    })

});

What I expected from code is, whenever I give input, then that input text should be binded to the p tags (both). But it is only binding to only first one.

Sample output


Solution

  • The oninput event-handler binding is functionally wrong here :

    fb(2, fa(b, 1), a).forEach(c => b.oninput = () => c.innerText = b.value)
    

    For each of the <p> elements ( variable c ), oninput binding on the input element ( variable b ) is getting overridden. So, essentially the binding is happening for the last element in the iteration, which is the 2nd <p> element in this case.

    The binding should happen separately for each of the <p> elements, as shown below. Loop over the <p> elements as part of the oninput implementation.

    fb(0).forEach((a) => {
      fb(1).forEach((b) => {
        return (b.oninput = () => {
          fb(2, fa(b, 1), a).forEach((c) => {
            return (c.innerText = b.value);
          });
        });
      });
    });