35

I'm having a small issue with setting the initial value of a dropdown. The code below is the view model definition and the initialization in $(document).ready. I have an array called sourceMaterialTypes and a selectedSourceMaterialType representing the selected value of that array. I am initializing the view model with values from the (ASP.Net MVC) Model and ViewBag.

var viewModel = {
    sourceMaterialTypes : 
        ko.observableArray(@Html.Raw(Json.Encode(ViewBag.SourceMaterialTypes))),
    selectedSourceMaterialType :
        ko.observable(@Html.Raw(Json.Encode(Model.SourceMaterialType))),
    ingredientTypes :
        ko.observableArray(@Html.Raw(Json.Encode(ViewBag.IngredientTypes))),
    selectedIngredientType : ko.observable()
};

$(document).ready(function () {

    ko.applyBindings(viewModel);

    viewModel.selectedSourceMaterialType.subscribe(function(newSourceMaterialType) {
        $.getJSON("/IngredientType/FindByMaterialType",
                  { "id": newSourceMaterialType })
            .success(function (data) {
                viewModel.ingredientTypes($.parseJSON(data));
            })
            .error(function () { alert("error"); });
    });
});

The following is the definition of my dropdown (select) list with the Knockout binding definition.

<select id="SourceMaterialTypeId"
        name="SourceMaterialTypeId"
        data-bind="options: sourceMaterialTypes,
                   optionsText: 'Name',
                   optionsValue : 'Id',
                   value: selectedSourceMaterialType"></select>

This all works fine except for the initially selected value in the source materials dropdown (selectedSourceMaterialType is bound correctly so when the dropdown selection changes its value is correctly updated, it is only the initial selection I am having a problem with), which is always the first item in the sourceMaterialTypes array on my view model.

I would like the initially selected value to be that which is initialized from the (server-side) model as the value of selectedSourceMaterialType view model property.

5
  • this should be working fine; check the source of the html generated and see what is being rendered from > selectedSourceMaterialType:ko.observable(@Html.Raw(Json.Encode(Model.SourceMaterialType))) I suspect it's an empty parameter. Commented Jul 11, 2011 at 11:02
  • @nEEbz no, not empty....selectedSourceMaterialType : ko.observable({"Id":2,"Name":"Fruit","Description":"Fresh Fruit","MeasuredIn":1,"MeasuredInValue":1}), is what is rendered, however the initial selection is the the first item in sourceMaterialTypes....which renders as sourceMaterialTypes : ko.observableArray([{"Id":1,"Name":"Coffee Bean","Description":"Raw coffee beans","MeasuredIn":0,"MeasuredInValue":0},{"Id":2,"Name":"Fruit","Description":"‌​Fresh Fruit","MeasuredIn":1,"MeasuredInValue":1}]), (the initial selection is "Coffee Bean") Commented Jul 11, 2011 at 11:18
  • 3
    I guess you need to pass the Id only and not the whole object in the selectedSourceMaterialType observable function -> selectedSourceMaterialType: ko.observable(2) Commented Jul 11, 2011 at 11:23
  • Yes, with optionsValue: 'Id', it would expect that selectedSourceMaterialType is just the Id. Commented Jul 11, 2011 at 12:48
  • @nEEbz ah of course, my bad. If you want to provide that as an answer I will accept and upvote. Commented Jul 11, 2011 at 19:29

3 Answers 3

13

I guess you need to pass the Id only and not the whole object in the selectedSourceMaterialType observable function ->

selectedSourceMaterialType: ko.observable(@Model.SourceMaterialType.Id)
Sign up to request clarification or add additional context in comments.

1 Comment

But does anyone know how to do it if you want to provide the whole object and not use optionsValue:'Id' ?
5

The API has the solution for you, you'll just need to add optionsCaption to your select.

<select id="SourceMaterialTypeId"
    name="SourceMaterialTypeId"
    data-bind="options: sourceMaterialTypes,
               optionsText: 'Name',
               optionsValue : 'Id',
               value: selectedSourceMaterialType,
               optionsCaption: 'Please select...'"></select>

2 Comments

I believe the question is more focused on having the initial/default value to be what is set by the model/view model. So if upon editing the item, you'd want the last selected value to be shown, not "Please select..."
Tip: optionsCaption is an observable itself. if it returns null then the item won't be present in the list of options - so you can do this monthCaption = ko.computed(() => this.nextShipmentDate_month() ? null : '-- Select Month --'); (assuming typescript here)
2

As @nEEBz suggested, selectedSourceMaterialType is initialized improperly. In the learn.knockoutjs.com "Lists and Collections" tutorial, they initialize their viewmodel's selected-item property by passing the value of a specific index of the observable array. For example, do this:

selectedSourceMaterialType: ko.observable(sourceMaterialTypes[2])

...instead of this:

selectedSourceMaterialType: ko.observable({"Id":1,"Name":"Coffee Bean" /* ... */});

That way, the value of the selected item is a reference to the item in the same observable array that the dropdownlist items come from.

1 Comment

I don't think they are doing it quite like that? That requires extra processing of the results that have come back from the server to determine the index of the item that needs to be selected, which you don't need to do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.