Question

I've always used Harvest's Chosen dropdown which requires some js called to be called on a <select> item. Now, I'm rendering my select lists with Knockout.

This is the code used to transform a standard dropdown in a Chosen dropdown

$(dropdownSelectorOrElement).Chosen()

I need to know when Knockout has finished rendering the <select>, in order to call the code above: possibly, the callback function should reference the <select> itself so that I can pass without the use of selectors.

Knockout exposes the optionsAfterRender callback (documented here: see "note 2") however:

  • optionsAfterRender gets called every time an option is rendered

  • optionsAfterRender provides only a reference to the option element

I need exactly something like optionsAfterRender but called only when the entire <select> has finished rendering. Does knockout have anything like this?

I've prepared a jsfiddle which illustrates optionsAfterRender.

Was it helpful?

Solution

I've solved with this custom binding found on this question.

ko.bindingHandlers.chosen = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {

        $(element).chosen();
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var value = ko.unwrap(valueAccessor()); // - see comment
        $(element).trigger("liszt:updated");
    }
};

Note that if you don't use ko.unwrap, the update function will not fire, as it has been told to me in this question relating to this issue.

OTHER TIPS

Could also create an afterRender binding :

ko.bindingHandlers.afterRender = {
    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        allBindings.get('afterRender').call(viewModel, element);
    }
};

With this view :

<select data-bind="
options: Options,
value: selection,
optionsText: 'text',
optionsValue: 'value',
afterRender: renderCallback
"></select>
<span data-bind="text: selection"></span>

And this View model :

function viewModel() {

    this.renderCallback = function (selectElement) {
        console.log('call');
    };

    this.Options = [{
        text: "abee",
        value: "123"
    } ...
};

See fiddle

I hope it helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top