JQuery fires event when source selection / control options change

I have a scenario where I have access to a Select (Combobox) control and I need a way to fire an event when its source / parameter list changes.

For example, if I have a select control that first has Option1 and Option2 as its options, I need a way to fire an event when the options change to Option1, Option3, Option4. I don't care if a new parameter was added, removed, or all items were added again. All I want is an event handler for when the options of the select control change.

One friend suggested changing the DOM since Option elements are added to the DOM, but I'm not sure about that since the DOM change is triggered every time any dom element on the page changes.

Update: Sorry for the confusion. I am not looking for a change of choice. I am looking for changing the actual list of options.

I am using Knockoutjs and I am binding an observable array to a select control as parameters. knockoutjs applybindings takes a few milliseconds and then sets the observable array as parameters to the Select control. I need to be bound to this change event so that I can do something based on the new set of parameters.

Before anyone says why not handle changing an observable array, I don't have access to that observable array where I have an event handler.

Update 2:

More information ...

I have a select control that has a custom binding, something like this.

 @Html.KnockOutDropDownListFor(rule => ruleTemplate.RuleReserveWordId, new List<SelectListItem>(), null,
              new {data_bind = "options: $root.RuleReserveWords, optionsText:'Name', optionsValue:'RuleReserveWordId', typeaheadCombobox: {sizeClass : 'input-mini'}" }

      

@ Html.KnockoutDropDownlIstFor is a custom ASP.NET MVC helper that I wrote to create a select control with the appropriate knockout related attributes. It will ultimately render the selected DOM control.

The select control I want should be auto-kit / typeahead comobox. And since we are using bootstrap we used the bootstrap plugin

https://github.com/danielfarrell/bootstrap-combobox

In my custom binding, I tried to call the plugin.

selectControl.customcombobox ();

The plugin basically creates input control over the select control and hides the select control. At the same time, it tries to access the options of the select control and sets as the dropdown menu for the input control when users start typing.

The problem is that I find ko.applybindings very quickly (because I think no matter where I call applybindings, after all the bindings are set, the UI will automatically update), by the time the plugin is called , the bindings are not yet linked. So the select control has no actual options. Thus, input control is irrelevant.

If I call the plugin after a few milliseconds, it works when the bindings are done by then. But its risky, if the server call took longer, everything will break again.

This is why I was looking for is there a way to find either

1) When the control selection options are updated (without binding to some of the options after binding) using jquery. There is no way for this. Some people have suggested updating the DOM, but it doesn't work for all browsers and doesn't matter.

or

2) Find a knockout way to see when the actual observable border associated with the select control is updated (RuleReserveWords in this example). This would be my preferred way.

I cannot use "update" because it is called every time the value selected in the select control changes. This is not what I want.

I have a way to update the parameters as long as I know when.

Another way I tried was this. I tried adding options to select the control before naming the plugin. The DOM renders fine, but somehow the selection is not set immediately after binding.

ko.bindingHandlers.typeaheadCombobox = {
    init: function (element, valueAccessor, allBindingsAccessor)
    {
        var valueUnwrapped = ko.utils.unwrapObservable(valueAccessor());
        var selectControl = $(element);
        var options = allBindingsAccessor().options;
        var optionsValuePropertyName = allBindingsAccessor().optionsValue;
        var optionsTextPropertyName = allBindingsAccessor().optionsText;
        //Add appropriate class for the typeahead combobox plugin to work
        selectControl.addClass('combobox');
        $.each(options(), function (index, option)
        {
            var value = null;
            var text = null;
            for (var propertyName in option)
            {
                if (propertyName)
                {
                    if (propertyName == optionsValuePropertyName)
                    {
                        value = option[propertyName];
                    }
                    else if (propertyName == optionsTextPropertyName)
                    {
                        text = option[propertyName];
                    }
                }
            }
            if (value && text)
            {
                selectControl.append('<option value=' + value() + '>' + text() + '</option>');
            }
        });
        //Call bootstrap custom combobox plugin on the select control
        selectControl.customcombobox(options());
        //Find the input control that is created by the bootstrap custom combobox plugin to set input control settings like size, style, validation attributes, etc
        var inputControl = selectControl.parent().find('input');
        inputControl.attr('name', selectControl.attr('name'));
        inputControl.attr('data-val', selectControl.attr('data-val'));
        inputControl.attr('data-val-required', selectControl.attr('data-val-required'));
        inputControl.attr('style', selectControl.attr('style'));
        if (inputControl && valueUnwrapped && valueUnwrapped.sizeClass) //Used the sizeClass instead of class itself becasue IE7 was having issues if using class or 'class' for custom bindings.
        {
            inputControl.addClass(valueUnwrapped.sizeClass);
        }        
    }

      

+3


source to share


1 answer


I'm assuming RuleReserveWords is a knockout observable array? In this case, you can subscribe to it. The subscription will be triggered when the list changes ...



viewModel.RuleReserveWords.subscribe(function() { ... list has changed here... })

      

0


source







All Articles