2

I'm using what I believe to be the generally accepted ko.bindingHandler.select2:

ko.bindingHandlers.select2 = {
  init: function (element, valueAccessor) {
      $(element).select2(valueAccessor());

      ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
          $(element).select2('destroy');
      });
  },
  update: function (element) {
      $(element).trigger('change');
  }
};

However, this seems to have a couple of issues. In this question I'd like to find an answer for how to make the View update when a change to the Model is made.

I've created a jsFiddle which demonstrates the issue. I have a simple setTimeout() function that sets the Model's selectedValue after 0.25 seconds to emulate behaviour similar to the Model loading data via an Ajax call. In the example the dropdown value is not updated when Select2 is used but appears to work just fine for a normal dropdown.

Full Solution : My updated custom binding now looks like this...

ko.bindingHandlers.select2 = {
init: function (element) {
    $(element).select2({});

    ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
        $(element).select2('destroy');
    });
},
update: function (element, valueAccessor) {
    var value = valueAccessor();
    var valueUnwrapped = ko.utils.unwrapObservable(value);
    $(element).val(valueUnwrapped).trigger('change');
}

};

In my HTML I'm now passing in the value to the custom binding.

data-bind="select2: selectedValueS2
Justin
  • 10,667
  • 15
  • 58
  • 79

1 Answers1

2

OK, seems that I was able to figure out where the issue was. If you update dropdown value when value changes and then call trigger, it will work:

$(element).val(value()).trigger('change');

http://jsfiddle.net/tkirda/Mmuvx/5/

Tomas Kirda
  • 8,347
  • 3
  • 31
  • 23
  • Not sure I understand the issue. Everything seems to work as intended. setTimeout changes values and then UI updates. – Tomas Kirda May 30 '13 at 19:59
  • 1
    Sorry, previous comment was looking at the wrong fiddle. But your fiddle is actually getting rid of the special select2 dropdown the OP was using. You didn't fix the problem, you just removed the plugin entirely. – Kyeotic May 30 '13 at 20:04
  • His fiddle contains the `select2` plugin, btw. Look under External Resources. – Kyeotic May 30 '13 at 20:06
  • The updated fiddle does not render the dropdown using the Select2 plugin? – Justin May 30 '13 at 21:04
  • Looks like it's working as you wanted now. See: http://jsfiddle.net/tkirda/Mmuvx/5/ Initialy I did not pay attention to what select2 plugin does. – Tomas Kirda May 30 '13 at 21:24
  • Hey Tomas. You seemed to have solved it. You should mention in your solution that you also modified the data-bind attribute to pass in "select2: selectedValueS2" versus the old "select2: {}". I'm not 100% certain what that does but I assume it is somehow related to the valueAccessor? Will take a look at the customBinding documation to better understand but feel free to comment. – Justin May 30 '13 at 22:08
  • I'm glad this is what you need. I just changed that binding to have access to selectedValueS2 value when it changes. Before it was passing options to select2 plugin. Can you accept the answer? Thanks! – Tomas Kirda May 30 '13 at 22:13
  • Answer accepted and I made a few changes in my description above. Main thing being I unwrap the value in case its not an observable. Seemed to be suggested by the knockout site. – Justin May 30 '13 at 22:27
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/30940/discussion-between-justin-and-tomas-kirda) – Justin May 30 '13 at 22:36