ASG TAGS (based on: knockout-sortable - simple list)

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

by Asle Gundersby

HTML

<script src="http://knockoutjs.com/downloads/knockout-3.2.0.js"></script>
<script src="https://rawgithub.com/rniemeyer/knockout-sortable/master/build/knockout-sortable.js"></script>
<div id="main">
    <h3>Tags</h3>
    
    <div class="container">
        <div class="item" data-bind="sortable:{template:'tagsTmpl',data:myTags, allowDrop:true"></div>
        <input class="new" data-bind="value: mytext, event: {keypress: handleKey}"/>
        <!-- Line above replacing this: <a href="#" data-bind="click: $root.addTag">Add Tag</a> -->                    
    </div>
    
    <script id="tagsTmple" type="html/text"><div>
        <a href="#" data-bind="click: $root.removeTag">x</a>
        <span data-bind="text: name>"></span>
    </div></script>
    
    <h3>Tasks</h3>
    <div class="container" data-bind="sortable: tasks">
        <div class="item" >
            <span data-bind="visible: !$root.isTaskSelected($data)">
                <a href="#" data-bind="text: name, click: $root.selectedTask"></a>
            </span>
            <span data-bind="visibleAndSelect: $root.isTaskSelected($data)">
                <input data-bind="value: name, event: { blur: $root.clearTask }" />
            </span>  
        </div>
        <input class="new" data-bind="value: mytext, event: {keypress: handleKey}"/> 
    </div>
    <a href="#" data-bind="click: addTask">Add Task</a>
</div>

<div id="results">
    <h3>Tasks</h3>
    <ul data-bind="foreach: tasks">
        <li data-bind="text: name"></li>
    </ul>
</div>

CSS

body {
    font-family: arial;
}

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

div {
    padding: 5px;
    margin: 5px;
    border: black 1px solid;
}

p, a {
    font-size: .8em;
}

ul {
    padding-bottom: 10px;
}

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

.high {
    background-color: red;
}

.trash {
    background-color: #000;
}

.item {
    background-color: #DDD;
    cursor: move;
    text-align: center;
}

.new {
    width: 100px;
}
.item input {
    width: 100px;
}

#main {
    float: left;
    width: 150px;
    margin-top: 0px;
}

#results {
    margin-left: 175px;
    width: 150px;
}

JavaScript

var Tag = function(data){
    var self = this;
    
    self.ID = data.ID;
    self.name = ko.observable(data.name);
    self.type = ko.observable(data.type);
    self.isAllocated = ko.observable(data.isAllocated);
    
    return self;
}

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

var ViewModel = function() {
    var self = this;
    self.tasks = ko.observableArray([
        new Task("Get dog food"),
        new Task("Mow lawn"),
        new Task("Fix car"),
        new Task("Fix fence"),
        new Task("Walk dog"),
        new Task("Read book")
    ]);

    // ASG 2015
    self.mytext = ko.observable("initial value");
    self.handleKey = function(data, event) {
        if (event.keyCode == 0x20) {
            console.log("Space has been pressed!");
        }
        return true;
    };
    self.myTags = ko.observableArray();
    
    var newtags = new Tag({
        ID: -1,
        name: null,
        type: 0,
        isAllocated: false
    });
    
    self.removeTag = function(tag){
       self.myTags.remove(tag);
    };
    //------------------------------------------
    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() {
               ...