JSFiddle - React, Tailwind, and code Playground

by dzul1983

HTML

<!-- Initial data for the people observableArray -->
<div data-bind="useInitForEach: people">
    <p><span data-bind="text: firstName">John</span> <span data-bind="text: lastName">Doe</span></p>
    <p><span data-bind="text: firstName">Jane</span> <span data-bind="text: lastName">Doe</span></p>
    <p><span data-bind="text: firstName">Frank</span> <span data-bind="text: lastName">Doe</span></p>
</div>
<!-- ko foreach: people -->
<p><span data-bind="text: firstName"></span> <span data-bind="text: lastName"></span></p>
<!-- /ko -->

<p data-bind="text: ko.toJSON(people)"></p>

JavaScript

ko.bindingHandlers.useInitForEach = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext){
        var bindingProvider = ko.bindingProvider['instance'];
        var children = element.children;
        var foreachArray = [];
        
        for(var i=0;i<children.length;i++){
            var c = children[i];
            var c_children = c.getElementsByTagName('*');
            var foreachArrayObj = {};
            for(var j=0;j<c_children.length;j++){
                var child = c_children[j];
                var bindingString = bindingProvider.getBindingsString(child);
                if (!bindingString || bindingString.length === 0) {
                    continue;
                }
                var bindPropObj = ko.jsonExpressionRewriting.parseObjectLiteral(bindingString.replace(/\s+/g, ''));
                if(!bindPropObj){
                    continue;
                }

                var val;
                var bindType = bindPropObj[0].key;
                switch(bindType){ // TODO: add other type value getter
                    case 'text':
                        val = child.innerHTML;
                        break;
                }
                foreachArrayObj[bindPropObj[0].value] = val;
            }
            foreachArray.push(foreachArrayObj);
        }
        // empty observableArray and push new objects in
        valueAccessor().removeAll();
        for(var k=0;k<foreachArray.length;k++){
            valueAccessor().push(foreachArray[k]);
        }
        // remove init data element node from DOM
        element.parentNode.removeChild(element);
        
        // make sure KO doesn't bind children for this element
        return { controlsDescendantBindings: true };
    }
};

function viewModel(){
    this.people = ko.observableArray([]);
}

var viewmodel = new viewModel();
ko.applyBindings(viewmodel);