سؤال

To begin with, here's a fiddle that shows my point.

I have a simple form with a select field. At first I have pre-loaded only one option that is chosen and I want to load the rest of the options on clicking on the select field. That works fine except for the fact that right on loading these options into the observableArray of options, the 'Choose' default option-caption is taken even though I save the choice before loading and then I try to restore it.

The script is like

(function() {

    function COption(id, name) {
        this.ID = id;
        this.Name = name;
    }

    var Options = {
        List: ko.observableArray([
            new COption(1, "opt1")
        ]),
        Loaded: false
    }

    var Choice = ko.observable(1);

    function LoadOptions() {
        var opts = [
            new COption(1, "opt1"),
            new COption(2, "opt2"),
            new COption(3, "opt3")
        ];
        // Save current select state
        var currentChoice = Choice();
        console.log("the choice from before load is " + currentChoice);

        // Prevent loading on each click
        if (!Options.Loaded) {
        // Act as if it was an ajax request
            window.setTimeout(function() {
                Options.List(opts);
                Options.Loaded = true;
                // Bring back the state from beforeload
                Choice(currentChoice);
            }, 100);
        }
    }

    function ChangeOption() {

        var index = 1;
        if (Options.List()[index]) {
            console.log("the choice id is now " + Choice());
            Choice(Options.List()[index].ID);

            console.log("and now it is " + Choice());
        }
    }

    var vm = {
        Choice: Choice,
        Options: Options,
        LoadOptions: LoadOptions,
        ChangeOption: ChangeOption
    }

    ko.applyBindings(vm, document.getElementById("page"));

})(); 

and my view goes

<div id = "page">
    <div>
        <select data-bind = "options: Options.List, optionsCaption: 'Choose', optionsText: 'Name', optionsValue: 'ID', value: Choice, click: LoadOptions"></select>
    </div>
    <div>your choice's id: <span data-bind = "text: Choice"></span></div>
    <div>
        <button type = "button" data-bind = "click: ChangeOption">Option 2 please</button>
    </div>
</div>

I have been wondering if such kind of forcing the value change is being followed by the bound select field. Turns out that it is which the button proves (the selected option changes after clicking on 'change option' button).

I believe the key is somewhere in the Choice(currentChoice);. This applies the change when used with a button and it does not when options are loaded dynamically.

Is it possible to preserve the selected option?

EDIT: It turns out that each of browsers (IE, Chrome and FF) that I have (later) tested it behaves in a different manner, i.e.

  • Firefox (which the description above is about) is the closest to my goal,
  • Chrome does not refresh the select options list in my view while it is opened. It needs to be hidden (clicked out) and then reopened to have loaded options visible. This seems weird comparing to FF,
  • IE simply closes (hides) the select options list on loading them. This is clearly not my point.

This is why my question now is more like:

is it possible to dynamically append options to a select while it is opened (shown)?

And, unfortunately, I can answer to myself with another fiddle that clearly proves that the problem is simple as that: only Firefox adds options while the select is shown.

That makes me ask you:

what is a cross-browser method to dynamically add/load content into a select menu?

... and again here is the answer: there is no such possibility (proper explanation). So now I am into own select-like control. Over 'n out

هل كانت مفيدة؟

المحلول

There's this other question that suggests that adding options to a select while it's open isn't quite possible in a good cross-browser way.

The question and answer both have 0 upvotes but I think they're right nonetheless. You know what, I think I'll even go about and let empiricism do its thing (Chrome & IE10/9/8 will fail, FF will be okay).

This would mean you'd have to replace regular dropdowns with something like Select2 or the Chosen jQuery plugin.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top