The various inputs on my page are bound via knockout to a view model, let's say a customer record. That's all working fine.
Now, I want to put a SELECT at the top of the page that contains a list of all customers. The user will pick a customer, the record will be fetched from the database, and the data will be bound to the view model.
My question concerns conditional styling of the items in that SELECT list. It will be bound to an array of customer objects. The Customer object definition has a function called hasExpired:
var Customer = function (id, name, expiryDate) {
this.id = id;
this.customerName = name;
this.expiryDate = expiryDate;
this.hasExpired = function() {
return this.expiryDate == null ? false : true;
};
};
The ViewModel, to which the inputs on the page are bound, looks like this:
function ViewModel() {
var self=this;
self.customerRegion = ko.observable(),
self.customerName = ko.observable(),
.
.
.
self.allCustomers = Customers, // Customers is an array of Customer objects
self.selectedCustomer = ko.observable()
}
This knockout binding works; the SELECT is correctly populated with the list of customers:
<select id="customerSelect"
data-bind="options: allCustomers,
optionsText: 'customerName',
value: selectedCustomer />
I want to style the individual OPTIONS, adding an "expired" class if appropriate.
The individual items in the Customers SELECT are not bound to the view model. The SELECT functions like a navigation menu. The options are bound to the customer objects in the allCustomers array.
How to tell knockout to consult the hasExpired property of the customer object bound to each OPTION, to determine whether that particular option should get the expired
property?
I want the customer to remain in the Select list but to appear with strike-through formatting.
Does the SELECT require its own view model?
The options binding has a parameter (optionsAfterRender
) that allows for additional processing of the options elements. See Note 2: Post-processing the generated options (via the linked documentation).
Unless I have misinterpreted the structure of your data models, all that is required is a callback
self.setOptionStyling = function(option, item) {
ko.applyBindingsToNode(option, {css: {expired: item.hasExpired()} }, item);
}
bound to the optionsAfterRender
parameter:
<select id="customerSelect"
data-bind="options: allCustomers,
optionsText: 'customerName',
value: selectedCustomer,
optionsAfterRender: setOptionStyling" />
Where the expired
css class is defined as:
.expired {
text-decoration: line-through;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With