knockout.js sortable with updating array inside observable

This demo shows you how to update specific array item in observableArray using sortable

by pkysylevych

HTML

<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.2.0.js"></script>
<script src="http://cloud.github.com/downloads/rniemeyer/knockout-sortable/knockout-sortable.js"></script>
<select data-bind="options: customExportFileArray, optionsText: function(item) { 
return item.FileName }, value: selectedTemplate">
</select>
<input type="button" Value="Grab all data from specific template" data-bind="click: GrabData" />
<br/><br/>
<div>
    <div class="PopupColumn1">
      <div class="PopupColumnHeaders"><b>Conversion Types to Choose From</b></div>
        <div class="PopupListContainer">
          <ul id="chooseFromTable" class="PopupListContainerData" data-bind="sortable: { template: 'conversionTypeConvertLeftTemplate', data: selectedTemplate().ChooseFromConversionTypesSelectList} ">
          </ul>
        </div>
      </div>
    <div class="PopupArrows">
    </div>
    <div class="PopupColumn2">
      <div class="PopupColumnHeaders"><b>Include in Export</b></div>
      <div class="PopupListContainer">
        <ul id="includeInExportTable" class="PopupListContainerData" data-bind="sortable: { template: 'conversionTypeConvertRightTemplate', data: selectedTemplate().IncludeInExportConversionTypesSelectList} ">
        </ul>
      </div>
    </div>
</div>

<!--Templates-->       
<script id="conversionTypeConvertLeftTemplate" type="text/html">
  <li>
      <div data-bind="text: $data.Title"></div>
  </li>
</script>

<script id="conversionTypeConvertRightTemplate" type="text/html">
  <li>
    <div data-bind="text: $data.Title"></div>
  </li>
</script>

CSS

#wizard_tabs {
    position: absolute; margin-top: 0px; width: 766px; height: 552px; z-index: auto; /*border: 1px solid green;*/ /*margin-bottom: -10px;*/}

 div.panes .panesTab {
     height: 423px; width: 724px; border: 1px solid #dadada; border-top: none;}

    .panes .panesTab {
        background-color: #FFFFFF; display: none; font-size: 14px; padding: 0 20px; overflow: hidden;}


    ul.tabs {
        border-bottom: 1px solid #CCC; background-color: #EEEEEE; height: 44px; list-style: none outside none; padding-left: 10px;}

        ul.tabs li {
            float: left; list-style-image: none !important; margin: 0 !important; padding: 0; text-indent: 0; border-left: 1px solid #CCC;}

        ul.tabs a {
            color: #333333; display: block; font-size: 11px; padding: 15px 18px 15px 18px; position: relative; text-align: center; text-decoration: none; /*width: 134px;*/ text-shadow: 2px 2px #FFF;}

            ul.tabs a:active {outline: medium none;}

            ul.tabs a:hover {/*background-position: -420px -31px; color: #333; font-weight: bold; font-size: 11px;*/}

            ul.tabs a.current, ul.tabs a.current:hover, ul.tabs li.current a {
                background-position: -420px -62px; color: #333 !important; cursor: default !important; 
                font-weight: bold; font-size: 11px; padding-bottom: 16px; background-color: white;}

            ul.tabs a.s {background-position: -553px 0; width: 81px;}

                ul.tabs a.s:hover {background-position: -553px -31px;}

                ul.tabs a.s.current {background-position: -553px -62px;}

            ul.tabs a.l {background-position: -248px 0; /*width: 157px;*/}

                ul.tabs a.l:hover {background-position: -248px -31px;}

                ul.tabs a.l.current {background-position: -248px -62px;}

            ul.tabs a.xl {background-position: 0 0; width: 248px;}

                ul.tabs a.xl:hover {background-position: 0 -31px;}

                ul.tabs a.xl.current...

JavaScript

var AttributionCustomExport = {
    CustomExportModel: function(){
        var self = this;
        self.selectedTemplate = ko.observable();
        
        self.customExportFileArray = ko.observableArray([
          {
            "IncludeInExportConversionTypesSelectList" : ko.observableArray(
              [
                {
                  "ConversionGroupID" : "1",
                  "Title" : "Quote Start - Auto"
                },
                {
                  "ConversionGroupID" : "2",
                  "Title" : "Quote Finish - Auto"
                },
                {
                  "ConversionGroupID" : "3",
                  "Title" : "Sales Data"
                }
              ]),
            "ChooseFromConversionTypesSelectList" : ko.observableArray([]),
            "FileName" : "Template1"
          },
          {
            "IncludeInExportConversionTypesSelectList": ko.observableArray(
              [
                {
                  "ConversionGroupID" : "1",
                  "Title" : "Quote Start - Auto"
                },
                {
                  "ConversionGroupID" : "2",
                  "Title" : "Sales Data"
                }
              ]),
            "ChooseFromConversionTypesSelectList": ko.observableArray(
              [
                {
                  "Title" : "Quote Finish - Auto"
                }
              ]),
            "FileName" : "Template2"
          }
        ]);
        self.GrabData = function(){
            return alert(ko.toJSON(self.selectedTemplate));
        };
    },
    OnDocumentReady: function(){
        ko.applyBindings(new AttributionCustomExport.CustomExportModel());    
    }
}
   
AttributionCustomExport.OnDocumentReady();