JSFiddle - React, Tailwind, and code Playground

by will russell

HTML

<script src="//code.jquery.com/jquery-2.1.3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-debug.js"></script>
<script src="//raw.githubusercontent.com/Knockout-Contrib/KoGrid/master/koGrid-2.1.1.js"></script>
<div class="gridStyle">
    <div data-bind="koGrid: gridOptions"></div>
</div>
<div class="gridStyle" data-bind="foreach: items">
    <div data-bind="html: field1.value"></div>
    <div data-bind="html: field2.value"></div>
</div>

CSS

.gridStyle {
    border: 1px solid rgb(212, 212, 212);
    width: 400px;
    height: 300px;
}
/******** Grid Global ********/
 .kglabel {
    display: block;
    float: left;
    font-weight: bold;
    padding-right: 5px;
}
.kgNoSelect {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
/******** Grid ********/
 .koGrid {
    background-color: rgb(253, 253, 253);
    height: 50%;
    width: 100%;
}
/******** Header ********/
 .kgGroupPanel {
    background-color: rgb(234, 234, 234);
    overflow: hidden;
    border-bottom: 1px solid rgb(212, 212, 212);
}
.kgGroupPanelDescription {
    margin-top: 5px;
    margin-left: 5px;
}
.kgGroupList {
    list-style-type: none;
    margin: 0;
    padding: 0;
}
.kgGroupItem {
    float: left;
}
.kgGroupElement {
    float: left;
    height: 100%;
    width: 100%;
}
.kgGroupName {
    background-color: rgb(247, 247, 247);
    border: 1px solid rgb(212, 212, 212);
    padding: 3px 10px;
    float: left;
    margin-left: 0;
    margin-top: 2px;
    -moz-border-radius: 3px;
    -webkit-border-radius: 3px;
    border-radius: 3px;
    font-weight: bold;
}
.kgGroupItem:first-child {
    margin-left: 2px;
}
.kgRemoveGroup {
    width: 5px;
    float: right;
    -moz-opacity: 0.4;
    opacity: 0.4;
    margin-top: -1px;
    margin-left: 5px;
}
.kgRemoveGroup:hover {
    color: black;
    text-decoration: none;
    cursor: pointer;
    -moz-opacity: 0.7;
    opacity: 0.7;
}
.kgGroupArrow {
    width: 0;
    height: 0;
    border-top: 6px solid transparent;
    border-bottom: 6px solid transparent;
    border-left: 6px solid black;
    margin-top: 10px;
    margin-left: 5px;
    margin-right: 5px;
    float: right;
}
.kgTopPanel {
    position: relative;
    background-color: rgb(234, 234, 234);
    border-bottom: 1px solid rgb(212, 212, 212);
    z-index: 5;
}
.kgHeaderContainer {
    position: relative;
   ...

JavaScript

"use strict";

function koCompObject(value) {
	var c = {};

	c.component = {};
	c.component.viewModel = function (params) {
		var vm = {};

		//Get a reference to the passed object model.
		vm.classObject = params.objModel;

		//Pass through the observable properties of the object model.
		vm.value = vm.classObject.value;

		//These are not used by this template, but are included for completeness.
		vm.boundCssProperty = vm.classObject.boundCssProperty;
		vm.boundNameProperty = vm.classObject.boundNameProperty;
		vm.boundShowProperty = vm.classObject.boundShowProperty;

		return vm; //required for "use strict"
	}
	c.component.template = "<input type=\"text\" data-bind=\"textInput: value\" />"

	c.modelObject = function (value) {
		var m = {};

		m.boundNameProperty = ko.observable(c.componentName);
		m.boundShowProperty = ko.observable(true);
		m.value = ko.observable(value);

		m.cssList = ko.observableArray([]);

		m.boundCssProperty = ko.computed(function () {
			var s = "";
			for (var i in m.cssList()) {
				s += " " + m.cssList()[i];
			}
			return s;
		});

		return m;
	}

	c.register = function () {
		c.componentName = "koTestText";
		if (!ko.components.isRegistered(c.componentName))
			ko.components.register(c.componentName, c.component);
	}

	return c;
}

function pageViewModel() {
	var pgm = {};

	pgm.koComponent = new koCompObject();
	pgm.koComponent.register();

	pgm.items = ko.observableArray([]);

	pgm.gridOptions = {};
	pgm.gridOptions.data = ko.observableArray([]);

	pgm.items.push({ field1: new pgm.koComponent.modelObject('fresh'), field2: new pgm.koComponent.modelObject('examples') });
	pgm.items.push({ field1: new pgm.koComponent.modelObject('are hard'), field2: new pgm.koComponent.modelObject('to find') });

	pgm.gridOptions.data = pgm.items;
    
	pgm.gridOptions.columnDefs = ko.observableArray([]);
	pgm.gridOptions.columnDefs.push({
		field: "field1",
		displayName: "Field 1",
		cellTemplate: "<div data-bind=\"attr: { 'class': 'kgCellText...