JSFiddle - React, Tailwind, and code Playground

JavaScript

function Template(template) {
    // Look for identifiers in the template
    var re = /:::(\w+):::/g;
    
    // Split on the identifiers. The ID will be retained because of the capture group
    var parts = template.split(re);
    
    // Here our template object will hold the MyCtor objects
    this.bindings = {};
    
    // Grab the identifiers from the parts (they're at odd indices)
    for (var i = 0; i < parts.length; i++) {
        if (i % 2 === 1) { // its an identifier
            var id = parts[i];
            // Make a temporary object holding the IDs until we make the elements.
            this.bindings[id] = {id: id, target:id + "__target__"};
            
            // Replace the ID with a span used to target the updates
            parts[i] = "<span id='" + id + "__target__'></span>";
        }
    }
    // Render the HTML with the new spans
    document.body.innerHTML = parts.join("");
    
    // Replace the temporary objects that held the IDs with MyCtor objects that coordinate the updates.
    for (var b in this.bindings) {
        this.bindings[b] = new MyCtor(this.bindings[b].id,
                                      this.bindings[b].target);
    }
}
// Provide an interface to make changes by ID
Template.prototype.change = function(prop, value) {
    this.bindings[prop].change(value);
};
// And to retrieve the value by ID
Template.prototype.getValue = function(prop) {
    return this.bindings[prop].data;
};

// This holds the data, the input, and the target Element.
// A "change" handler is added to the input.
function MyCtor(input, target) {
    this.data = "";
    this.input = document.getElementById(input);
    this.target = document.getElementById(target);
    this.input.addEventListener("change", this, false);
}
// Implement the EventListener interface
MyCtor.prototype.handleEvent = function (event) {
    switch (event.type) {
        case "change":
            this.change(this.input.value);
    }
};
// Coordinate changes to both...