JSFiddle - React, Tailwind, and code Playground

by Mark

HTML

<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>
<script src="https://rawgithub.com/rniemeyer/knockout-sortable/master/build/knockout-sortable.js"></script>
<table id="sortableTable">
    <thead>
        <tr data-bind="foreach: columns">
            <th data-bind="text: $data"></th>
        </tr>
    </thead>
    <tbody data-bind="sortable: { data: rows, options: { handle: '.sortableHandle', cursor: 'move' } }">
        <tr data-bind="foreach: $data.Values">
            <td data-bind="value: $data" class="sortableHandle">	<span data-bind="text: $data"></span>

                <input type="text" style="display:none;" data-bind="value: $data" />
            </td>
        </tr>
    </tbody>
</table>
<pre id="hfResult" data-bind="text: ko.toJSON($root.rows, null, 2)"></pre>

CSS

th {
    font-weight:bold;
}
td, th {
    padding:5px;
}

JavaScript

var data = {
    "Headers": ["Header 1", "Header 2", "Header 3"],
        "List": [{
        "Values": ["Col1Item0", "Col2Item0", "Col3Item0"]
    }, {
        "Values": ["Col1Item1", "Col2Item1", "Col3Item1"]
    }, {
        "Values": ["Col1Item2", "Col2Item2", "Col3Item2"]
    }, {
        "Values": ["Col1Item3", "Col2Item3", "Col3Item3"]
    }, {
        "Values": ["Col1Item4", "Col2Item4", "Col3Item4"]
    }, {
        "Values": ["Col1Item5", "Col2Item5", "Col3Item5"]
    }]
};
var model = {
    columns: data.Headers,
    rows: ko.observableArray(data.List)
}

var onReady = function () {
    ko.applyBindings(model);

}

var fixHelper = function (e, ui) {
    ui.children().each(function () {
        $(this).width($(this).width());
    });
    return ui;
};

function saveItemOrder() {
    $('#hfResult').val(ko.toJSON(this));
}

$(document).ready(onReady);