JSFiddle - React, Tailwind, and code Playground

by Jon Kittell

HTML

<script src="http://knockoutjs.com/downloads/knockout-3.0.0.debug.js"></script>
<script>        
var folderTree = [{"Id":0,"ParentId":null,"DisplayText":"Folders","DefaultState":false}];//]]>
        </script>

<script type="text/html" id="TriStateCheckBox-Template">
		<div class="CheckBoxOuterDiv" data-bind="click: ChangeStatus, attr: { title: Title }">
			<img data-bind="css: { UncheckedCheckBox: State() == EnumState.UNCHECKED(), CheckedCheckBox: State() == EnumState.CHECKED(), IndeterminateCheckBox: State() == EnumState.INDETERMINATE() }">
			<span class="CheckBoxDisplayText" data-bind="text: DisplayText" />
		</div>
    </script>
    
	<script type="text/html" id="TriStateCheckBoxTree-Template">
		<table>
			<tr>
				<td style="width: 16px; padding: 0px;">
					<!-- <img data-bind="click: ExpandChild, css: { ExpandCheckBoxTree: !ShowChild(), CollapseCheckBoxTree: ShowChild }, visible: HasChild"> -->
				</td>
				<td style="margin: 0px; padding: 0px; text-align: left">
					<div data-bind="template: { name: 'TriStateCheckBox-Template', data: CurrentNode }" />
				</td>
			</tr>
			<tr data-bind="visible: ShowChild" >
				<td colspan="2" style="margin: 0px; padding: 0px; text-align: left">
					<div data-bind="if: HasChild">
						<ul style="list-style: none; padding-left: 20px" data-bind="template: { name: 'TriStateCheckBoxTree-Template', foreach: ChildNodes }" />
					</div>
				</td>
			</tr>
		</table>
	</script>


	<!--<input type="checkbox" disabled="disabled" data-bind="attr: { checked: $data.Checked},prop: { indeterminate: $data.Indeterminate }" />-->
	<!--    <ul data-bind="foreach: $data.ChildNodes">
				<li>
					<div data-bind="template: { name: 'TriStateCheckBoxTree-Template', data: $data.CurrentNode }" />
				</li>
			</ul>-->
</head>
<body>
	<form id="form1" runat="server">
	<h1>Select the folder(s) where you want the selected file to be copied.</h1>
	<hr />
	<div style="height: 500px; width: 500px; overflow: scroll" data-bind="template: { name:...

JavaScript

function ViewModel() {
    var self = this;
    self.NodeTree = ko.observable(new TriStateTreeNode(self, folderTree, 15, 2, null));
};

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


function isUndefined(item) {
    var result = false;
    if (typeof item === "undefined") {
        var message = "Boom: Undefined";
        Write(message);
        alert(message);
        result = true;
    }
    return result;
}


function Write() {
    var theString = arguments[0];
    for (var i = 1; i < arguments.length; i++) {
        // "gm" = RegEx options for Global search (more than one instance)
        // and for Multiline search
        var regEx = new RegExp("\\{" + (i - 1) + "\\}", "gm");
        theString = theString.replace(regEx, arguments[i]);
    }
    console.log(theString);
    return theString;
};

function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

function TriStateTreeNode(parent, cNode, displayTextLength, levelToExpand, currentLevel) {
    var self = this;
    self.CurrentNode = ko.observable(); // TriStateCheckBox
    self.ChildNodes = ko.observableArray([]);  //Array of TriStateTreeNode
    self.HasChild = ko.observable(false);
    var isExpandedChild = false;


    if (levelToExpand == null) levelToExpand = 0;
    if (currentLevel == null) currentLevel = 1;
    if (levelToExpand == 0) {
        isExpandedChild = false;
    } else if (levelToExpand < 0) {
        isExpandedChild = true;
    } else if (levelToExpand >= currentLevel) {
        isExpandedChild = true;
    } else {
        isExpandedChild = false;;
    }


    self.ShowChild = ko.observable(isExpandedChild);
    self.CurrentStatus = 0;


    self.ExpandChild = function () {
        self.ShowChild(!self.ShowChild());
    }

   ...