D´n´D-TAGS v3 ASG (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 class="tag-container">
<input class="taginput" placeholder="<add a tag>" data-bind="
autoComplete: { selected: selectedOption, options: options },
textInput: tagname,
event: {keyup: inputTagASG}
"/>
<h3>Selected Tags ('sceneTags')</h3>
<div class="tag-table">
<div class="tag-list" data-bind="sortable:{template:'tagsTmpl',data:sceneTags, allowDrop:true,options:{update:$root.onUpdate}}"></div>
</div>
</div>
<!-- helper: 'clone',revert: true, -->
<br/>
<div class="tag-container">
<h3>Available Tags ('projectSceneTags')</h3>
<div class="tag-table">
<div class="tag-list" data-bind="
sortable:{template:'tagsTmpl',data:tags, allowDrop:true, options:{ update:$root.onUpdate}}"></div>
</div>
</div>
<script type="text/html" id="tagsTmpl">
<div class="tag" data-bind="css : {}">
<span class="tag-action" data-bind="
visible: !isAllocated() && source() === 'external' && sceneID !== null,
click: function(){$root.applyTagsAllocation($data)}
">+</span>
<span class="tag-action remove" data-bind="
visible: isAllocated() && source() === 'external' && sceneID !== null,
click: function(){$root.undoTagsAllocation($data)}
">x</span>
<span class="tag-action remove" data-bind="
css: {'internal': (source() === 'internal')},
visible: source() === 'internal' && sceneID !== null,
click: function(){$root.undoTagsAllocation($data)}
">x</span>
<span class="tag-text" data-bind="text: text"></span>
</div></script>
<!--
<script type="text/html" id="template-tag">
<div class="tag" data-bind="css: {selected: isSelected}">
<span class="tag-action"...
CSS
body {
font-family: arial;
}
p, a, input {
font-size: .8em;
}
.ko_container {
width: auto;
min-width: 25px;
min-height: 25px;
border: 1px dotted;
padding: 2px;
}
.tag-container {
width: 350px;
margin-top: 5px;
margin-left: 5px;
padding: 2px;
border: black 1px solid;
}
.tag-container h3 {
text-align: left;
font-weight: bold;
margin-bottom: 4px;
}
.tag-container input.taginput {
float: right;
position: relative;
background: lightyellow;
font-size: 10px;
min-width: 20px;
width: auto;
max-width: 80px;
margin: 0px 1px 2px 10px;
border: 1px solid grey;
padding: 1px;
}
.tag-table{
background-color: lightblue ;
margin: -2px;
padding: 1px;
border-radius: 0px;
}
.tag-list {
height: auto;
margin: 1px;
padding: 1px;
overflow-y: auto;
clear: both;
}
.tag {
float: left;
background-color: #444;
color: #fff;
border-radius: 3px;
margin: 1px;
padding: 2px 3px;
cursor: move;
white-space: nowrap;
}
.tag .tag-action {
display: inline-block;
/* width: 11px;
height: 11px; */
width: 0.5em;
cursor: pointer;
text-align: center;
vertical-align: middle;
font-size: 12x;
}
.tag .tag-action {
color: lime;
font-size: 11px;
font-weight:400;
}
.tag.selected .tag-action { /* Tomalak css */
color: red;
font-weight:400;
vertical-align: top;
}
.tag-action.remove { /* ASG 2015 css */
color: yellow;
font-weight:600;
}
.tag-action.remove.internal{ /* ASG 2015 css */
color: red;
font-weight:600;
}
.tag-action.textbatch { /* ASG 2015 css */
color: white;
font-weight:600;
}
/*-----------------------------------------------------------------------------------------------------------------*/
/* ASG 2015 coloring of tabs -- not implemented yet */
div.type0 .tag {
font-size: 11px;
background-color: #6797ed; /* blue-ish */
background:...
JavaScript
ko.bindingHandlers.autoComplete = {
// Only using init event because the Jquery.UI.AutoComplete widget will take care of the update callbacks
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var settings = valueAccessor();
var selectedOption = settings.selected;
var options = settings.options;
var updateElementValueWithLabel = function (event, ui) {
// Stop the default behavior
event.preventDefault();
// Update the value of the html element with the label of the activated option (ui.item)
//$(element).val(ui.item.label);
bindingContext.$root.tagname(ui.item.label);
// Update our SelectedOption observable
if(typeof ui.item !== "undefined") {
selectedOption(ui.item); // ui.item - label|value|...
}
};
$(element).autocomplete({
source: options,
select: function (event, ui) {
updateElementValueWithLabel(event, ui);
},
focus: function (event, ui) {
updateElementValueWithLabel(event, ui);
},
change: function (event, ui) {
updateElementValueWithLabel(event, ui);
}
});
}
};
//----------------------------------------- bindingHandlers above….
var Tag = function (data) {
this.ID = data.ID || -1;
this.sceneID = data.sceneID || null;
this.textbatchID = data.textbatchID || null;
this.text = ko.observable( (data.text || 'new').trim() );
this.tagType = ko.observable( data.tagType || 0 );
this.isAllocated = ko.observable(data.isAllocated);
this.source = ko.observable(data.source || 'external'); // default source is 'external', cannot be deleted!
this.isSelected = ko.observable( data.isSelected || false );
};
Tag.create = function (data) {
return new...