JSFiddle - React, Tailwind, and code Playground

by xdenser

HTML

<script src="https://raw.github.com/xdenser/knockout-component/master/knockout.component.js"></script>
Words:
<ul data-bind="foreach: selectedFromWords">
     <li data-bind="text: $data"></li>
 </ul>
<br>
Numbers:
<ul data-bind="foreach: selectedFromNumbers">
     <li data-bind="text: $data"></li>
 </ul>
<br>

<div data-bind="kc.doubleList:{ secondList: selectedFromWords }, kc.options: { firstList: ['foo','bar','baz'] } ">
</div>

<div data-bind="kc.doubleList: { secondList: selectedFromNumbers }, kc.options: { firstList: ['one','two','three'] }">

</div>



<script id="doubleListTemplate" type="text/html" >
     <table>
     <tr>
      <td>
     <select data-bind="options:firstList, value: selectedInFirst" multiple=true size=5>
     </select>
      </td>
     <td>
     <button data-bind="click: moveToSecond, enable: selectedInFirst" > &rarr; </button><br>
     <button data-bind="click: moveToFirst, enable: selectedInSecond" > &larr; </button>
     </td>
     <td>
     <select data-bind="options:secondList, value: selectedInSecond" multiple=true size=5>
     </select>
     </td>
     </tr>
     </table>

</script>

CSS

select { width: 100px;}

JavaScript

kc.component('doubleList','doubleListTemplate',function(options){
        var
             viewModel = {
                 firstList: ko.observableArray(options.firstList),
                 secondList: ko.observableArray(),
                 selectedInFirst: ko.observable(),
                 selectedInSecond: ko.observable(),
                 moveToSecond:function(){
                     var sel = this.selectedInFirst();
                     if(sel) {
                        this.secondList.push(this.firstList.remove(sel));
                     }
                 },
                 moveToFirst:function(){
                     var sel = this.selectedInSecond();
                     if(sel) {
                         this.firstList.push(this.secondList.remove(sel));
                     }
                 }
             };
         return viewModel;
});


 var vm = {
        selectedFromWords: ko.observableArray(),
        selectedFromNumbers: ko.observableArray()
     };

ko.applyBindings(vm);