JSFiddle - React, Tailwind, and code Playground

by Steve Fortner

HTML

<script src="http://cloud.github.com/downloads/rniemeyer/knockout-sortable/knockout-sortable.min.js"></script>
<script src="http://knockoutjs.com/downloads/knockout-3.2.0.js"></script>
Sortable:
<div class="container" data-bind="sortable: {data: posts, afterMove: changeTime} ">
    <div class="item">
        <span data-bind="text: time"></span>
        -
        <span data-bind="text: title"></span>
    </div>
</div>
<hr/>
Observable with foreach:
<br/>
<div class="viewer">
    <ul data-bind="foreach: posts">
        <li>
            <span data-bind="text: time"></span>
            -
            <span data-bind="text: title"></span>
        </li>
    </ul>
</div>
<hr/>
Values to JSON:
<button id="print" data-bind="click: printValues">Print</button>
<div id="result">
</div>

CSS

.item{

    display: block; 
    background: #C0C0C0; 
    margin-bottom: 5px;
    width: 200px;
}

.container {
    margin: 20px;
    padding: 5px;
    border: 1px solid black;
    width: 200px;        
}

JavaScript

var Post = function( time, title) {
    this.time = ko.observable( time );
    this.title = ko.observable( title );
};


function GridModel(){
    
    var self = this;
    
    posts = [
        {time: "07:00", title: "test#1"},
        {time: "08:00", title: "work#2"},     
        {time: "09:00", title: "task#3"},    
        {time: "10:00", title: "sleep#4"}
    ];
    
    self.posts = ko.observableArray( ko.utils.arrayMap( posts , function( post ) {
            return new Post( post.time, post.title);
    }));
    
    self.times = ko.observableArray(["07:00","08:00","09:00","10:00"]);
    
    self.selectedPost = ko.observable();
    
    self.clearPost = function(data, event) {
        if (data === self.selectedPost()) {
            self.selectedPost(null);                
        }

        if (data.name() === "") {
           self.posts.remove(data);   
        }
    }

    self.isPostSelected = function(post) {
       return post === self.selectedPost();  
    }

   
    self.changeTime = function(arg){
        
        var count = 0;
        
        ko.utils.arrayForEach(self.posts(), function(post) {
            post.time(self.times()[count]);
            count++;
        });
        
    }
        
    self.printValues = function(){
        var values = ko.toJSON(self.posts);
        $("#result").html(values);            
    }
        
}
    
ko.bindingHandlers.visibleAndSelect = {
    update: function(element, valueAccessor) {
        ko.bindingHandlers.visible.update(element, valueAccessor);
        if (valueAccessor()) {
            setTimeout(function() {
                $(element).find("input").focus().select();
            }, 0); //new tasks are not in DOM yet
        }
    }
};
    

var Grid_Model = new GridModel();
ko.applyBindings(Grid_Model);

//ko.bindingHandlers.sortable.afterMove = Grid_Model.changeTime;

$(document).ready(function(){

});