2

I am creating a knockout js custom binding that will allow me to use data-binding with bootstrap multiselect. I need it to work for single <select>'s and also multiselects <select multiple="true">. I am doing it in this jsfiddle

I have got it so that both single and multiselects can show the dropdown options and as new categories are added with the button, they show on the multiselect dropdown. I also want to update the viewmodels selectedItems which are _selectedCategory for the single <select> and '_selectedCategories' for the multiselect.

I have added some buttons into the jsfiddle to test the bootstrap multiselect elements.

How can the viewmodels _selectedCategories and _selectedCategory be updated upon selecting the DOM elements from the dropdowns?

The code is in the jsfiddle

BeniaminoBaggins
  • 11,202
  • 41
  • 152
  • 287

1 Answers1

3

I'm not sure I can get you to the point of making it work, but some pointers:

  1. DOM manipulation belongs in the binding handler. In particular, the initialization: $(this).multiselect({ goes in the init.
  2. The parameter object you pass to that initialization is what should be the bound variable for your multiselect binding. (I have no idea what _categoryID is for.) It will be what causes the update to fire. It will be what valueAccessor() returns.
  3. Although optionsText and optionsValue should have simple string arguments, value's argument should be an unquoted observable name. This is one key issue in the question you're asking.
  4. Only wrap (directly call the ko.bindingHandlers entry for) handlers that you aren't binding separately, and only when you need their binding to be part of what you're doing. You may need to wrap options, optionsText, and optionsValue instead of including them in the data-bind. But one or the other.

Update I've updated your fiddle to handle the multiselect case. I didn't find that the selectedOptions binding handler was working for me, so I had to put this in the init. This breaks the single-select case; need to special-case it.

  $(element).change(function (e) {
    var selectedOptions = ko.utils.arrayFilter(Array.from(e.target.options), function (opt) {
      return opt.selected;
    });
    var selectedValues = ko.utils.arrayMap(selectedOptions, function (opt) {
      return opt.value;
    });
    valueAccessor()(selectedValues);
  });
Roy J
  • 42,522
  • 10
  • 78
  • 102
  • Thanks, all good info. I have made some changes to the jsfiddle recently, some of them were along the lines of what you are saying. I will have a think how to implement your suggestions. There is one main problem now, displaying what the selected options are. That's really all that is not working now. Let me know if you find the solution. - the jsfiddle in the question is the new updated one. – BeniaminoBaggins Mar 11 '16 at 02:16
  • I also don't know what categoryId is. I just did it because i was copying this fiddle: http://jsfiddle.net/bkzb272j/1/ and adapting it for bootstrap multiselect – BeniaminoBaggins Mar 11 '16 at 02:18
  • Also, your show-single is calling `alertSelectedCategories` instead of `alertSelectedCategory` – Roy J Mar 11 '16 at 13:31