knockout-sortable - simple list

https://github.com/rniemeyer/knockout-sortable

by agib

HTML

<script src="http://knockoutjs.com/downloads/knockout-2.0.0.debug.js"></script>
<script src="https://rawgithub.com/rniemeyer/knockout-sortable/master/build/knockout-sortable.js"></script>
<div id="main">
     <h3>Scripts</h3>

    <div class="container">
        <div class="item prevent">All pages - before load</div>
        <div class="inner-container" data-bind="sortable: { data: tasks, options: { cancel: '.prevent' } }">
            <div class="item" data-bind="css: { prevent: preventSort }"> <span data-bind="visible: !$root.isTaskSelected($data)">
                <div data-bind="text: name, click: $root.selectedTask"></div>
            </span>
 <span data-bind="visibleAndSelect: $root.isTaskSelected($data)">
                <input data-bind="value: name, event: { blur: $root.clearTask }" />
            </span> 
            </div>
        </div>
    </div>
    <!--<a href="#" data-bind="click: addTask">Add Task</a>-->
</div>

CSS

body {
    font-family: arial;
}
h3 {
    text-align: center;
    font-weight: bold;
}


.ko_container {
    width: 250px;
    min-height: 50px;
    background-color: #AAA;
}

.trash {
    background-color: #000;
}
.item {
    background-color: #EEE;
    color: black;
    padding: 10px 20px 10px 5px;
    border-bottom: 1px solid #BBB;
    cursor: pointer;
}
.item.prevent {
    background-color: #CCC;
    color: #777;
    font-size: 0.9em;
    padding-top: 5px;
    padding-bottom: 5px;
    cursor: default;
}
.inner-container {
    background-color: white;
}
.prevent {
    background-color: #aaa;
}
.prevent a {
    color: #666;
}

.item input {
    width: 100%;
}

#main {
    float: left;
}

JavaScript

var Task = function (name, preventSort) {
    this.name = ko.observable(name);
    this.preventSort = !! preventSort;
}

var ViewModel = function () {
    var self = this;
    self.tasks = ko.observableArray([
    new Task("All pages - after load", true),
    new Task("Script 1"),
    new Task("Script beta"),
    new Task("Cript script"),
    new Task("Page 1 - before load", true),
    new Task("Some script"),
    new Task("Another script"),
    new Task("Page 1 - after load", true),
    new Task("Ok script")]);


    self.selectedTask = ko.observable();
    self.clearTask = function (data, event) {
        if (data === self.selectedTask()) {
            self.selectedTask(null);
        }

        if (data.name() === "") {
            self.tasks.remove(data);
        }
    };
    self.addTask = function () {
        var task = new Task("new");
        self.selectedTask(task);
        self.tasks.push(task);
    };

    self.isTaskSelected = function (task) {
        return task === self.selectedTask();
    };
};

//control visibility, give element focus, and select the contents (in order)
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
        }
    }
};

ko.applyBindings(new ViewModel());