Reputation: 3030
3I use jquery to $.getJSON and populate a SELECT dropdown with this information (the <OPTION>
s value is the ItemID
, and the text is the DisplayName
):
//$.getJSON and populate <SELECT> options with this info
{"ItemOptions": [
{"ItemID" : 1, "DisplayName": "Apples"},
{"ItemID" : 2, "DisplayName": "Bananas"},
{"ItemID" : 3, "DisplayName": "Oranges"},
{"ItemID" : 4, "DisplayName": "Grapes"},
{"ItemID" : 5, "DisplayName": "Carrots"},
{"ItemID" : 6, "DisplayName": "Crushed Dreams"}
]}
Later on in the code, I get a shipment "manifest", which contains some information, of which includes a list of things that were shipped, it looks like this:
//manifest
{
"LocationSource" : "Dallas",
"LocationDestination" : "New York",
"Items" : [
{"ItemID" : 2},
{"ItemID" : 3},
{"ItemID" : 6}
],
"Status" : "In Transit"
}
// then ko.mapping.toJS(manifest) and
// ko.applyBindings(manifest) is done in javascript.
You'll notice that the Items array in the manifest have ItemID
- which match up to the ItemID
I've populated the SELECT with.
I use Knockout's mapping plugin -- and just ko.mapping.fromJS(manifest)
-- works great. The INPUTs and SPANs and such where I map LocationSource, Status and the like are doing great.
My problem is that I want that SELECT to be a multiple, and representative of my Items in my manifest (the ability to add/remove them). HTML is like:
<input data-bind="value: LocationSource"/>
<input data-bind="value: LocationDestination"/>
<select multiple="multiple" data-bind="value: Items"></select> // this thing
or
<select multiple="multiple" data-bind="value: Items().ItemID"></select>
doesn't seem to be cutting it for me, and I can't seem to figure out how to get it to work right (it appears that the ko.mapping is setting the Items
to an array, but any time I make selections in the SELECT box, it explodes (either stays as it was when initialized, or gets changed from a function to a straight value, depending on how I tinker in code).
Essentially, my question is this:
I have a list of "things". They have IDs that match to an array in my manifest that is ko.mapped (and supposedly an .observableArray for that property). How can I add or remove from my Items
based off that list of "things" (ItemOptions) -- so that when I push the ko.map.toJS(manifest)
back up to the server, my Items array will still be a list of ItemIDs representative of what I chose in the SELECT.
edit: I've looked at adding the entire list as something like .AllItems to the manifest, like they show in the Knockout examples (self.AvailableMeals), but that's really not what I want -- nor do I want that entire list pushed back to the server when I map.toJS and $.post it back.
UPDATE
self.AllItems = ItemOptions; //doesn't need to change, dont obvserable it, right?
self.Items = ko.observableArray(model.Items);
Then, in the HTML I have:
<select data-bind="options: AllItems, optionsText: 'DisplayName', selectedOptions: Items" size="15" multiple="true"></select>
This is getting me there, very close. It's manipulating the manifest like I expect it to -- the only issue now is that when I first load the manifest and apply bindings, the SELECT doesn't autoselect the Items that are in the manifest. I suspect this is because the Items array entry and the ItemOptions entry aren't identical? They both have ItemID, but one has DisplayName, and the other doesn't.
UPDATE 2
Added a jsfiddle: It will demonstrate that it works, but doesn't select the initial load:
Upvotes: 0
Views: 696
Reputation: 4101
If I understood your question correctly you want to use the selectedOptions binding?
so you'd have something like:
<select data-bind="options: ItemOptions, selectedOptions: (manifest.)Items, optionsText: 'name', optionsValue: 'id'" size="5" multiple="true"></select>
and for your javascript something like:
ItemOptions = [
{name: "opt1", id: 1},
{name: "opt2", id: 2},
{name: "opt3", id: 3},
{name: "opt4", id: 4}
]
Upvotes: 1