Choices.js – server-side search filtering

I want to use Choices JS as the UI for server side search filtering. The demo only includes loading the whole list and filtering client-side – I have too many records for that to be viable.

I have got it working except for one thing, which is that as you type, the search box loses focus, meaning its almost unusable from a UX point of view.

I have this so far (note it is wrapped in a Knockout binding and uses a timeout as a fake request):

(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 || {},
            _current: cfg.items || ko.observableArray()
        };

        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 });
                });

                el.addEventListener('search', function(e)
                {
                    console.log('search', e);
                    chc.setChoices(function() { return cfg.src(chc, { initial: false, term: e.detail.value }) });
                });
            },
        update:
            function(el, f_valueaccessor, allbindings, viewmodel, bindingcontext)
            {
            }
    };
})();

var model = new function()
{
    this.Choice = ko.observableArray();
    this.IsMultiple = ko.observable(false);

    this.find = function(sender, eargs)
    {
        return new Promise(function(resolve)
        {
            setTimeout(function()
            {
                resolve([{ value: 1, label: 'Hello' }, { value: 2, label: 'World' }]);
            }, 100);
        });
    };
};

ko.applyBindings(model);

Working Fiddle: https://jsfiddle.net/whelkaholism/5sn9wt0r/22/

UPDATE:

I have changed the search event handler to the below and it works, but it seems pretty hacky, is there a better way?

el.addEventListener('search', function(e)
                {
                    console.log('search', e, chc);
                    
                    chc.setChoices(function() { 
                        return new Promise(function(resolve){
                        cfg.src(chc, { initial: false, term: e.detail.value }).then(function(data) {
                            resolve(data);
                          
                          setTimeout(function() {chc.choiceList.element.parentElement.querySelector('input[type=search]').focus(); }, 0);
                        });
                      });
                     });
                });