Choices (sandbox) #CONTROLS

by whelkaholism

HTML

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/choices.min.css">
<script src="https://cdn.jsdelivr.net/npm/choices.js/public/assets/scripts/choices.min.js"></script>
<div>
<select data-bind="choices: { boundField: Choice, items: Choices, src: find, multiple: IsMultiple }">

</select>
</div>

JavaScript

(function()
{
    var _getConfig = function(el, f_valueaccessor, allbindings, viewmodel, bindingcontext)
    {
        var cfg = ko.unwrap(f_valueaccessor());

        var res = {
            obs: cfg.boundField,
            src: cfg.src,
            multiple: ko.unwrap(cfg.multiple) || false,
            options: cfg.options || {}
        };

        return res;
    };

    ko.bindingHandlers.choices = {
        init:
            function(el, f_valueaccessor, allbindings, viewmodel, bindingcontext)
            {
                var cfg = _getConfig(el, f_valueaccessor, allbindings, viewmodel, bindingcontext);
                cfg.multiple && el.setAttribute('multiple');

                var chc = new Choices(el, {
                    searchChoices: false,
                    shouldSort: false,
                    shouldSortItems: false
                });
                
                chc.setChoices(function()
                {
                    return cfg.src(chc, { initial: true, term: null });
                });
                
                cfg.__search = ko.observable().extend({ rateLimit: 300 });

								cfg.__search.subscribe(function(newval) {
                                    chc.setChoices(function() { 
                    	return new Promise(function(resolve){
                      	cfg.src(chc, { initial: false, term: newval }).then(function(data) {
                        	resolve(data);
                          
                          setTimeout(function() {chc.choiceList.element.parentElement.querySelector('input[type=search]').focus(); }, 0);
                        });
                      });
                     });

                });

                el.addEventListener('search', function(e)
                {            
                		cfg.__search(e.detail.value);
                });
            },
        update:
            function(el, f_valueaccessor, allbindings, viewmodel, bindingcontext)
            {
           ...