I had a look at the various ways of doing this and came up with adding the new value to the base list specified in the options if it doesn't exist. Go straight to a fiddle
businessUnitsList: ko.observableArray([{
id: "a",
title: "business1"
}, {
id: "b",
title: "business2"
}, {
id: "c",
title: "business3"
}, {
id: "d",
title: "business4"
}]),
The base list array must be an observableArray so it gets updated automatically by knockout when a new value is added), this then triggers the list to refresh.
The HTML to set up the binding:
<select data-bind="missingText:'{val} is DELETED',
options:businessUnits.businessUnitsList,
optionsText:'title',
optionsValue:'id',
value:businessUnits.currentlySelected">
</select>
The "missingText" property hooks into the binding handler and allows the text to be configured, along with the value that was not found as a token in the text {val}
And inside the binding handler which I have called "missingText"
ko.bindingHandlers["missingText"] = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bind) {
var allBindings = allBindingsAccessor(),
items = allBindings['options'],
value = ko.utils.unwrapObservable(allBindings['value']),
valueProperty = ko.utils.unwrapObservable(allBindings['optionsValue']),
textProperty = ko.utils.unwrapObservable(allBindings['optionsText']),
missingTextProperty= ko.utils.unwrapObservable(allBindings['missingText']),
valueSetter = allBindings['value'],
list
//we must have the two properties specified
if (!valueProperty || !textProperty){
throw ("missingText requires the optionsText and optionsValue property to be provided");
}
if (value) {
//try and find the currentlySelected value in the list
var found = ko.utils.arrayFilter(items(), function (item) {
//we're binding to a particular field for the value
//so look for that as the value
return item[valueProperty] == value;
});
//if we haven't found it in the list, add it with our missingText text
if (found.length === 0) {
var newItem ={};
newItem[valueProperty]=value;
//replace token with the value that's missing
newItem[textProperty]=missingTextProperty.replace('{val}', value);
//adding the new item to the items list will trigger the list to refresh
//and display our new value
items.push(newItem);
}
Hopefully that helps?