http://stackoverflow.com/questions/42699436/knockout-js-select2-binding-broke-after-upgrading-select2-to-v4

by jlspake

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.4.3/select2.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.4.3/select2.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.1/knockout-debug.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<div>
  <select name="book_choice" id="book_selector" class="form-control input-sm"
      data-bind="
          select2: {
              value: book,
              options: function(){return {results: books(), text:'What goes here?'}},
              optionsText: bookFormat,
              optionsValue: bookFormat,
              placeholder:'-- Select Book --'
          }
      "
></select>
</div>

JavaScript

var viewModel = function(){
	var self = this;
  
  self.book = ko.observable();
  self.books = function(){ return [
    "Book1",
    "Book2",
    "Book3"
  ]};
  self.bookFormat = ko.observable("TestFormat");
}

ko.bindingHandlers.select2 = {

    init: function(el, valueAccessor, allBindingsAccessor) {

        var allBindings = allBindingsAccessor();
        var select2 = ko.utils.unwrapObservable(allBindings.select2);

        ko.utils.domNodeDisposal.addDisposeCallback(el, function() {
            $(el).select2('destroy');
        });

        $(el).select2(select2);

        // update select2 if value is set elsewhere
        select2.value.subscribe(function(newValue){
            if (newValue){
                $(el).val(newValue.id);
            }
        });

        $(el).on("select2:select", function(event){
            var allBindings = allBindingsAccessor();
            if (event.choice){
                allBindings.select2.value(event.choice);
            }
        });
    },

    update: function(el, valueAccessor, allBindings, viewModel, bindingContext) {
        var obj = valueAccessor();
        $(el).select2("data", obj.options());

        console.log(obj.options());

        if (_.contains(obj.options().results, obj.value())){
            $(el).val(obj.value().id);
        }else{
            obj.value(null);
        }

        $(el).prop('disable', !obj.options().results.length > 0);
        $(el).trigger('change');
    }
};

ko.applyBindings(new viewModel());